From a3f768a252df2091ffe23d1afd1425776f5610ac Mon Sep 17 00:00:00 2001 From: magicalmeghan Date: Mon, 19 Dec 2022 09:22:47 -0800 Subject: [PATCH 01/20] Renamed SaveableNewsResource to UserNewsResource --- .../core/domain/GetSaveableNewsResourcesUseCase.kt | 8 ++++---- .../{SaveableNewsResource.kt => UserNewsResource.kt} | 2 +- ...aseTest.kt => GetUserNewsResourcesUseCaseTest.kt} | 12 ++++++------ .../samples/apps/nowinandroid/core/ui/NewsFeed.kt | 6 +++--- .../feature/bookmarks/BookmarksScreenTest.kt | 6 +++--- .../feature/bookmarks/BookmarksScreen.kt | 4 ++-- .../feature/bookmarks/BookmarksViewModel.kt | 6 +++--- .../nowinandroid/feature/foryou/ForYouScreenTest.kt | 4 ++-- .../apps/nowinandroid/feature/foryou/ForYouScreen.kt | 10 +++++----- .../nowinandroid/feature/foryou/ForYouViewModel.kt | 6 +++--- .../feature/foryou/ForYouViewModelTest.kt | 12 ++++++------ .../nowinandroid/feature/topic/TopicScreenTest.kt | 6 +++--- .../apps/nowinandroid/feature/topic/TopicScreen.kt | 4 ++-- .../nowinandroid/feature/topic/TopicViewModel.kt | 6 +++--- 14 files changed, 46 insertions(+), 46 deletions(-) rename core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/{SaveableNewsResource.kt => UserNewsResource.kt} (96%) rename core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/{GetSaveableNewsResourcesUseCaseTest.kt => GetUserNewsResourcesUseCaseTest.kt} (92%) diff --git a/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetSaveableNewsResourcesUseCase.kt b/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetSaveableNewsResourcesUseCase.kt index 4bd2fc6c3..df63a4487 100644 --- a/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetSaveableNewsResourcesUseCase.kt +++ b/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetSaveableNewsResourcesUseCase.kt @@ -18,7 +18,7 @@ package com.google.samples.apps.nowinandroid.core.domain import com.google.samples.apps.nowinandroid.core.data.repository.NewsRepository import com.google.samples.apps.nowinandroid.core.data.repository.UserDataRepository -import com.google.samples.apps.nowinandroid.core.domain.model.SaveableNewsResource +import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import javax.inject.Inject import kotlinx.coroutines.flow.Flow @@ -47,7 +47,7 @@ class GetSaveableNewsResourcesUseCase @Inject constructor( */ operator fun invoke( filterTopicIds: Set = emptySet() - ): Flow> = + ): Flow> = if (filterTopicIds.isEmpty()) { newsRepository.getNewsResources() } else { @@ -57,11 +57,11 @@ class GetSaveableNewsResourcesUseCase @Inject constructor( private fun Flow>.mapToSaveableNewsResources( savedNewsResourceIds: Flow> -): Flow> = +): Flow> = filterNot { it.isEmpty() } .combine(savedNewsResourceIds) { newsResources, savedNewsResourceIds -> newsResources.map { newsResource -> - SaveableNewsResource( + UserNewsResource( newsResource = newsResource, isSaved = savedNewsResourceIds.contains(newsResource.id) ) diff --git a/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/SaveableNewsResource.kt b/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/UserNewsResource.kt similarity index 96% rename from core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/SaveableNewsResource.kt rename to core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/UserNewsResource.kt index 6850d421f..ddd8a27f6 100644 --- a/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/SaveableNewsResource.kt +++ b/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/UserNewsResource.kt @@ -21,7 +21,7 @@ import com.google.samples.apps.nowinandroid.core.model.data.NewsResource /** * A [NewsResource] with the additional information for whether it is saved. */ -data class SaveableNewsResource( +data class UserNewsResource( val newsResource: NewsResource, val isSaved: Boolean, ) diff --git a/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetSaveableNewsResourcesUseCaseTest.kt b/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt similarity index 92% rename from core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetSaveableNewsResourcesUseCaseTest.kt rename to core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt index 876811e61..6bdbd9f34 100644 --- a/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetSaveableNewsResourcesUseCaseTest.kt +++ b/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt @@ -16,7 +16,7 @@ package com.google.samples.apps.nowinandroid.core.domain -import com.google.samples.apps.nowinandroid.core.domain.model.SaveableNewsResource +import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType.Video import com.google.samples.apps.nowinandroid.core.model.data.Topic @@ -30,7 +30,7 @@ import kotlinx.datetime.Instant import org.junit.Rule import org.junit.Test -class GetSaveableNewsResourcesUseCaseTest { +class GetUserNewsResourcesUseCaseTest { @get:Rule val mainDispatcherRule = MainDispatcherRule() @@ -55,9 +55,9 @@ class GetSaveableNewsResourcesUseCaseTest { // Check that the correct news resources are returned with their bookmarked state. assertEquals( listOf( - SaveableNewsResource(sampleNewsResources[0], true), - SaveableNewsResource(sampleNewsResources[1], false), - SaveableNewsResource(sampleNewsResources[2], true) + UserNewsResource(sampleNewsResources[0], true), + UserNewsResource(sampleNewsResources[1], false), + UserNewsResource(sampleNewsResources[2], true) ), saveableNewsResources.first() ) @@ -77,7 +77,7 @@ class GetSaveableNewsResourcesUseCaseTest { assertEquals( sampleNewsResources .filter { it.topics.contains(sampleTopic1) } - .map { SaveableNewsResource(it, false) }, + .map { UserNewsResource(it, false) }, saveableNewsResources.first() ) } diff --git a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsFeed.kt b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsFeed.kt index 55d84af2f..cf2714db7 100644 --- a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsFeed.kt +++ b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsFeed.kt @@ -37,7 +37,7 @@ import androidx.compose.ui.tooling.preview.Devices import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme -import com.google.samples.apps.nowinandroid.core.domain.model.SaveableNewsResource +import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.model.data.previewNewsResources /** @@ -100,7 +100,7 @@ sealed interface NewsFeedUiState { /** * The list of news resources contained in this feed. */ - val feed: List + val feed: List ) : NewsFeedUiState } @@ -126,7 +126,7 @@ fun NewsFeedContentPreview() { newsFeed( feedState = NewsFeedUiState.Success( previewNewsResources.map { - SaveableNewsResource( + UserNewsResource( it, false ) diff --git a/feature/bookmarks/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreenTest.kt b/feature/bookmarks/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreenTest.kt index 1dafc5c98..3421f885a 100644 --- a/feature/bookmarks/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreenTest.kt +++ b/feature/bookmarks/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreenTest.kt @@ -31,7 +31,7 @@ import androidx.compose.ui.test.onNodeWithContentDescription import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick import androidx.compose.ui.test.performScrollToNode -import com.google.samples.apps.nowinandroid.core.domain.model.SaveableNewsResource +import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.model.data.previewNewsResources import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState import kotlin.test.assertEquals @@ -71,7 +71,7 @@ class BookmarksScreenTest { BookmarksScreen( feedState = NewsFeedUiState.Success( previewNewsResources.take(2) - .map { SaveableNewsResource(it, true) } + .map { UserNewsResource(it, true) } ), removeFromBookmarks = { } ) @@ -110,7 +110,7 @@ class BookmarksScreenTest { BookmarksScreen( feedState = NewsFeedUiState.Success( previewNewsResources.take(2) - .map { SaveableNewsResource(it, true) } + .map { UserNewsResource(it, true) } ), removeFromBookmarks = { newsResourceId -> assertEquals(previewNewsResources[0].id, newsResourceId) diff --git a/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreen.kt b/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreen.kt index 06a87bc9e..0bab4e449 100644 --- a/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreen.kt +++ b/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreen.kt @@ -52,7 +52,7 @@ import androidx.lifecycle.compose.ExperimentalLifecycleComposeApi import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaLoadingWheel import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme -import com.google.samples.apps.nowinandroid.core.domain.model.SaveableNewsResource +import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.model.data.previewNewsResources import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState.Loading @@ -185,7 +185,7 @@ private fun BookmarksGridPreview() { BookmarksGrid( feedState = Success( previewNewsResources.map { - SaveableNewsResource(it, false) + UserNewsResource(it, false) } ), removeFromBookmarks = {} diff --git a/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModel.kt b/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModel.kt index 8223ecd1b..8ea565bfd 100644 --- a/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModel.kt +++ b/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModel.kt @@ -20,7 +20,7 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.google.samples.apps.nowinandroid.core.data.repository.UserDataRepository import com.google.samples.apps.nowinandroid.core.domain.GetSaveableNewsResourcesUseCase -import com.google.samples.apps.nowinandroid.core.domain.model.SaveableNewsResource +import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState.Loading import dagger.hilt.android.lifecycle.HiltViewModel @@ -41,8 +41,8 @@ class BookmarksViewModel @Inject constructor( val feedUiState: StateFlow = getSaveableNewsResources() .filterNot { it.isEmpty() } - .map { newsResources -> newsResources.filter(SaveableNewsResource::isSaved) } // Only show bookmarked news resources. - .map, NewsFeedUiState>(NewsFeedUiState::Success) + .map { newsResources -> newsResources.filter(UserNewsResource::isSaved) } // Only show bookmarked news resources. + .map, NewsFeedUiState>(NewsFeedUiState::Success) .onStart { emit(Loading) } .stateIn( scope = viewModelScope, diff --git a/feature/foryou/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt b/feature/foryou/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt index 702a963c1..ee6e2795b 100644 --- a/feature/foryou/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt +++ b/feature/foryou/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt @@ -29,7 +29,7 @@ import androidx.compose.ui.test.onNodeWithContentDescription import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performScrollToNode import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic -import com.google.samples.apps.nowinandroid.core.domain.model.SaveableNewsResource +import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.model.data.Topic import com.google.samples.apps.nowinandroid.core.model.data.previewNewsResources import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState @@ -226,7 +226,7 @@ class ForYouScreenTest { onboardingUiState = OnboardingUiState.NotShown, feedState = NewsFeedUiState.Success( feed = previewNewsResources.map { - SaveableNewsResource(it, false) + UserNewsResource(it, false) } ), onTopicCheckedChanged = { _, _ -> }, diff --git a/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt b/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt index 1427aecff..e1a5b5e9e 100644 --- a/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt +++ b/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt @@ -83,7 +83,7 @@ import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaOverl import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic -import com.google.samples.apps.nowinandroid.core.domain.model.SaveableNewsResource +import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.model.data.previewNewsResources import com.google.samples.apps.nowinandroid.core.model.data.previewTopics import com.google.samples.apps.nowinandroid.core.ui.DevicePreviews @@ -397,7 +397,7 @@ fun ForYouScreenPopulatedFeed() { onboardingUiState = OnboardingUiState.NotShown, feedState = NewsFeedUiState.Success( feed = previewNewsResources.map { - SaveableNewsResource(it, false) + UserNewsResource(it, false) } ), onTopicCheckedChanged = { _, _ -> }, @@ -418,7 +418,7 @@ fun ForYouScreenOfflinePopulatedFeed() { onboardingUiState = OnboardingUiState.NotShown, feedState = NewsFeedUiState.Success( feed = previewNewsResources.map { - SaveableNewsResource(it, false) + UserNewsResource(it, false) } ), onTopicCheckedChanged = { _, _ -> }, @@ -441,7 +441,7 @@ fun ForYouScreenTopicSelection() { ), feedState = NewsFeedUiState.Success( feed = previewNewsResources.map { - SaveableNewsResource(it, false) + UserNewsResource(it, false) } ), onTopicCheckedChanged = { _, _ -> }, @@ -479,7 +479,7 @@ fun ForYouScreenPopulatedAndLoading() { onboardingUiState = OnboardingUiState.Loading, feedState = NewsFeedUiState.Success( feed = previewNewsResources.map { - SaveableNewsResource(it, false) + UserNewsResource(it, false) } ), onTopicCheckedChanged = { _, _ -> }, diff --git a/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModel.kt b/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModel.kt index 800cba0d3..645566056 100644 --- a/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModel.kt +++ b/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModel.kt @@ -22,7 +22,7 @@ import com.google.samples.apps.nowinandroid.core.data.repository.UserDataReposit import com.google.samples.apps.nowinandroid.core.data.util.SyncStatusMonitor import com.google.samples.apps.nowinandroid.core.domain.GetFollowableTopicsUseCase import com.google.samples.apps.nowinandroid.core.domain.GetSaveableNewsResourcesUseCase -import com.google.samples.apps.nowinandroid.core.domain.model.SaveableNewsResource +import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject @@ -117,6 +117,6 @@ class ForYouViewModel @Inject constructor( } } -private fun Flow>.mapToFeedState(): Flow = - map, NewsFeedUiState>(NewsFeedUiState::Success) +private fun Flow>.mapToFeedState(): Flow = + map, NewsFeedUiState>(NewsFeedUiState::Success) .onStart { emit(NewsFeedUiState.Loading) } diff --git a/feature/foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt b/feature/foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt index ad29aba60..06b7ebe7a 100644 --- a/feature/foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt +++ b/feature/foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt @@ -19,7 +19,7 @@ package com.google.samples.apps.nowinandroid.feature.foryou import com.google.samples.apps.nowinandroid.core.domain.GetFollowableTopicsUseCase import com.google.samples.apps.nowinandroid.core.domain.GetSaveableNewsResourcesUseCase import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic -import com.google.samples.apps.nowinandroid.core.domain.model.SaveableNewsResource +import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType.Video import com.google.samples.apps.nowinandroid.core.model.data.Topic @@ -282,7 +282,7 @@ class ForYouViewModelTest { NewsFeedUiState.Success( feed = sampleNewsResources.map { - SaveableNewsResource( + UserNewsResource( newsResource = it, isSaved = false ) @@ -397,11 +397,11 @@ class ForYouViewModelTest { assertEquals( NewsFeedUiState.Success( feed = listOf( - SaveableNewsResource( + UserNewsResource( newsResource = sampleNewsResources[1], isSaved = false ), - SaveableNewsResource( + UserNewsResource( newsResource = sampleNewsResources[2], isSaved = false ) @@ -497,11 +497,11 @@ class ForYouViewModelTest { assertEquals( NewsFeedUiState.Success( feed = listOf( - SaveableNewsResource( + UserNewsResource( newsResource = sampleNewsResources[1], isSaved = true ), - SaveableNewsResource( + UserNewsResource( newsResource = sampleNewsResources[2], isSaved = false ) diff --git a/feature/topic/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreenTest.kt b/feature/topic/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreenTest.kt index 9bef39a36..0f6d2dcc0 100644 --- a/feature/topic/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreenTest.kt +++ b/feature/topic/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreenTest.kt @@ -25,7 +25,7 @@ import androidx.compose.ui.test.onNodeWithContentDescription import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performScrollToNode import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic -import com.google.samples.apps.nowinandroid.core.domain.model.SaveableNewsResource +import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType.Video import com.google.samples.apps.nowinandroid.core.model.data.Topic @@ -101,7 +101,7 @@ class TopicScreenTest { topicUiState = TopicUiState.Loading, newsUiState = NewsUiState.Success( sampleNewsResources.mapIndexed { index, newsResource -> - SaveableNewsResource( + UserNewsResource( newsResource = newsResource, isSaved = index % 2 == 0, ) @@ -127,7 +127,7 @@ class TopicScreenTest { topicUiState = TopicUiState.Success(testTopic), newsUiState = NewsUiState.Success( sampleNewsResources.mapIndexed { index, newsResource -> - SaveableNewsResource( + UserNewsResource( newsResource = newsResource, isSaved = index % 2 == 0, ) diff --git a/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreen.kt b/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreen.kt index 61bd13aa0..b57c96954 100644 --- a/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreen.kt +++ b/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreen.kt @@ -53,7 +53,7 @@ import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaLoadi import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic -import com.google.samples.apps.nowinandroid.core.domain.model.SaveableNewsResource +import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.model.data.previewNewsResources import com.google.samples.apps.nowinandroid.core.model.data.previewTopics import com.google.samples.apps.nowinandroid.core.ui.DevicePreviews @@ -258,7 +258,7 @@ fun TopicScreenPopulated() { topicUiState = TopicUiState.Success(FollowableTopic(previewTopics[0], false)), newsUiState = NewsUiState.Success( previewNewsResources.mapIndexed { index, newsResource -> - SaveableNewsResource( + UserNewsResource( newsResource = newsResource, isSaved = index % 2 == 0, ) diff --git a/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModel.kt b/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModel.kt index 17096ca88..e65bc1dee 100644 --- a/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModel.kt +++ b/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModel.kt @@ -24,7 +24,7 @@ import com.google.samples.apps.nowinandroid.core.data.repository.UserDataReposit import com.google.samples.apps.nowinandroid.core.decoder.StringDecoder import com.google.samples.apps.nowinandroid.core.domain.GetSaveableNewsResourcesUseCase import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic -import com.google.samples.apps.nowinandroid.core.domain.model.SaveableNewsResource +import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.model.data.Topic import com.google.samples.apps.nowinandroid.core.result.Result import com.google.samples.apps.nowinandroid.core.result.asResult @@ -135,7 +135,7 @@ private fun newsUiState( userDataRepository: UserDataRepository, ): Flow { // Observe news - val news: Flow> = getSaveableNewsResources( + val news: Flow> = getSaveableNewsResources( filterTopicIds = setOf(element = topicId), ) @@ -172,7 +172,7 @@ sealed interface TopicUiState { } sealed interface NewsUiState { - data class Success(val news: List) : NewsUiState + data class Success(val news: List) : NewsUiState object Error : NewsUiState object Loading : NewsUiState } From 464f28a07fac87d088bac975c8c29400aa211ae7 Mon Sep 17 00:00:00 2001 From: magicalmeghan Date: Mon, 19 Dec 2022 11:39:05 -0800 Subject: [PATCH 02/20] Renamed SaveableNewsResource to UserNewsResource --- ...Case.kt => GetUserNewsResourcesUseCase.kt} | 36 ++++---- .../core/domain/model/FollowableTopic.kt | 18 +++- .../core/domain/model/UserNewsResource.kt | 84 ++++++++++++++++++- .../domain/GetUserNewsResourcesUseCaseTest.kt | 67 +++++++++++++-- .../core/ui/NewsResourceCardTest.kt | 4 +- .../apps/nowinandroid/core/ui/NewsFeed.kt | 21 ++--- .../nowinandroid/core/ui/NewsResourceCard.kt | 30 +++---- .../core/ui/NewsResourceCardList.kt | 5 +- .../feature/bookmarks/BookmarksScreen.kt | 5 +- .../feature/bookmarks/BookmarksViewModel.kt | 4 +- .../bookmarks/BookmarksViewModelTest.kt | 6 +- .../feature/foryou/ForYouScreen.kt | 17 ++-- .../feature/foryou/ForYouViewModel.kt | 4 +- .../feature/foryou/ForYouViewModelTest.kt | 78 +++++++++++++++-- .../nowinandroid/feature/topic/TopicScreen.kt | 12 +-- .../feature/topic/TopicViewModel.kt | 6 +- .../feature/topic/TopicViewModelTest.kt | 6 +- 17 files changed, 304 insertions(+), 99 deletions(-) rename core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/{GetSaveableNewsResourcesUseCase.kt => GetUserNewsResourcesUseCase.kt} (62%) diff --git a/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetSaveableNewsResourcesUseCase.kt b/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCase.kt similarity index 62% rename from core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetSaveableNewsResourcesUseCase.kt rename to core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCase.kt index df63a4487..19d65581f 100644 --- a/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetSaveableNewsResourcesUseCase.kt +++ b/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCase.kt @@ -18,29 +18,25 @@ package com.google.samples.apps.nowinandroid.core.domain import com.google.samples.apps.nowinandroid.core.data.repository.NewsRepository import com.google.samples.apps.nowinandroid.core.data.repository.UserDataRepository +import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResource +import com.google.samples.apps.nowinandroid.core.model.data.UserData import javax.inject.Inject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.filterNot -import kotlinx.coroutines.flow.map /** * A use case responsible for obtaining news resources with their associated bookmarked (also known * as "saved") state. */ -class GetSaveableNewsResourcesUseCase @Inject constructor( +class GetUserNewsResourcesUseCase @Inject constructor( private val newsRepository: NewsRepository, - userDataRepository: UserDataRepository + private val userDataRepository: UserDataRepository ) { - - private val bookmarkedNewsResources = userDataRepository.userData.map { - it.bookmarkedNewsResources - } - /** - * Returns a list of SaveableNewsResources which match the supplied set of topic ids. + * Returns a list of UserNewsResources which match the supplied set of topic ids. * * @param filterTopicIds - A set of topic ids used to filter the list of news resources. If * this is empty the list of news resources will not be filtered. @@ -52,18 +48,30 @@ class GetSaveableNewsResourcesUseCase @Inject constructor( newsRepository.getNewsResources() } else { newsRepository.getNewsResources(filterTopicIds = filterTopicIds) - }.mapToSaveableNewsResources(bookmarkedNewsResources) + }.mapToSaveableNewsResources(userDataRepository.userData) } private fun Flow>.mapToSaveableNewsResources( - savedNewsResourceIds: Flow> + userData: Flow ): Flow> = filterNot { it.isEmpty() } - .combine(savedNewsResourceIds) { newsResources, savedNewsResourceIds -> + .combine(userData) { newsResources, userData -> newsResources.map { newsResource -> UserNewsResource( - newsResource = newsResource, - isSaved = savedNewsResourceIds.contains(newsResource.id) + id = newsResource.id, + title = newsResource.title, + content = newsResource.content, + url = newsResource.url, + headerImageUrl = newsResource.headerImageUrl, + publishDate = newsResource.publishDate, + type = newsResource.type, + topics = newsResource.topics.map { topic -> + FollowableTopic( + topic = topic, + isFollowed = userData.followedTopics.contains(topic.id) + ) + }, + isSaved = userData.bookmarkedNewsResources.contains(newsResource.id) ) } } diff --git a/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/FollowableTopic.kt b/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/FollowableTopic.kt index 87a77daa4..c081abf1f 100644 --- a/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/FollowableTopic.kt +++ b/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/FollowableTopic.kt @@ -17,11 +17,27 @@ package com.google.samples.apps.nowinandroid.core.domain.model import com.google.samples.apps.nowinandroid.core.model.data.Topic +import com.google.samples.apps.nowinandroid.core.model.data.previewTopics /** * A [topic] with the additional information for whether or not it is followed. */ -data class FollowableTopic( +data class FollowableTopic( //TODO consider changing to UserTopic and flattening val topic: Topic, val isFollowed: Boolean ) + +val previewFollowableTopics = listOf( + FollowableTopic( + previewTopics[0], + isFollowed = false + ), + FollowableTopic( + previewTopics[1], + isFollowed = true + ), + FollowableTopic( + previewTopics[2], + isFollowed = false + ) +) diff --git a/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/UserNewsResource.kt b/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/UserNewsResource.kt index ddd8a27f6..c70f549b2 100644 --- a/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/UserNewsResource.kt +++ b/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/UserNewsResource.kt @@ -17,11 +17,89 @@ package com.google.samples.apps.nowinandroid.core.domain.model import com.google.samples.apps.nowinandroid.core.model.data.NewsResource +import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType +import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType.Codelab +import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType.Unknown +import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType.Video +import com.google.samples.apps.nowinandroid.core.model.data.previewTopics +import kotlinx.datetime.Instant +import kotlinx.datetime.LocalDateTime +import kotlinx.datetime.TimeZone +import kotlinx.datetime.toInstant /** - * A [NewsResource] with the additional information for whether it is saved. + * A [NewsResource] with the additional user information. */ data class UserNewsResource( - val newsResource: NewsResource, - val isSaved: Boolean, + val id: String, + val title: String, + val content: String, + val url: String, + val headerImageUrl: String?, + val publishDate: Instant, + val type: NewsResourceType, + val topics: List, + val isSaved: Boolean +) + +val previewUserNewsResources = listOf( + UserNewsResource( + id = "1", + title = "Android Basics with Compose", + content = "We released the first two units of Android Basics with Compose, our first free course that teaches Android Development with Jetpack Compose to anyone; you do not need any prior programming experience other than basic computer literacy to get started. You’ll learn the fundamentals of programming in Kotlin while building Android apps using Jetpack Compose, Android’s modern toolkit that simplifies and accelerates native UI development. These two units are just the beginning; more will be coming soon. Check out Android Basics with Compose to get started on your Android development journey", + url = "https://android-developers.googleblog.com/2022/05/new-android-basics-with-compose-course.html", + headerImageUrl = "https://developer.android.com/images/hero-assets/android-basics-compose.svg", + publishDate = LocalDateTime( + year = 2022, + monthNumber = 5, + dayOfMonth = 4, + hour = 23, + minute = 0, + second = 0, + nanosecond = 0 + ).toInstant(TimeZone.UTC), + type = Codelab, + topics = listOf(previewFollowableTopics[1]), + isSaved = true + ), + UserNewsResource( + id = "2", + title = "Thanks for helping us reach 1M YouTube Subscribers", + content = "Thank you everyone for following the Now in Android series and everything the " + + "Android Developers YouTube channel has to offer. During the Android Developer " + + "Summit, our YouTube channel reached 1 million subscribers! Here’s a small video to " + + "thank you all.", + url = "https://youtu.be/-fJ6poHQrjM", + headerImageUrl = "https://i.ytimg.com/vi/-fJ6poHQrjM/maxresdefault.jpg", + publishDate = Instant.parse("2021-11-09T00:00:00.000Z"), + type = Video, + topics = listOf(previewFollowableTopics[0], previewFollowableTopics[1]), + isSaved = false + ), + UserNewsResource( + id = "3", + title = "Transformations and customisations in the Paging Library", + content = "A demonstration of different operations that can be performed " + + "with Paging. Transformations like inserting separators, when to " + + "create a new pager, and customisation options for consuming " + + "PagingData.", + url = "https://youtu.be/ZARz0pjm5YM", + headerImageUrl = "https://i.ytimg.com/vi/ZARz0pjm5YM/maxresdefault.jpg", + publishDate = Instant.parse("2021-11-01T00:00:00.000Z"), + type = Video, + topics = listOf(previewFollowableTopics[2]), + isSaved = false + ), + UserNewsResource( + id = "4", + title = "New Jetpack Release", + content = "New Jetpack release includes updates to libraries such as CameraX, Benchmark, and" + + "more!", + url = "https://developer.android.com/jetpack/androidx/versions/all-channel", + headerImageUrl = "", + publishDate = Instant.parse("2022-10-01T00:00:00.000Z"), + type = Unknown, + topics = listOf(previewFollowableTopics[2]), + isSaved = true + ) ) diff --git a/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt b/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt index 6bdbd9f34..ce730d6f2 100644 --- a/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt +++ b/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt @@ -16,6 +16,7 @@ package com.google.samples.apps.nowinandroid.core.domain +import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType.Video @@ -38,7 +39,7 @@ class GetUserNewsResourcesUseCaseTest { private val newsRepository = TestNewsRepository() private val userDataRepository = TestUserDataRepository() - val useCase = GetSaveableNewsResourcesUseCase(newsRepository, userDataRepository) + val useCase = GetUserNewsResourcesUseCase(newsRepository, userDataRepository) @Test fun whenNoFilters_allNewsResourcesAreReturned() = runTest { @@ -55,9 +56,51 @@ class GetUserNewsResourcesUseCaseTest { // Check that the correct news resources are returned with their bookmarked state. assertEquals( listOf( - UserNewsResource(sampleNewsResources[0], true), - UserNewsResource(sampleNewsResources[1], false), - UserNewsResource(sampleNewsResources[2], true) + UserNewsResource( + sampleNewsResources[0].id, + sampleNewsResources[0].title, + sampleNewsResources[0].content, + sampleNewsResources[0].url, + sampleNewsResources[0].headerImageUrl, + sampleNewsResources[0].publishDate, + sampleNewsResources[0].type, + sampleNewsResources[0].topics.map { topic -> + FollowableTopic( + topic = topic, + isFollowed = false + ) + }, + true), + UserNewsResource( + sampleNewsResources[1].id, + sampleNewsResources[1].title, + sampleNewsResources[1].content, + sampleNewsResources[1].url, + sampleNewsResources[1].headerImageUrl, + sampleNewsResources[1].publishDate, + sampleNewsResources[1].type, + sampleNewsResources[1].topics.map { topic -> + FollowableTopic( + topic = topic, + isFollowed = false + ) + }, + false), + UserNewsResource( + sampleNewsResources[2].id, + sampleNewsResources[2].title, + sampleNewsResources[2].content, + sampleNewsResources[2].url, + sampleNewsResources[2].headerImageUrl, + sampleNewsResources[2].publishDate, + sampleNewsResources[2].type, + sampleNewsResources[2].topics.map { topic -> + FollowableTopic( + topic = topic, + isFollowed = true + ) + }, + true), ), saveableNewsResources.first() ) @@ -77,7 +120,21 @@ class GetUserNewsResourcesUseCaseTest { assertEquals( sampleNewsResources .filter { it.topics.contains(sampleTopic1) } - .map { UserNewsResource(it, false) }, + .map { UserNewsResource( + id = it.id, + title = it.title, + content = it.content, + url = it.url, + headerImageUrl = it.headerImageUrl, + publishDate = it.publishDate, + type = it.type, + topics = it.topics.map { topic -> + FollowableTopic( + topic = topic, + isFollowed = false + ) + }, + isSaved = false) }, saveableNewsResources.first() ) } diff --git a/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt b/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt index 69f919a62..c334f1bab 100644 --- a/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt +++ b/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt @@ -35,7 +35,7 @@ class NewsResourceCardTest { composeTestRule.setContent { NewsResourceCardExpanded( - newsResource = newsWithKnownResourceType, + userNewsResource = newsWithKnownResourceType, isBookmarked = false, onToggleBookmark = {}, onClick = {} @@ -62,7 +62,7 @@ class NewsResourceCardTest { composeTestRule.setContent { NewsResourceCardExpanded( - newsResource = newsWithUnknownResourceType, + userNewsResource = newsWithUnknownResourceType, isBookmarked = false, onToggleBookmark = {}, onClick = {} diff --git a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsFeed.kt b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsFeed.kt index cf2714db7..a4ccdaca5 100644 --- a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsFeed.kt +++ b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsFeed.kt @@ -38,7 +38,7 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource -import com.google.samples.apps.nowinandroid.core.model.data.previewNewsResources +import com.google.samples.apps.nowinandroid.core.domain.model.previewUserNewsResources /** * An extension on [LazyListScope] defining a feed with news resources. @@ -51,21 +51,21 @@ fun LazyGridScope.newsFeed( when (feedState) { NewsFeedUiState.Loading -> Unit is NewsFeedUiState.Success -> { - items(feedState.feed, key = { it.newsResource.id }) { saveableNewsResource -> + items(feedState.feed, key = { it.id }) { userNewsResource -> val resourceUrl by remember { - mutableStateOf(Uri.parse(saveableNewsResource.newsResource.url)) + mutableStateOf(Uri.parse(userNewsResource.url)) } val context = LocalContext.current val backgroundColor = MaterialTheme.colorScheme.background.toArgb() NewsResourceCardExpanded( - newsResource = saveableNewsResource.newsResource, - isBookmarked = saveableNewsResource.isSaved, + userNewsResource = userNewsResource, + isBookmarked = userNewsResource.isSaved, onClick = { launchCustomChromeTab(context, resourceUrl, backgroundColor) }, onToggleBookmark = { onNewsResourcesCheckedChanged( - saveableNewsResource.newsResource.id, - !saveableNewsResource.isSaved + userNewsResource.id, + !userNewsResource.isSaved ) } ) @@ -125,12 +125,7 @@ fun NewsFeedContentPreview() { LazyVerticalGrid(columns = GridCells.Adaptive(300.dp)) { newsFeed( feedState = NewsFeedUiState.Success( - previewNewsResources.map { - UserNewsResource( - it, - false - ) - } + previewUserNewsResources ), onNewsResourcesCheckedChanged = { _, _ -> } ) diff --git a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt index 21ee1a7a8..6eb6e7859 100644 --- a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt +++ b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt @@ -56,9 +56,11 @@ import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaIconT import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaTopicTag import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme +import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic +import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource +import com.google.samples.apps.nowinandroid.core.domain.model.previewUserNewsResources import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType -import com.google.samples.apps.nowinandroid.core.model.data.Topic import com.google.samples.apps.nowinandroid.core.model.data.previewNewsResources import java.time.ZoneId import java.time.format.DateTimeFormatter @@ -73,7 +75,7 @@ import kotlinx.datetime.toJavaInstant @OptIn(ExperimentalMaterial3Api::class) @Composable fun NewsResourceCardExpanded( - newsResource: NewsResource, + userNewsResource: UserNewsResource, isBookmarked: Boolean, onToggleBookmark: () -> Unit, onClick: () -> Unit, @@ -91,9 +93,9 @@ fun NewsResourceCardExpanded( } ) { Column { - if (!newsResource.headerImageUrl.isNullOrEmpty()) { + if (!userNewsResource.headerImageUrl.isNullOrEmpty()) { Row { - NewsResourceHeaderImage(newsResource.headerImageUrl) + NewsResourceHeaderImage(userNewsResource.headerImageUrl) } } Box( @@ -103,18 +105,18 @@ fun NewsResourceCardExpanded( Spacer(modifier = Modifier.height(12.dp)) Row { NewsResourceTitle( - newsResource.title, + userNewsResource.title, modifier = Modifier.fillMaxWidth((.8f)) ) Spacer(modifier = Modifier.weight(1f)) BookmarkButton(isBookmarked, onToggleBookmark) } Spacer(modifier = Modifier.height(12.dp)) - NewsResourceMetaData(newsResource.publishDate, newsResource.type) + NewsResourceMetaData(userNewsResource.publishDate, userNewsResource.type) Spacer(modifier = Modifier.height(12.dp)) - NewsResourceShortDescription(newsResource.content) + NewsResourceShortDescription(userNewsResource.content) Spacer(modifier = Modifier.height(12.dp)) - NewsResourceTopics(newsResource.topics) + NewsResourceTopics(userNewsResource.topics) } } } @@ -227,7 +229,7 @@ fun NewsResourceShortDescription( @Composable fun NewsResourceTopics( - topics: List, + topics: List, modifier: Modifier = Modifier ) { // Store the ID of the Topic which has its "following" menu expanded, if any. @@ -238,17 +240,17 @@ fun NewsResourceTopics( modifier = modifier.horizontalScroll(rememberScrollState()), // causes narrow chips horizontalArrangement = Arrangement.spacedBy(4.dp), ) { - for (topic in topics) { + for (followableTopic in topics) { NiaTopicTag( - expanded = expandedTopicId == topic.id, + expanded = expandedTopicId == followableTopic.topic.id, followed = true, // ToDo: Check if topic is followed onDropdownMenuToggle = { show -> - expandedTopicId = if (show) topic.id else null + expandedTopicId = if (show) followableTopic.topic.id else null }, onFollowClick = { }, // ToDo onUnfollowClick = { }, // ToDo onBrowseClick = { }, // ToDo - text = { Text(text = topic.name.uppercase(Locale.getDefault())) } + text = { Text(text = followableTopic.topic.name.uppercase(Locale.getDefault())) } ) } } @@ -280,7 +282,7 @@ fun ExpandedNewsResourcePreview() { NiaTheme { Surface { NewsResourceCardExpanded( - newsResource = previewNewsResources[0], + userNewsResource = previewUserNewsResources[0], isBookmarked = true, onToggleBookmark = {}, onClick = {} diff --git a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardList.kt b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardList.kt index c76a8124d..c2bdb6580 100644 --- a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardList.kt +++ b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardList.kt @@ -23,6 +23,7 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.platform.LocalContext +import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResource /** @@ -37,7 +38,7 @@ import com.google.samples.apps.nowinandroid.core.model.data.NewsResource */ fun LazyListScope.newsResourceCardItems( items: List, - newsResourceMapper: (item: T) -> NewsResource, + newsResourceMapper: (item: T) -> UserNewsResource, //TODO remove this? isBookmarkedMapper: (item: T) -> Boolean, onToggleBookmark: (item: T) -> Unit, onItemClick: ((item: T) -> Unit)? = null, @@ -52,7 +53,7 @@ fun LazyListScope.newsResourceCardItems( val context = LocalContext.current NewsResourceCardExpanded( - newsResource = newsResource, + userNewsResource = newsResource, isBookmarked = isBookmarkedMapper(item), onToggleBookmark = { onToggleBookmark(item) }, onClick = { diff --git a/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreen.kt b/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreen.kt index 0bab4e449..9dbad373b 100644 --- a/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreen.kt +++ b/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreen.kt @@ -53,6 +53,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaLoadingWheel import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource +import com.google.samples.apps.nowinandroid.core.domain.model.previewUserNewsResources import com.google.samples.apps.nowinandroid.core.model.data.previewNewsResources import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState.Loading @@ -184,9 +185,7 @@ private fun BookmarksGridPreview() { NiaTheme { BookmarksGrid( feedState = Success( - previewNewsResources.map { - UserNewsResource(it, false) - } + previewUserNewsResources ), removeFromBookmarks = {} ) diff --git a/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModel.kt b/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModel.kt index 8ea565bfd..db94839be 100644 --- a/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModel.kt +++ b/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModel.kt @@ -19,7 +19,7 @@ package com.google.samples.apps.nowinandroid.feature.bookmarks import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.google.samples.apps.nowinandroid.core.data.repository.UserDataRepository -import com.google.samples.apps.nowinandroid.core.domain.GetSaveableNewsResourcesUseCase +import com.google.samples.apps.nowinandroid.core.domain.GetUserNewsResourcesUseCase import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState.Loading @@ -36,7 +36,7 @@ import kotlinx.coroutines.launch @HiltViewModel class BookmarksViewModel @Inject constructor( private val userDataRepository: UserDataRepository, - getSaveableNewsResources: GetSaveableNewsResourcesUseCase + getSaveableNewsResources: GetUserNewsResourcesUseCase ) : ViewModel() { val feedUiState: StateFlow = getSaveableNewsResources() diff --git a/feature/bookmarks/src/test/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModelTest.kt b/feature/bookmarks/src/test/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModelTest.kt index 56f30eff5..a8da1a4ff 100644 --- a/feature/bookmarks/src/test/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModelTest.kt +++ b/feature/bookmarks/src/test/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModelTest.kt @@ -16,7 +16,7 @@ package com.google.samples.apps.nowinandroid.feature.bookmarks -import com.google.samples.apps.nowinandroid.core.domain.GetSaveableNewsResourcesUseCase +import com.google.samples.apps.nowinandroid.core.domain.GetUserNewsResourcesUseCase import com.google.samples.apps.nowinandroid.core.model.data.previewNewsResources import com.google.samples.apps.nowinandroid.core.testing.repository.TestNewsRepository import com.google.samples.apps.nowinandroid.core.testing.repository.TestUserDataRepository @@ -43,7 +43,7 @@ class BookmarksViewModelTest { private val userDataRepository = TestUserDataRepository() private val newsRepository = TestNewsRepository() - private val getSaveableNewsResourcesUseCase = GetSaveableNewsResourcesUseCase( + private val getUserNewsResourcesUseCase = GetUserNewsResourcesUseCase( newsRepository = newsRepository, userDataRepository = userDataRepository ) @@ -53,7 +53,7 @@ class BookmarksViewModelTest { fun setup() { viewModel = BookmarksViewModel( userDataRepository = userDataRepository, - getSaveableNewsResources = getSaveableNewsResourcesUseCase + getSaveableNewsResources = getUserNewsResourcesUseCase ) } diff --git a/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt b/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt index e1a5b5e9e..fb4d83c7e 100644 --- a/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt +++ b/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt @@ -84,6 +84,7 @@ import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource +import com.google.samples.apps.nowinandroid.core.domain.model.previewUserNewsResources import com.google.samples.apps.nowinandroid.core.model.data.previewNewsResources import com.google.samples.apps.nowinandroid.core.model.data.previewTopics import com.google.samples.apps.nowinandroid.core.ui.DevicePreviews @@ -396,9 +397,7 @@ fun ForYouScreenPopulatedFeed() { isSyncing = false, onboardingUiState = OnboardingUiState.NotShown, feedState = NewsFeedUiState.Success( - feed = previewNewsResources.map { - UserNewsResource(it, false) - } + feed = previewUserNewsResources ), onTopicCheckedChanged = { _, _ -> }, saveFollowedTopics = {}, @@ -417,9 +416,7 @@ fun ForYouScreenOfflinePopulatedFeed() { isSyncing = false, onboardingUiState = OnboardingUiState.NotShown, feedState = NewsFeedUiState.Success( - feed = previewNewsResources.map { - UserNewsResource(it, false) - } + feed = previewUserNewsResources ), onTopicCheckedChanged = { _, _ -> }, saveFollowedTopics = {}, @@ -440,9 +437,7 @@ fun ForYouScreenTopicSelection() { topics = previewTopics.map { FollowableTopic(it, false) }, ), feedState = NewsFeedUiState.Success( - feed = previewNewsResources.map { - UserNewsResource(it, false) - } + feed = previewUserNewsResources ), onTopicCheckedChanged = { _, _ -> }, saveFollowedTopics = {}, @@ -478,9 +473,7 @@ fun ForYouScreenPopulatedAndLoading() { isSyncing = true, onboardingUiState = OnboardingUiState.Loading, feedState = NewsFeedUiState.Success( - feed = previewNewsResources.map { - UserNewsResource(it, false) - } + feed = previewUserNewsResources ), onTopicCheckedChanged = { _, _ -> }, saveFollowedTopics = {}, diff --git a/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModel.kt b/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModel.kt index 645566056..6c9218a75 100644 --- a/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModel.kt +++ b/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModel.kt @@ -21,7 +21,7 @@ import androidx.lifecycle.viewModelScope import com.google.samples.apps.nowinandroid.core.data.repository.UserDataRepository import com.google.samples.apps.nowinandroid.core.data.util.SyncStatusMonitor import com.google.samples.apps.nowinandroid.core.domain.GetFollowableTopicsUseCase -import com.google.samples.apps.nowinandroid.core.domain.GetSaveableNewsResourcesUseCase +import com.google.samples.apps.nowinandroid.core.domain.GetUserNewsResourcesUseCase import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState import dagger.hilt.android.lifecycle.HiltViewModel @@ -41,7 +41,7 @@ import kotlinx.coroutines.launch class ForYouViewModel @Inject constructor( syncStatusMonitor: SyncStatusMonitor, private val userDataRepository: UserDataRepository, - private val getSaveableNewsResources: GetSaveableNewsResourcesUseCase, + private val getSaveableNewsResources: GetUserNewsResourcesUseCase, getFollowableTopics: GetFollowableTopicsUseCase ) : ViewModel() { diff --git a/feature/foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt b/feature/foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt index 06b7ebe7a..35b8a2f5a 100644 --- a/feature/foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt +++ b/feature/foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt @@ -17,7 +17,7 @@ package com.google.samples.apps.nowinandroid.feature.foryou import com.google.samples.apps.nowinandroid.core.domain.GetFollowableTopicsUseCase -import com.google.samples.apps.nowinandroid.core.domain.GetSaveableNewsResourcesUseCase +import com.google.samples.apps.nowinandroid.core.domain.GetUserNewsResourcesUseCase import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResource @@ -54,7 +54,7 @@ class ForYouViewModelTest { private val userDataRepository = TestUserDataRepository() private val topicsRepository = TestTopicsRepository() private val newsRepository = TestNewsRepository() - private val getSaveableNewsResourcesUseCase = GetSaveableNewsResourcesUseCase( + private val getUserNewsResourcesUseCase = GetUserNewsResourcesUseCase( newsRepository = newsRepository, userDataRepository = userDataRepository ) @@ -69,7 +69,7 @@ class ForYouViewModelTest { viewModel = ForYouViewModel( syncStatusMonitor = syncStatusMonitor, userDataRepository = userDataRepository, - getSaveableNewsResources = getSaveableNewsResourcesUseCase, + getSaveableNewsResources = getUserNewsResourcesUseCase, getFollowableTopics = getFollowableTopicsUseCase ) } @@ -283,7 +283,19 @@ class ForYouViewModelTest { feed = sampleNewsResources.map { UserNewsResource( - newsResource = it, + id = it.id, + title = it.title, + content = it.content, + url = it.url, + headerImageUrl = it.headerImageUrl, + publishDate = it.publishDate, + type = it.type, + topics = it.topics.map{ topic -> + FollowableTopic( + topic = topic, + isFollowed = false + ) + }, isSaved = false ) } @@ -398,11 +410,35 @@ class ForYouViewModelTest { NewsFeedUiState.Success( feed = listOf( UserNewsResource( - newsResource = sampleNewsResources[1], + id = sampleNewsResources[1].id, + title = sampleNewsResources[1].title, + content = sampleNewsResources[1].content, + url = sampleNewsResources[1].url, + headerImageUrl = sampleNewsResources[1].headerImageUrl, + publishDate = sampleNewsResources[1].publishDate, + type = sampleNewsResources[1].type, + topics = sampleNewsResources[1].topics.map{ topic -> + FollowableTopic( + topic = topic, + isFollowed = false + ) + }, isSaved = false ), UserNewsResource( - newsResource = sampleNewsResources[2], + id = sampleNewsResources[2].id, + title = sampleNewsResources[2].title, + content = sampleNewsResources[2].content, + url = sampleNewsResources[2].url, + headerImageUrl = sampleNewsResources[2].headerImageUrl, + publishDate = sampleNewsResources[2].publishDate, + type = sampleNewsResources[2].type, + topics = sampleNewsResources[2].topics.map{ topic -> + FollowableTopic( + topic = topic, + isFollowed = false + ) + }, isSaved = false ) ) @@ -498,13 +534,37 @@ class ForYouViewModelTest { NewsFeedUiState.Success( feed = listOf( UserNewsResource( - newsResource = sampleNewsResources[1], + id = sampleNewsResources[1].id, + title = sampleNewsResources[1].title, + content = sampleNewsResources[1].content, + url = sampleNewsResources[1].url, + headerImageUrl = sampleNewsResources[1].headerImageUrl, + publishDate = sampleNewsResources[1].publishDate, + type = sampleNewsResources[1].type, + topics = sampleNewsResources[1].topics.map{ topic -> + FollowableTopic( + topic = topic, + isFollowed = false + ) + }, isSaved = true ), UserNewsResource( - newsResource = sampleNewsResources[2], + id = sampleNewsResources[2].id, + title = sampleNewsResources[2].title, + content = sampleNewsResources[2].content, + url = sampleNewsResources[2].url, + headerImageUrl = sampleNewsResources[2].headerImageUrl, + publishDate = sampleNewsResources[2].publishDate, + type = sampleNewsResources[2].type, + topics = sampleNewsResources[2].topics.map{ topic -> + FollowableTopic( + topic = topic, + isFollowed = false + ) + }, isSaved = false - ) + ), ) ), viewModel.feedState.value diff --git a/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreen.kt b/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreen.kt index b57c96954..3e79318eb 100644 --- a/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreen.kt +++ b/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreen.kt @@ -54,6 +54,7 @@ import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource +import com.google.samples.apps.nowinandroid.core.domain.model.previewUserNewsResources import com.google.samples.apps.nowinandroid.core.model.data.previewNewsResources import com.google.samples.apps.nowinandroid.core.model.data.previewTopics import com.google.samples.apps.nowinandroid.core.ui.DevicePreviews @@ -182,9 +183,9 @@ private fun LazyListScope.TopicCards( is NewsUiState.Success -> { newsResourceCardItems( items = news.news, - newsResourceMapper = { it.newsResource }, + newsResourceMapper = { it }, isBookmarkedMapper = { it.isSaved }, - onToggleBookmark = { onBookmarkChanged(it.newsResource.id, !it.isSaved) }, + onToggleBookmark = { onBookmarkChanged(it.id, !it.isSaved) }, itemModifier = Modifier.padding(24.dp) ) } @@ -257,12 +258,7 @@ fun TopicScreenPopulated() { TopicScreen( topicUiState = TopicUiState.Success(FollowableTopic(previewTopics[0], false)), newsUiState = NewsUiState.Success( - previewNewsResources.mapIndexed { index, newsResource -> - UserNewsResource( - newsResource = newsResource, - isSaved = index % 2 == 0, - ) - } + previewUserNewsResources ), onBackClick = {}, onFollowClick = {}, diff --git a/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModel.kt b/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModel.kt index e65bc1dee..1f08d233a 100644 --- a/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModel.kt +++ b/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModel.kt @@ -22,7 +22,7 @@ import androidx.lifecycle.viewModelScope import com.google.samples.apps.nowinandroid.core.data.repository.TopicsRepository import com.google.samples.apps.nowinandroid.core.data.repository.UserDataRepository import com.google.samples.apps.nowinandroid.core.decoder.StringDecoder -import com.google.samples.apps.nowinandroid.core.domain.GetSaveableNewsResourcesUseCase +import com.google.samples.apps.nowinandroid.core.domain.GetUserNewsResourcesUseCase import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.model.data.Topic @@ -46,7 +46,7 @@ class TopicViewModel @Inject constructor( private val userDataRepository: UserDataRepository, topicsRepository: TopicsRepository, // newsRepository: NewsRepository, - getSaveableNewsResources: GetSaveableNewsResourcesUseCase + getSaveableNewsResources: GetUserNewsResourcesUseCase ) : ViewModel() { private val topicArgs: TopicArgs = TopicArgs(savedStateHandle, stringDecoder) @@ -131,7 +131,7 @@ private fun topicUiState( private fun newsUiState( topicId: String, - getSaveableNewsResources: GetSaveableNewsResourcesUseCase, + getSaveableNewsResources: GetUserNewsResourcesUseCase, userDataRepository: UserDataRepository, ): Flow { // Observe news diff --git a/feature/topic/src/test/java/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModelTest.kt b/feature/topic/src/test/java/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModelTest.kt index 32768c4d7..6c61e59d5 100644 --- a/feature/topic/src/test/java/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModelTest.kt +++ b/feature/topic/src/test/java/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModelTest.kt @@ -17,7 +17,7 @@ package com.google.samples.apps.nowinandroid.feature.topic import androidx.lifecycle.SavedStateHandle -import com.google.samples.apps.nowinandroid.core.domain.GetSaveableNewsResourcesUseCase +import com.google.samples.apps.nowinandroid.core.domain.GetUserNewsResourcesUseCase import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType.Video @@ -53,7 +53,7 @@ class TopicViewModelTest { private val userDataRepository = TestUserDataRepository() private val topicsRepository = TestTopicsRepository() private val newsRepository = TestNewsRepository() - private val getSaveableNewsResourcesUseCase = GetSaveableNewsResourcesUseCase( + private val getUserNewsResourcesUseCase = GetUserNewsResourcesUseCase( newsRepository = newsRepository, userDataRepository = userDataRepository ) @@ -66,7 +66,7 @@ class TopicViewModelTest { stringDecoder = FakeStringDecoder(), userDataRepository = userDataRepository, topicsRepository = topicsRepository, - getSaveableNewsResources = getSaveableNewsResourcesUseCase + getSaveableNewsResources = getUserNewsResourcesUseCase ) } From 6941e2082be9ee4712b8ed612ad80fdc25c1c06b Mon Sep 17 00:00:00 2001 From: magicalmeghan Date: Mon, 19 Dec 2022 09:22:47 -0800 Subject: [PATCH 03/20] Renamed SaveableNewsResource to UserNewsResource --- .../core/domain/GetSaveableNewsResourcesUseCase.kt | 8 ++++---- .../{SaveableNewsResource.kt => UserNewsResource.kt} | 2 +- ...aseTest.kt => GetUserNewsResourcesUseCaseTest.kt} | 12 ++++++------ .../samples/apps/nowinandroid/core/ui/NewsFeed.kt | 6 +++--- .../feature/bookmarks/BookmarksScreenTest.kt | 6 +++--- .../feature/bookmarks/BookmarksScreen.kt | 4 ++-- .../feature/bookmarks/BookmarksViewModel.kt | 6 +++--- .../nowinandroid/feature/foryou/ForYouScreenTest.kt | 4 ++-- .../apps/nowinandroid/feature/foryou/ForYouScreen.kt | 10 +++++----- .../nowinandroid/feature/foryou/ForYouViewModel.kt | 6 +++--- .../feature/foryou/ForYouViewModelTest.kt | 12 ++++++------ .../nowinandroid/feature/topic/TopicScreenTest.kt | 6 +++--- .../apps/nowinandroid/feature/topic/TopicScreen.kt | 4 ++-- .../nowinandroid/feature/topic/TopicViewModel.kt | 6 +++--- 14 files changed, 46 insertions(+), 46 deletions(-) rename core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/{SaveableNewsResource.kt => UserNewsResource.kt} (96%) rename core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/{GetSaveableNewsResourcesUseCaseTest.kt => GetUserNewsResourcesUseCaseTest.kt} (92%) diff --git a/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetSaveableNewsResourcesUseCase.kt b/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetSaveableNewsResourcesUseCase.kt index 4bd2fc6c3..df63a4487 100644 --- a/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetSaveableNewsResourcesUseCase.kt +++ b/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetSaveableNewsResourcesUseCase.kt @@ -18,7 +18,7 @@ package com.google.samples.apps.nowinandroid.core.domain import com.google.samples.apps.nowinandroid.core.data.repository.NewsRepository import com.google.samples.apps.nowinandroid.core.data.repository.UserDataRepository -import com.google.samples.apps.nowinandroid.core.domain.model.SaveableNewsResource +import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import javax.inject.Inject import kotlinx.coroutines.flow.Flow @@ -47,7 +47,7 @@ class GetSaveableNewsResourcesUseCase @Inject constructor( */ operator fun invoke( filterTopicIds: Set = emptySet() - ): Flow> = + ): Flow> = if (filterTopicIds.isEmpty()) { newsRepository.getNewsResources() } else { @@ -57,11 +57,11 @@ class GetSaveableNewsResourcesUseCase @Inject constructor( private fun Flow>.mapToSaveableNewsResources( savedNewsResourceIds: Flow> -): Flow> = +): Flow> = filterNot { it.isEmpty() } .combine(savedNewsResourceIds) { newsResources, savedNewsResourceIds -> newsResources.map { newsResource -> - SaveableNewsResource( + UserNewsResource( newsResource = newsResource, isSaved = savedNewsResourceIds.contains(newsResource.id) ) diff --git a/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/SaveableNewsResource.kt b/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/UserNewsResource.kt similarity index 96% rename from core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/SaveableNewsResource.kt rename to core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/UserNewsResource.kt index 6850d421f..ddd8a27f6 100644 --- a/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/SaveableNewsResource.kt +++ b/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/UserNewsResource.kt @@ -21,7 +21,7 @@ import com.google.samples.apps.nowinandroid.core.model.data.NewsResource /** * A [NewsResource] with the additional information for whether it is saved. */ -data class SaveableNewsResource( +data class UserNewsResource( val newsResource: NewsResource, val isSaved: Boolean, ) diff --git a/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetSaveableNewsResourcesUseCaseTest.kt b/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt similarity index 92% rename from core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetSaveableNewsResourcesUseCaseTest.kt rename to core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt index 876811e61..6bdbd9f34 100644 --- a/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetSaveableNewsResourcesUseCaseTest.kt +++ b/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt @@ -16,7 +16,7 @@ package com.google.samples.apps.nowinandroid.core.domain -import com.google.samples.apps.nowinandroid.core.domain.model.SaveableNewsResource +import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType.Video import com.google.samples.apps.nowinandroid.core.model.data.Topic @@ -30,7 +30,7 @@ import kotlinx.datetime.Instant import org.junit.Rule import org.junit.Test -class GetSaveableNewsResourcesUseCaseTest { +class GetUserNewsResourcesUseCaseTest { @get:Rule val mainDispatcherRule = MainDispatcherRule() @@ -55,9 +55,9 @@ class GetSaveableNewsResourcesUseCaseTest { // Check that the correct news resources are returned with their bookmarked state. assertEquals( listOf( - SaveableNewsResource(sampleNewsResources[0], true), - SaveableNewsResource(sampleNewsResources[1], false), - SaveableNewsResource(sampleNewsResources[2], true) + UserNewsResource(sampleNewsResources[0], true), + UserNewsResource(sampleNewsResources[1], false), + UserNewsResource(sampleNewsResources[2], true) ), saveableNewsResources.first() ) @@ -77,7 +77,7 @@ class GetSaveableNewsResourcesUseCaseTest { assertEquals( sampleNewsResources .filter { it.topics.contains(sampleTopic1) } - .map { SaveableNewsResource(it, false) }, + .map { UserNewsResource(it, false) }, saveableNewsResources.first() ) } diff --git a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsFeed.kt b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsFeed.kt index 55d84af2f..cf2714db7 100644 --- a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsFeed.kt +++ b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsFeed.kt @@ -37,7 +37,7 @@ import androidx.compose.ui.tooling.preview.Devices import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme -import com.google.samples.apps.nowinandroid.core.domain.model.SaveableNewsResource +import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.model.data.previewNewsResources /** @@ -100,7 +100,7 @@ sealed interface NewsFeedUiState { /** * The list of news resources contained in this feed. */ - val feed: List + val feed: List ) : NewsFeedUiState } @@ -126,7 +126,7 @@ fun NewsFeedContentPreview() { newsFeed( feedState = NewsFeedUiState.Success( previewNewsResources.map { - SaveableNewsResource( + UserNewsResource( it, false ) diff --git a/feature/bookmarks/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreenTest.kt b/feature/bookmarks/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreenTest.kt index 1dafc5c98..3421f885a 100644 --- a/feature/bookmarks/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreenTest.kt +++ b/feature/bookmarks/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreenTest.kt @@ -31,7 +31,7 @@ import androidx.compose.ui.test.onNodeWithContentDescription import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick import androidx.compose.ui.test.performScrollToNode -import com.google.samples.apps.nowinandroid.core.domain.model.SaveableNewsResource +import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.model.data.previewNewsResources import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState import kotlin.test.assertEquals @@ -71,7 +71,7 @@ class BookmarksScreenTest { BookmarksScreen( feedState = NewsFeedUiState.Success( previewNewsResources.take(2) - .map { SaveableNewsResource(it, true) } + .map { UserNewsResource(it, true) } ), removeFromBookmarks = { } ) @@ -110,7 +110,7 @@ class BookmarksScreenTest { BookmarksScreen( feedState = NewsFeedUiState.Success( previewNewsResources.take(2) - .map { SaveableNewsResource(it, true) } + .map { UserNewsResource(it, true) } ), removeFromBookmarks = { newsResourceId -> assertEquals(previewNewsResources[0].id, newsResourceId) diff --git a/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreen.kt b/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreen.kt index 06a87bc9e..0bab4e449 100644 --- a/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreen.kt +++ b/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreen.kt @@ -52,7 +52,7 @@ import androidx.lifecycle.compose.ExperimentalLifecycleComposeApi import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaLoadingWheel import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme -import com.google.samples.apps.nowinandroid.core.domain.model.SaveableNewsResource +import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.model.data.previewNewsResources import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState.Loading @@ -185,7 +185,7 @@ private fun BookmarksGridPreview() { BookmarksGrid( feedState = Success( previewNewsResources.map { - SaveableNewsResource(it, false) + UserNewsResource(it, false) } ), removeFromBookmarks = {} diff --git a/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModel.kt b/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModel.kt index 8223ecd1b..8ea565bfd 100644 --- a/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModel.kt +++ b/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModel.kt @@ -20,7 +20,7 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.google.samples.apps.nowinandroid.core.data.repository.UserDataRepository import com.google.samples.apps.nowinandroid.core.domain.GetSaveableNewsResourcesUseCase -import com.google.samples.apps.nowinandroid.core.domain.model.SaveableNewsResource +import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState.Loading import dagger.hilt.android.lifecycle.HiltViewModel @@ -41,8 +41,8 @@ class BookmarksViewModel @Inject constructor( val feedUiState: StateFlow = getSaveableNewsResources() .filterNot { it.isEmpty() } - .map { newsResources -> newsResources.filter(SaveableNewsResource::isSaved) } // Only show bookmarked news resources. - .map, NewsFeedUiState>(NewsFeedUiState::Success) + .map { newsResources -> newsResources.filter(UserNewsResource::isSaved) } // Only show bookmarked news resources. + .map, NewsFeedUiState>(NewsFeedUiState::Success) .onStart { emit(Loading) } .stateIn( scope = viewModelScope, diff --git a/feature/foryou/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt b/feature/foryou/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt index 702a963c1..ee6e2795b 100644 --- a/feature/foryou/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt +++ b/feature/foryou/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt @@ -29,7 +29,7 @@ import androidx.compose.ui.test.onNodeWithContentDescription import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performScrollToNode import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic -import com.google.samples.apps.nowinandroid.core.domain.model.SaveableNewsResource +import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.model.data.Topic import com.google.samples.apps.nowinandroid.core.model.data.previewNewsResources import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState @@ -226,7 +226,7 @@ class ForYouScreenTest { onboardingUiState = OnboardingUiState.NotShown, feedState = NewsFeedUiState.Success( feed = previewNewsResources.map { - SaveableNewsResource(it, false) + UserNewsResource(it, false) } ), onTopicCheckedChanged = { _, _ -> }, diff --git a/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt b/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt index 1427aecff..e1a5b5e9e 100644 --- a/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt +++ b/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt @@ -83,7 +83,7 @@ import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaOverl import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic -import com.google.samples.apps.nowinandroid.core.domain.model.SaveableNewsResource +import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.model.data.previewNewsResources import com.google.samples.apps.nowinandroid.core.model.data.previewTopics import com.google.samples.apps.nowinandroid.core.ui.DevicePreviews @@ -397,7 +397,7 @@ fun ForYouScreenPopulatedFeed() { onboardingUiState = OnboardingUiState.NotShown, feedState = NewsFeedUiState.Success( feed = previewNewsResources.map { - SaveableNewsResource(it, false) + UserNewsResource(it, false) } ), onTopicCheckedChanged = { _, _ -> }, @@ -418,7 +418,7 @@ fun ForYouScreenOfflinePopulatedFeed() { onboardingUiState = OnboardingUiState.NotShown, feedState = NewsFeedUiState.Success( feed = previewNewsResources.map { - SaveableNewsResource(it, false) + UserNewsResource(it, false) } ), onTopicCheckedChanged = { _, _ -> }, @@ -441,7 +441,7 @@ fun ForYouScreenTopicSelection() { ), feedState = NewsFeedUiState.Success( feed = previewNewsResources.map { - SaveableNewsResource(it, false) + UserNewsResource(it, false) } ), onTopicCheckedChanged = { _, _ -> }, @@ -479,7 +479,7 @@ fun ForYouScreenPopulatedAndLoading() { onboardingUiState = OnboardingUiState.Loading, feedState = NewsFeedUiState.Success( feed = previewNewsResources.map { - SaveableNewsResource(it, false) + UserNewsResource(it, false) } ), onTopicCheckedChanged = { _, _ -> }, diff --git a/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModel.kt b/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModel.kt index 800cba0d3..645566056 100644 --- a/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModel.kt +++ b/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModel.kt @@ -22,7 +22,7 @@ import com.google.samples.apps.nowinandroid.core.data.repository.UserDataReposit import com.google.samples.apps.nowinandroid.core.data.util.SyncStatusMonitor import com.google.samples.apps.nowinandroid.core.domain.GetFollowableTopicsUseCase import com.google.samples.apps.nowinandroid.core.domain.GetSaveableNewsResourcesUseCase -import com.google.samples.apps.nowinandroid.core.domain.model.SaveableNewsResource +import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject @@ -117,6 +117,6 @@ class ForYouViewModel @Inject constructor( } } -private fun Flow>.mapToFeedState(): Flow = - map, NewsFeedUiState>(NewsFeedUiState::Success) +private fun Flow>.mapToFeedState(): Flow = + map, NewsFeedUiState>(NewsFeedUiState::Success) .onStart { emit(NewsFeedUiState.Loading) } diff --git a/feature/foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt b/feature/foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt index ad29aba60..06b7ebe7a 100644 --- a/feature/foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt +++ b/feature/foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt @@ -19,7 +19,7 @@ package com.google.samples.apps.nowinandroid.feature.foryou import com.google.samples.apps.nowinandroid.core.domain.GetFollowableTopicsUseCase import com.google.samples.apps.nowinandroid.core.domain.GetSaveableNewsResourcesUseCase import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic -import com.google.samples.apps.nowinandroid.core.domain.model.SaveableNewsResource +import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType.Video import com.google.samples.apps.nowinandroid.core.model.data.Topic @@ -282,7 +282,7 @@ class ForYouViewModelTest { NewsFeedUiState.Success( feed = sampleNewsResources.map { - SaveableNewsResource( + UserNewsResource( newsResource = it, isSaved = false ) @@ -397,11 +397,11 @@ class ForYouViewModelTest { assertEquals( NewsFeedUiState.Success( feed = listOf( - SaveableNewsResource( + UserNewsResource( newsResource = sampleNewsResources[1], isSaved = false ), - SaveableNewsResource( + UserNewsResource( newsResource = sampleNewsResources[2], isSaved = false ) @@ -497,11 +497,11 @@ class ForYouViewModelTest { assertEquals( NewsFeedUiState.Success( feed = listOf( - SaveableNewsResource( + UserNewsResource( newsResource = sampleNewsResources[1], isSaved = true ), - SaveableNewsResource( + UserNewsResource( newsResource = sampleNewsResources[2], isSaved = false ) diff --git a/feature/topic/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreenTest.kt b/feature/topic/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreenTest.kt index 9bef39a36..0f6d2dcc0 100644 --- a/feature/topic/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreenTest.kt +++ b/feature/topic/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreenTest.kt @@ -25,7 +25,7 @@ import androidx.compose.ui.test.onNodeWithContentDescription import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performScrollToNode import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic -import com.google.samples.apps.nowinandroid.core.domain.model.SaveableNewsResource +import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType.Video import com.google.samples.apps.nowinandroid.core.model.data.Topic @@ -101,7 +101,7 @@ class TopicScreenTest { topicUiState = TopicUiState.Loading, newsUiState = NewsUiState.Success( sampleNewsResources.mapIndexed { index, newsResource -> - SaveableNewsResource( + UserNewsResource( newsResource = newsResource, isSaved = index % 2 == 0, ) @@ -127,7 +127,7 @@ class TopicScreenTest { topicUiState = TopicUiState.Success(testTopic), newsUiState = NewsUiState.Success( sampleNewsResources.mapIndexed { index, newsResource -> - SaveableNewsResource( + UserNewsResource( newsResource = newsResource, isSaved = index % 2 == 0, ) diff --git a/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreen.kt b/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreen.kt index 61bd13aa0..b57c96954 100644 --- a/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreen.kt +++ b/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreen.kt @@ -53,7 +53,7 @@ import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaLoadi import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic -import com.google.samples.apps.nowinandroid.core.domain.model.SaveableNewsResource +import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.model.data.previewNewsResources import com.google.samples.apps.nowinandroid.core.model.data.previewTopics import com.google.samples.apps.nowinandroid.core.ui.DevicePreviews @@ -258,7 +258,7 @@ fun TopicScreenPopulated() { topicUiState = TopicUiState.Success(FollowableTopic(previewTopics[0], false)), newsUiState = NewsUiState.Success( previewNewsResources.mapIndexed { index, newsResource -> - SaveableNewsResource( + UserNewsResource( newsResource = newsResource, isSaved = index % 2 == 0, ) diff --git a/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModel.kt b/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModel.kt index 17096ca88..e65bc1dee 100644 --- a/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModel.kt +++ b/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModel.kt @@ -24,7 +24,7 @@ import com.google.samples.apps.nowinandroid.core.data.repository.UserDataReposit import com.google.samples.apps.nowinandroid.core.decoder.StringDecoder import com.google.samples.apps.nowinandroid.core.domain.GetSaveableNewsResourcesUseCase import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic -import com.google.samples.apps.nowinandroid.core.domain.model.SaveableNewsResource +import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.model.data.Topic import com.google.samples.apps.nowinandroid.core.result.Result import com.google.samples.apps.nowinandroid.core.result.asResult @@ -135,7 +135,7 @@ private fun newsUiState( userDataRepository: UserDataRepository, ): Flow { // Observe news - val news: Flow> = getSaveableNewsResources( + val news: Flow> = getSaveableNewsResources( filterTopicIds = setOf(element = topicId), ) @@ -172,7 +172,7 @@ sealed interface TopicUiState { } sealed interface NewsUiState { - data class Success(val news: List) : NewsUiState + data class Success(val news: List) : NewsUiState object Error : NewsUiState object Loading : NewsUiState } From ec4bceead3668b90cc7f896cb9f6130ae44cb01f Mon Sep 17 00:00:00 2001 From: magicalmeghan Date: Mon, 19 Dec 2022 11:39:05 -0800 Subject: [PATCH 04/20] Renamed SaveableNewsResource to UserNewsResource --- ...Case.kt => GetUserNewsResourcesUseCase.kt} | 36 ++++---- .../core/domain/model/FollowableTopic.kt | 18 +++- .../core/domain/model/UserNewsResource.kt | 84 ++++++++++++++++++- .../domain/GetUserNewsResourcesUseCaseTest.kt | 67 +++++++++++++-- .../core/ui/NewsResourceCardTest.kt | 4 +- .../apps/nowinandroid/core/ui/NewsFeed.kt | 21 ++--- .../nowinandroid/core/ui/NewsResourceCard.kt | 30 +++---- .../core/ui/NewsResourceCardList.kt | 5 +- .../feature/bookmarks/BookmarksScreen.kt | 5 +- .../feature/bookmarks/BookmarksViewModel.kt | 4 +- .../bookmarks/BookmarksViewModelTest.kt | 6 +- .../feature/foryou/ForYouScreen.kt | 17 ++-- .../feature/foryou/ForYouViewModel.kt | 4 +- .../feature/foryou/ForYouViewModelTest.kt | 78 +++++++++++++++-- .../nowinandroid/feature/topic/TopicScreen.kt | 12 +-- .../feature/topic/TopicViewModel.kt | 6 +- .../feature/topic/TopicViewModelTest.kt | 6 +- 17 files changed, 304 insertions(+), 99 deletions(-) rename core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/{GetSaveableNewsResourcesUseCase.kt => GetUserNewsResourcesUseCase.kt} (62%) diff --git a/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetSaveableNewsResourcesUseCase.kt b/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCase.kt similarity index 62% rename from core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetSaveableNewsResourcesUseCase.kt rename to core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCase.kt index df63a4487..19d65581f 100644 --- a/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetSaveableNewsResourcesUseCase.kt +++ b/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCase.kt @@ -18,29 +18,25 @@ package com.google.samples.apps.nowinandroid.core.domain import com.google.samples.apps.nowinandroid.core.data.repository.NewsRepository import com.google.samples.apps.nowinandroid.core.data.repository.UserDataRepository +import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResource +import com.google.samples.apps.nowinandroid.core.model.data.UserData import javax.inject.Inject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.filterNot -import kotlinx.coroutines.flow.map /** * A use case responsible for obtaining news resources with their associated bookmarked (also known * as "saved") state. */ -class GetSaveableNewsResourcesUseCase @Inject constructor( +class GetUserNewsResourcesUseCase @Inject constructor( private val newsRepository: NewsRepository, - userDataRepository: UserDataRepository + private val userDataRepository: UserDataRepository ) { - - private val bookmarkedNewsResources = userDataRepository.userData.map { - it.bookmarkedNewsResources - } - /** - * Returns a list of SaveableNewsResources which match the supplied set of topic ids. + * Returns a list of UserNewsResources which match the supplied set of topic ids. * * @param filterTopicIds - A set of topic ids used to filter the list of news resources. If * this is empty the list of news resources will not be filtered. @@ -52,18 +48,30 @@ class GetSaveableNewsResourcesUseCase @Inject constructor( newsRepository.getNewsResources() } else { newsRepository.getNewsResources(filterTopicIds = filterTopicIds) - }.mapToSaveableNewsResources(bookmarkedNewsResources) + }.mapToSaveableNewsResources(userDataRepository.userData) } private fun Flow>.mapToSaveableNewsResources( - savedNewsResourceIds: Flow> + userData: Flow ): Flow> = filterNot { it.isEmpty() } - .combine(savedNewsResourceIds) { newsResources, savedNewsResourceIds -> + .combine(userData) { newsResources, userData -> newsResources.map { newsResource -> UserNewsResource( - newsResource = newsResource, - isSaved = savedNewsResourceIds.contains(newsResource.id) + id = newsResource.id, + title = newsResource.title, + content = newsResource.content, + url = newsResource.url, + headerImageUrl = newsResource.headerImageUrl, + publishDate = newsResource.publishDate, + type = newsResource.type, + topics = newsResource.topics.map { topic -> + FollowableTopic( + topic = topic, + isFollowed = userData.followedTopics.contains(topic.id) + ) + }, + isSaved = userData.bookmarkedNewsResources.contains(newsResource.id) ) } } diff --git a/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/FollowableTopic.kt b/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/FollowableTopic.kt index 87a77daa4..c081abf1f 100644 --- a/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/FollowableTopic.kt +++ b/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/FollowableTopic.kt @@ -17,11 +17,27 @@ package com.google.samples.apps.nowinandroid.core.domain.model import com.google.samples.apps.nowinandroid.core.model.data.Topic +import com.google.samples.apps.nowinandroid.core.model.data.previewTopics /** * A [topic] with the additional information for whether or not it is followed. */ -data class FollowableTopic( +data class FollowableTopic( //TODO consider changing to UserTopic and flattening val topic: Topic, val isFollowed: Boolean ) + +val previewFollowableTopics = listOf( + FollowableTopic( + previewTopics[0], + isFollowed = false + ), + FollowableTopic( + previewTopics[1], + isFollowed = true + ), + FollowableTopic( + previewTopics[2], + isFollowed = false + ) +) diff --git a/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/UserNewsResource.kt b/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/UserNewsResource.kt index ddd8a27f6..c70f549b2 100644 --- a/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/UserNewsResource.kt +++ b/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/UserNewsResource.kt @@ -17,11 +17,89 @@ package com.google.samples.apps.nowinandroid.core.domain.model import com.google.samples.apps.nowinandroid.core.model.data.NewsResource +import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType +import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType.Codelab +import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType.Unknown +import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType.Video +import com.google.samples.apps.nowinandroid.core.model.data.previewTopics +import kotlinx.datetime.Instant +import kotlinx.datetime.LocalDateTime +import kotlinx.datetime.TimeZone +import kotlinx.datetime.toInstant /** - * A [NewsResource] with the additional information for whether it is saved. + * A [NewsResource] with the additional user information. */ data class UserNewsResource( - val newsResource: NewsResource, - val isSaved: Boolean, + val id: String, + val title: String, + val content: String, + val url: String, + val headerImageUrl: String?, + val publishDate: Instant, + val type: NewsResourceType, + val topics: List, + val isSaved: Boolean +) + +val previewUserNewsResources = listOf( + UserNewsResource( + id = "1", + title = "Android Basics with Compose", + content = "We released the first two units of Android Basics with Compose, our first free course that teaches Android Development with Jetpack Compose to anyone; you do not need any prior programming experience other than basic computer literacy to get started. You’ll learn the fundamentals of programming in Kotlin while building Android apps using Jetpack Compose, Android’s modern toolkit that simplifies and accelerates native UI development. These two units are just the beginning; more will be coming soon. Check out Android Basics with Compose to get started on your Android development journey", + url = "https://android-developers.googleblog.com/2022/05/new-android-basics-with-compose-course.html", + headerImageUrl = "https://developer.android.com/images/hero-assets/android-basics-compose.svg", + publishDate = LocalDateTime( + year = 2022, + monthNumber = 5, + dayOfMonth = 4, + hour = 23, + minute = 0, + second = 0, + nanosecond = 0 + ).toInstant(TimeZone.UTC), + type = Codelab, + topics = listOf(previewFollowableTopics[1]), + isSaved = true + ), + UserNewsResource( + id = "2", + title = "Thanks for helping us reach 1M YouTube Subscribers", + content = "Thank you everyone for following the Now in Android series and everything the " + + "Android Developers YouTube channel has to offer. During the Android Developer " + + "Summit, our YouTube channel reached 1 million subscribers! Here’s a small video to " + + "thank you all.", + url = "https://youtu.be/-fJ6poHQrjM", + headerImageUrl = "https://i.ytimg.com/vi/-fJ6poHQrjM/maxresdefault.jpg", + publishDate = Instant.parse("2021-11-09T00:00:00.000Z"), + type = Video, + topics = listOf(previewFollowableTopics[0], previewFollowableTopics[1]), + isSaved = false + ), + UserNewsResource( + id = "3", + title = "Transformations and customisations in the Paging Library", + content = "A demonstration of different operations that can be performed " + + "with Paging. Transformations like inserting separators, when to " + + "create a new pager, and customisation options for consuming " + + "PagingData.", + url = "https://youtu.be/ZARz0pjm5YM", + headerImageUrl = "https://i.ytimg.com/vi/ZARz0pjm5YM/maxresdefault.jpg", + publishDate = Instant.parse("2021-11-01T00:00:00.000Z"), + type = Video, + topics = listOf(previewFollowableTopics[2]), + isSaved = false + ), + UserNewsResource( + id = "4", + title = "New Jetpack Release", + content = "New Jetpack release includes updates to libraries such as CameraX, Benchmark, and" + + "more!", + url = "https://developer.android.com/jetpack/androidx/versions/all-channel", + headerImageUrl = "", + publishDate = Instant.parse("2022-10-01T00:00:00.000Z"), + type = Unknown, + topics = listOf(previewFollowableTopics[2]), + isSaved = true + ) ) diff --git a/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt b/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt index 6bdbd9f34..ce730d6f2 100644 --- a/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt +++ b/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt @@ -16,6 +16,7 @@ package com.google.samples.apps.nowinandroid.core.domain +import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType.Video @@ -38,7 +39,7 @@ class GetUserNewsResourcesUseCaseTest { private val newsRepository = TestNewsRepository() private val userDataRepository = TestUserDataRepository() - val useCase = GetSaveableNewsResourcesUseCase(newsRepository, userDataRepository) + val useCase = GetUserNewsResourcesUseCase(newsRepository, userDataRepository) @Test fun whenNoFilters_allNewsResourcesAreReturned() = runTest { @@ -55,9 +56,51 @@ class GetUserNewsResourcesUseCaseTest { // Check that the correct news resources are returned with their bookmarked state. assertEquals( listOf( - UserNewsResource(sampleNewsResources[0], true), - UserNewsResource(sampleNewsResources[1], false), - UserNewsResource(sampleNewsResources[2], true) + UserNewsResource( + sampleNewsResources[0].id, + sampleNewsResources[0].title, + sampleNewsResources[0].content, + sampleNewsResources[0].url, + sampleNewsResources[0].headerImageUrl, + sampleNewsResources[0].publishDate, + sampleNewsResources[0].type, + sampleNewsResources[0].topics.map { topic -> + FollowableTopic( + topic = topic, + isFollowed = false + ) + }, + true), + UserNewsResource( + sampleNewsResources[1].id, + sampleNewsResources[1].title, + sampleNewsResources[1].content, + sampleNewsResources[1].url, + sampleNewsResources[1].headerImageUrl, + sampleNewsResources[1].publishDate, + sampleNewsResources[1].type, + sampleNewsResources[1].topics.map { topic -> + FollowableTopic( + topic = topic, + isFollowed = false + ) + }, + false), + UserNewsResource( + sampleNewsResources[2].id, + sampleNewsResources[2].title, + sampleNewsResources[2].content, + sampleNewsResources[2].url, + sampleNewsResources[2].headerImageUrl, + sampleNewsResources[2].publishDate, + sampleNewsResources[2].type, + sampleNewsResources[2].topics.map { topic -> + FollowableTopic( + topic = topic, + isFollowed = true + ) + }, + true), ), saveableNewsResources.first() ) @@ -77,7 +120,21 @@ class GetUserNewsResourcesUseCaseTest { assertEquals( sampleNewsResources .filter { it.topics.contains(sampleTopic1) } - .map { UserNewsResource(it, false) }, + .map { UserNewsResource( + id = it.id, + title = it.title, + content = it.content, + url = it.url, + headerImageUrl = it.headerImageUrl, + publishDate = it.publishDate, + type = it.type, + topics = it.topics.map { topic -> + FollowableTopic( + topic = topic, + isFollowed = false + ) + }, + isSaved = false) }, saveableNewsResources.first() ) } diff --git a/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt b/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt index 69f919a62..c334f1bab 100644 --- a/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt +++ b/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt @@ -35,7 +35,7 @@ class NewsResourceCardTest { composeTestRule.setContent { NewsResourceCardExpanded( - newsResource = newsWithKnownResourceType, + userNewsResource = newsWithKnownResourceType, isBookmarked = false, onToggleBookmark = {}, onClick = {} @@ -62,7 +62,7 @@ class NewsResourceCardTest { composeTestRule.setContent { NewsResourceCardExpanded( - newsResource = newsWithUnknownResourceType, + userNewsResource = newsWithUnknownResourceType, isBookmarked = false, onToggleBookmark = {}, onClick = {} diff --git a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsFeed.kt b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsFeed.kt index cf2714db7..a4ccdaca5 100644 --- a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsFeed.kt +++ b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsFeed.kt @@ -38,7 +38,7 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource -import com.google.samples.apps.nowinandroid.core.model.data.previewNewsResources +import com.google.samples.apps.nowinandroid.core.domain.model.previewUserNewsResources /** * An extension on [LazyListScope] defining a feed with news resources. @@ -51,21 +51,21 @@ fun LazyGridScope.newsFeed( when (feedState) { NewsFeedUiState.Loading -> Unit is NewsFeedUiState.Success -> { - items(feedState.feed, key = { it.newsResource.id }) { saveableNewsResource -> + items(feedState.feed, key = { it.id }) { userNewsResource -> val resourceUrl by remember { - mutableStateOf(Uri.parse(saveableNewsResource.newsResource.url)) + mutableStateOf(Uri.parse(userNewsResource.url)) } val context = LocalContext.current val backgroundColor = MaterialTheme.colorScheme.background.toArgb() NewsResourceCardExpanded( - newsResource = saveableNewsResource.newsResource, - isBookmarked = saveableNewsResource.isSaved, + userNewsResource = userNewsResource, + isBookmarked = userNewsResource.isSaved, onClick = { launchCustomChromeTab(context, resourceUrl, backgroundColor) }, onToggleBookmark = { onNewsResourcesCheckedChanged( - saveableNewsResource.newsResource.id, - !saveableNewsResource.isSaved + userNewsResource.id, + !userNewsResource.isSaved ) } ) @@ -125,12 +125,7 @@ fun NewsFeedContentPreview() { LazyVerticalGrid(columns = GridCells.Adaptive(300.dp)) { newsFeed( feedState = NewsFeedUiState.Success( - previewNewsResources.map { - UserNewsResource( - it, - false - ) - } + previewUserNewsResources ), onNewsResourcesCheckedChanged = { _, _ -> } ) diff --git a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt index 21ee1a7a8..6eb6e7859 100644 --- a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt +++ b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt @@ -56,9 +56,11 @@ import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaIconT import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaTopicTag import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme +import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic +import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource +import com.google.samples.apps.nowinandroid.core.domain.model.previewUserNewsResources import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType -import com.google.samples.apps.nowinandroid.core.model.data.Topic import com.google.samples.apps.nowinandroid.core.model.data.previewNewsResources import java.time.ZoneId import java.time.format.DateTimeFormatter @@ -73,7 +75,7 @@ import kotlinx.datetime.toJavaInstant @OptIn(ExperimentalMaterial3Api::class) @Composable fun NewsResourceCardExpanded( - newsResource: NewsResource, + userNewsResource: UserNewsResource, isBookmarked: Boolean, onToggleBookmark: () -> Unit, onClick: () -> Unit, @@ -91,9 +93,9 @@ fun NewsResourceCardExpanded( } ) { Column { - if (!newsResource.headerImageUrl.isNullOrEmpty()) { + if (!userNewsResource.headerImageUrl.isNullOrEmpty()) { Row { - NewsResourceHeaderImage(newsResource.headerImageUrl) + NewsResourceHeaderImage(userNewsResource.headerImageUrl) } } Box( @@ -103,18 +105,18 @@ fun NewsResourceCardExpanded( Spacer(modifier = Modifier.height(12.dp)) Row { NewsResourceTitle( - newsResource.title, + userNewsResource.title, modifier = Modifier.fillMaxWidth((.8f)) ) Spacer(modifier = Modifier.weight(1f)) BookmarkButton(isBookmarked, onToggleBookmark) } Spacer(modifier = Modifier.height(12.dp)) - NewsResourceMetaData(newsResource.publishDate, newsResource.type) + NewsResourceMetaData(userNewsResource.publishDate, userNewsResource.type) Spacer(modifier = Modifier.height(12.dp)) - NewsResourceShortDescription(newsResource.content) + NewsResourceShortDescription(userNewsResource.content) Spacer(modifier = Modifier.height(12.dp)) - NewsResourceTopics(newsResource.topics) + NewsResourceTopics(userNewsResource.topics) } } } @@ -227,7 +229,7 @@ fun NewsResourceShortDescription( @Composable fun NewsResourceTopics( - topics: List, + topics: List, modifier: Modifier = Modifier ) { // Store the ID of the Topic which has its "following" menu expanded, if any. @@ -238,17 +240,17 @@ fun NewsResourceTopics( modifier = modifier.horizontalScroll(rememberScrollState()), // causes narrow chips horizontalArrangement = Arrangement.spacedBy(4.dp), ) { - for (topic in topics) { + for (followableTopic in topics) { NiaTopicTag( - expanded = expandedTopicId == topic.id, + expanded = expandedTopicId == followableTopic.topic.id, followed = true, // ToDo: Check if topic is followed onDropdownMenuToggle = { show -> - expandedTopicId = if (show) topic.id else null + expandedTopicId = if (show) followableTopic.topic.id else null }, onFollowClick = { }, // ToDo onUnfollowClick = { }, // ToDo onBrowseClick = { }, // ToDo - text = { Text(text = topic.name.uppercase(Locale.getDefault())) } + text = { Text(text = followableTopic.topic.name.uppercase(Locale.getDefault())) } ) } } @@ -280,7 +282,7 @@ fun ExpandedNewsResourcePreview() { NiaTheme { Surface { NewsResourceCardExpanded( - newsResource = previewNewsResources[0], + userNewsResource = previewUserNewsResources[0], isBookmarked = true, onToggleBookmark = {}, onClick = {} diff --git a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardList.kt b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardList.kt index c76a8124d..c2bdb6580 100644 --- a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardList.kt +++ b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardList.kt @@ -23,6 +23,7 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.platform.LocalContext +import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResource /** @@ -37,7 +38,7 @@ import com.google.samples.apps.nowinandroid.core.model.data.NewsResource */ fun LazyListScope.newsResourceCardItems( items: List, - newsResourceMapper: (item: T) -> NewsResource, + newsResourceMapper: (item: T) -> UserNewsResource, //TODO remove this? isBookmarkedMapper: (item: T) -> Boolean, onToggleBookmark: (item: T) -> Unit, onItemClick: ((item: T) -> Unit)? = null, @@ -52,7 +53,7 @@ fun LazyListScope.newsResourceCardItems( val context = LocalContext.current NewsResourceCardExpanded( - newsResource = newsResource, + userNewsResource = newsResource, isBookmarked = isBookmarkedMapper(item), onToggleBookmark = { onToggleBookmark(item) }, onClick = { diff --git a/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreen.kt b/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreen.kt index 0bab4e449..9dbad373b 100644 --- a/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreen.kt +++ b/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreen.kt @@ -53,6 +53,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaLoadingWheel import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource +import com.google.samples.apps.nowinandroid.core.domain.model.previewUserNewsResources import com.google.samples.apps.nowinandroid.core.model.data.previewNewsResources import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState.Loading @@ -184,9 +185,7 @@ private fun BookmarksGridPreview() { NiaTheme { BookmarksGrid( feedState = Success( - previewNewsResources.map { - UserNewsResource(it, false) - } + previewUserNewsResources ), removeFromBookmarks = {} ) diff --git a/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModel.kt b/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModel.kt index 8ea565bfd..db94839be 100644 --- a/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModel.kt +++ b/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModel.kt @@ -19,7 +19,7 @@ package com.google.samples.apps.nowinandroid.feature.bookmarks import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.google.samples.apps.nowinandroid.core.data.repository.UserDataRepository -import com.google.samples.apps.nowinandroid.core.domain.GetSaveableNewsResourcesUseCase +import com.google.samples.apps.nowinandroid.core.domain.GetUserNewsResourcesUseCase import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState.Loading @@ -36,7 +36,7 @@ import kotlinx.coroutines.launch @HiltViewModel class BookmarksViewModel @Inject constructor( private val userDataRepository: UserDataRepository, - getSaveableNewsResources: GetSaveableNewsResourcesUseCase + getSaveableNewsResources: GetUserNewsResourcesUseCase ) : ViewModel() { val feedUiState: StateFlow = getSaveableNewsResources() diff --git a/feature/bookmarks/src/test/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModelTest.kt b/feature/bookmarks/src/test/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModelTest.kt index 56f30eff5..a8da1a4ff 100644 --- a/feature/bookmarks/src/test/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModelTest.kt +++ b/feature/bookmarks/src/test/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModelTest.kt @@ -16,7 +16,7 @@ package com.google.samples.apps.nowinandroid.feature.bookmarks -import com.google.samples.apps.nowinandroid.core.domain.GetSaveableNewsResourcesUseCase +import com.google.samples.apps.nowinandroid.core.domain.GetUserNewsResourcesUseCase import com.google.samples.apps.nowinandroid.core.model.data.previewNewsResources import com.google.samples.apps.nowinandroid.core.testing.repository.TestNewsRepository import com.google.samples.apps.nowinandroid.core.testing.repository.TestUserDataRepository @@ -43,7 +43,7 @@ class BookmarksViewModelTest { private val userDataRepository = TestUserDataRepository() private val newsRepository = TestNewsRepository() - private val getSaveableNewsResourcesUseCase = GetSaveableNewsResourcesUseCase( + private val getUserNewsResourcesUseCase = GetUserNewsResourcesUseCase( newsRepository = newsRepository, userDataRepository = userDataRepository ) @@ -53,7 +53,7 @@ class BookmarksViewModelTest { fun setup() { viewModel = BookmarksViewModel( userDataRepository = userDataRepository, - getSaveableNewsResources = getSaveableNewsResourcesUseCase + getSaveableNewsResources = getUserNewsResourcesUseCase ) } diff --git a/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt b/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt index e1a5b5e9e..fb4d83c7e 100644 --- a/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt +++ b/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt @@ -84,6 +84,7 @@ import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource +import com.google.samples.apps.nowinandroid.core.domain.model.previewUserNewsResources import com.google.samples.apps.nowinandroid.core.model.data.previewNewsResources import com.google.samples.apps.nowinandroid.core.model.data.previewTopics import com.google.samples.apps.nowinandroid.core.ui.DevicePreviews @@ -396,9 +397,7 @@ fun ForYouScreenPopulatedFeed() { isSyncing = false, onboardingUiState = OnboardingUiState.NotShown, feedState = NewsFeedUiState.Success( - feed = previewNewsResources.map { - UserNewsResource(it, false) - } + feed = previewUserNewsResources ), onTopicCheckedChanged = { _, _ -> }, saveFollowedTopics = {}, @@ -417,9 +416,7 @@ fun ForYouScreenOfflinePopulatedFeed() { isSyncing = false, onboardingUiState = OnboardingUiState.NotShown, feedState = NewsFeedUiState.Success( - feed = previewNewsResources.map { - UserNewsResource(it, false) - } + feed = previewUserNewsResources ), onTopicCheckedChanged = { _, _ -> }, saveFollowedTopics = {}, @@ -440,9 +437,7 @@ fun ForYouScreenTopicSelection() { topics = previewTopics.map { FollowableTopic(it, false) }, ), feedState = NewsFeedUiState.Success( - feed = previewNewsResources.map { - UserNewsResource(it, false) - } + feed = previewUserNewsResources ), onTopicCheckedChanged = { _, _ -> }, saveFollowedTopics = {}, @@ -478,9 +473,7 @@ fun ForYouScreenPopulatedAndLoading() { isSyncing = true, onboardingUiState = OnboardingUiState.Loading, feedState = NewsFeedUiState.Success( - feed = previewNewsResources.map { - UserNewsResource(it, false) - } + feed = previewUserNewsResources ), onTopicCheckedChanged = { _, _ -> }, saveFollowedTopics = {}, diff --git a/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModel.kt b/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModel.kt index 645566056..6c9218a75 100644 --- a/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModel.kt +++ b/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModel.kt @@ -21,7 +21,7 @@ import androidx.lifecycle.viewModelScope import com.google.samples.apps.nowinandroid.core.data.repository.UserDataRepository import com.google.samples.apps.nowinandroid.core.data.util.SyncStatusMonitor import com.google.samples.apps.nowinandroid.core.domain.GetFollowableTopicsUseCase -import com.google.samples.apps.nowinandroid.core.domain.GetSaveableNewsResourcesUseCase +import com.google.samples.apps.nowinandroid.core.domain.GetUserNewsResourcesUseCase import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState import dagger.hilt.android.lifecycle.HiltViewModel @@ -41,7 +41,7 @@ import kotlinx.coroutines.launch class ForYouViewModel @Inject constructor( syncStatusMonitor: SyncStatusMonitor, private val userDataRepository: UserDataRepository, - private val getSaveableNewsResources: GetSaveableNewsResourcesUseCase, + private val getSaveableNewsResources: GetUserNewsResourcesUseCase, getFollowableTopics: GetFollowableTopicsUseCase ) : ViewModel() { diff --git a/feature/foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt b/feature/foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt index 06b7ebe7a..35b8a2f5a 100644 --- a/feature/foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt +++ b/feature/foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt @@ -17,7 +17,7 @@ package com.google.samples.apps.nowinandroid.feature.foryou import com.google.samples.apps.nowinandroid.core.domain.GetFollowableTopicsUseCase -import com.google.samples.apps.nowinandroid.core.domain.GetSaveableNewsResourcesUseCase +import com.google.samples.apps.nowinandroid.core.domain.GetUserNewsResourcesUseCase import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResource @@ -54,7 +54,7 @@ class ForYouViewModelTest { private val userDataRepository = TestUserDataRepository() private val topicsRepository = TestTopicsRepository() private val newsRepository = TestNewsRepository() - private val getSaveableNewsResourcesUseCase = GetSaveableNewsResourcesUseCase( + private val getUserNewsResourcesUseCase = GetUserNewsResourcesUseCase( newsRepository = newsRepository, userDataRepository = userDataRepository ) @@ -69,7 +69,7 @@ class ForYouViewModelTest { viewModel = ForYouViewModel( syncStatusMonitor = syncStatusMonitor, userDataRepository = userDataRepository, - getSaveableNewsResources = getSaveableNewsResourcesUseCase, + getSaveableNewsResources = getUserNewsResourcesUseCase, getFollowableTopics = getFollowableTopicsUseCase ) } @@ -283,7 +283,19 @@ class ForYouViewModelTest { feed = sampleNewsResources.map { UserNewsResource( - newsResource = it, + id = it.id, + title = it.title, + content = it.content, + url = it.url, + headerImageUrl = it.headerImageUrl, + publishDate = it.publishDate, + type = it.type, + topics = it.topics.map{ topic -> + FollowableTopic( + topic = topic, + isFollowed = false + ) + }, isSaved = false ) } @@ -398,11 +410,35 @@ class ForYouViewModelTest { NewsFeedUiState.Success( feed = listOf( UserNewsResource( - newsResource = sampleNewsResources[1], + id = sampleNewsResources[1].id, + title = sampleNewsResources[1].title, + content = sampleNewsResources[1].content, + url = sampleNewsResources[1].url, + headerImageUrl = sampleNewsResources[1].headerImageUrl, + publishDate = sampleNewsResources[1].publishDate, + type = sampleNewsResources[1].type, + topics = sampleNewsResources[1].topics.map{ topic -> + FollowableTopic( + topic = topic, + isFollowed = false + ) + }, isSaved = false ), UserNewsResource( - newsResource = sampleNewsResources[2], + id = sampleNewsResources[2].id, + title = sampleNewsResources[2].title, + content = sampleNewsResources[2].content, + url = sampleNewsResources[2].url, + headerImageUrl = sampleNewsResources[2].headerImageUrl, + publishDate = sampleNewsResources[2].publishDate, + type = sampleNewsResources[2].type, + topics = sampleNewsResources[2].topics.map{ topic -> + FollowableTopic( + topic = topic, + isFollowed = false + ) + }, isSaved = false ) ) @@ -498,13 +534,37 @@ class ForYouViewModelTest { NewsFeedUiState.Success( feed = listOf( UserNewsResource( - newsResource = sampleNewsResources[1], + id = sampleNewsResources[1].id, + title = sampleNewsResources[1].title, + content = sampleNewsResources[1].content, + url = sampleNewsResources[1].url, + headerImageUrl = sampleNewsResources[1].headerImageUrl, + publishDate = sampleNewsResources[1].publishDate, + type = sampleNewsResources[1].type, + topics = sampleNewsResources[1].topics.map{ topic -> + FollowableTopic( + topic = topic, + isFollowed = false + ) + }, isSaved = true ), UserNewsResource( - newsResource = sampleNewsResources[2], + id = sampleNewsResources[2].id, + title = sampleNewsResources[2].title, + content = sampleNewsResources[2].content, + url = sampleNewsResources[2].url, + headerImageUrl = sampleNewsResources[2].headerImageUrl, + publishDate = sampleNewsResources[2].publishDate, + type = sampleNewsResources[2].type, + topics = sampleNewsResources[2].topics.map{ topic -> + FollowableTopic( + topic = topic, + isFollowed = false + ) + }, isSaved = false - ) + ), ) ), viewModel.feedState.value diff --git a/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreen.kt b/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreen.kt index b57c96954..3e79318eb 100644 --- a/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreen.kt +++ b/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreen.kt @@ -54,6 +54,7 @@ import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource +import com.google.samples.apps.nowinandroid.core.domain.model.previewUserNewsResources import com.google.samples.apps.nowinandroid.core.model.data.previewNewsResources import com.google.samples.apps.nowinandroid.core.model.data.previewTopics import com.google.samples.apps.nowinandroid.core.ui.DevicePreviews @@ -182,9 +183,9 @@ private fun LazyListScope.TopicCards( is NewsUiState.Success -> { newsResourceCardItems( items = news.news, - newsResourceMapper = { it.newsResource }, + newsResourceMapper = { it }, isBookmarkedMapper = { it.isSaved }, - onToggleBookmark = { onBookmarkChanged(it.newsResource.id, !it.isSaved) }, + onToggleBookmark = { onBookmarkChanged(it.id, !it.isSaved) }, itemModifier = Modifier.padding(24.dp) ) } @@ -257,12 +258,7 @@ fun TopicScreenPopulated() { TopicScreen( topicUiState = TopicUiState.Success(FollowableTopic(previewTopics[0], false)), newsUiState = NewsUiState.Success( - previewNewsResources.mapIndexed { index, newsResource -> - UserNewsResource( - newsResource = newsResource, - isSaved = index % 2 == 0, - ) - } + previewUserNewsResources ), onBackClick = {}, onFollowClick = {}, diff --git a/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModel.kt b/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModel.kt index e65bc1dee..1f08d233a 100644 --- a/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModel.kt +++ b/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModel.kt @@ -22,7 +22,7 @@ import androidx.lifecycle.viewModelScope import com.google.samples.apps.nowinandroid.core.data.repository.TopicsRepository import com.google.samples.apps.nowinandroid.core.data.repository.UserDataRepository import com.google.samples.apps.nowinandroid.core.decoder.StringDecoder -import com.google.samples.apps.nowinandroid.core.domain.GetSaveableNewsResourcesUseCase +import com.google.samples.apps.nowinandroid.core.domain.GetUserNewsResourcesUseCase import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.model.data.Topic @@ -46,7 +46,7 @@ class TopicViewModel @Inject constructor( private val userDataRepository: UserDataRepository, topicsRepository: TopicsRepository, // newsRepository: NewsRepository, - getSaveableNewsResources: GetSaveableNewsResourcesUseCase + getSaveableNewsResources: GetUserNewsResourcesUseCase ) : ViewModel() { private val topicArgs: TopicArgs = TopicArgs(savedStateHandle, stringDecoder) @@ -131,7 +131,7 @@ private fun topicUiState( private fun newsUiState( topicId: String, - getSaveableNewsResources: GetSaveableNewsResourcesUseCase, + getSaveableNewsResources: GetUserNewsResourcesUseCase, userDataRepository: UserDataRepository, ): Flow { // Observe news diff --git a/feature/topic/src/test/java/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModelTest.kt b/feature/topic/src/test/java/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModelTest.kt index 32768c4d7..6c61e59d5 100644 --- a/feature/topic/src/test/java/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModelTest.kt +++ b/feature/topic/src/test/java/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModelTest.kt @@ -17,7 +17,7 @@ package com.google.samples.apps.nowinandroid.feature.topic import androidx.lifecycle.SavedStateHandle -import com.google.samples.apps.nowinandroid.core.domain.GetSaveableNewsResourcesUseCase +import com.google.samples.apps.nowinandroid.core.domain.GetUserNewsResourcesUseCase import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType.Video @@ -53,7 +53,7 @@ class TopicViewModelTest { private val userDataRepository = TestUserDataRepository() private val topicsRepository = TestTopicsRepository() private val newsRepository = TestNewsRepository() - private val getSaveableNewsResourcesUseCase = GetSaveableNewsResourcesUseCase( + private val getUserNewsResourcesUseCase = GetUserNewsResourcesUseCase( newsRepository = newsRepository, userDataRepository = userDataRepository ) @@ -66,7 +66,7 @@ class TopicViewModelTest { stringDecoder = FakeStringDecoder(), userDataRepository = userDataRepository, topicsRepository = topicsRepository, - getSaveableNewsResources = getSaveableNewsResourcesUseCase + getSaveableNewsResources = getUserNewsResourcesUseCase ) } From 5638e253aea9436adad022538d055ce7e81e3e48 Mon Sep 17 00:00:00 2001 From: Don Turner Date: Mon, 19 Dec 2022 20:47:43 +0000 Subject: [PATCH 05/20] Fix unit and UI tests. Apply spotless. Change-Id: Iab75852a27a44309d349f84e65226911ab59fcd5 --- .../core/domain/model/FollowableTopic.kt | 2 +- .../core/domain/model/UserNewsResource.kt | 3 +- .../domain/GetUserNewsResourcesUseCaseTest.kt | 44 +++---- .../core/ui/NewsResourceCardTest.kt | 6 +- .../nowinandroid/core/ui/NewsResourceCard.kt | 1 - .../core/ui/NewsResourceCardList.kt | 2 +- .../feature/bookmarks/BookmarksScreenTest.kt | 19 ++-- .../feature/bookmarks/BookmarksScreen.kt | 2 - .../feature/foryou/ForYouScreenTest.kt | 13 +-- .../feature/foryou/ForYouScreen.kt | 2 - .../feature/foryou/ForYouViewModelTest.kt | 107 ++++-------------- .../feature/topic/TopicScreenTest.kt | 43 +++---- .../nowinandroid/feature/topic/TopicScreen.kt | 2 - 13 files changed, 86 insertions(+), 160 deletions(-) diff --git a/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/FollowableTopic.kt b/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/FollowableTopic.kt index c081abf1f..4071eb1aa 100644 --- a/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/FollowableTopic.kt +++ b/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/FollowableTopic.kt @@ -22,7 +22,7 @@ import com.google.samples.apps.nowinandroid.core.model.data.previewTopics /** * A [topic] with the additional information for whether or not it is followed. */ -data class FollowableTopic( //TODO consider changing to UserTopic and flattening +data class FollowableTopic( // TODO consider changing to UserTopic and flattening val topic: Topic, val isFollowed: Boolean ) diff --git a/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/UserNewsResource.kt b/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/UserNewsResource.kt index c70f549b2..b8cef84a7 100644 --- a/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/UserNewsResource.kt +++ b/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/UserNewsResource.kt @@ -21,12 +21,13 @@ import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType.Codelab import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType.Unknown import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType.Video -import com.google.samples.apps.nowinandroid.core.model.data.previewTopics import kotlinx.datetime.Instant import kotlinx.datetime.LocalDateTime import kotlinx.datetime.TimeZone import kotlinx.datetime.toInstant +/* ktlint-disable max-line-length */ + /** * A [NewsResource] with the additional user information. */ diff --git a/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt b/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt index ce730d6f2..d711d851e 100644 --- a/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt +++ b/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt @@ -70,7 +70,8 @@ class GetUserNewsResourcesUseCaseTest { isFollowed = false ) }, - true), + true + ), UserNewsResource( sampleNewsResources[1].id, sampleNewsResources[1].title, @@ -85,7 +86,8 @@ class GetUserNewsResourcesUseCaseTest { isFollowed = false ) }, - false), + false + ), UserNewsResource( sampleNewsResources[2].id, sampleNewsResources[2].title, @@ -97,10 +99,11 @@ class GetUserNewsResourcesUseCaseTest { sampleNewsResources[2].topics.map { topic -> FollowableTopic( topic = topic, - isFollowed = true + isFollowed = false ) }, - true), + true + ), ), saveableNewsResources.first() ) @@ -120,21 +123,24 @@ class GetUserNewsResourcesUseCaseTest { assertEquals( sampleNewsResources .filter { it.topics.contains(sampleTopic1) } - .map { UserNewsResource( - id = it.id, - title = it.title, - content = it.content, - url = it.url, - headerImageUrl = it.headerImageUrl, - publishDate = it.publishDate, - type = it.type, - topics = it.topics.map { topic -> - FollowableTopic( - topic = topic, - isFollowed = false - ) - }, - isSaved = false) }, + .map { + UserNewsResource( + id = it.id, + title = it.title, + content = it.content, + url = it.url, + headerImageUrl = it.headerImageUrl, + publishDate = it.publishDate, + type = it.type, + topics = it.topics.map { topic -> + FollowableTopic( + topic = topic, + isFollowed = false + ) + }, + isSaved = false + ) + }, saveableNewsResources.first() ) } diff --git a/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt b/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt index c334f1bab..70ce0662f 100644 --- a/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt +++ b/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt @@ -20,7 +20,7 @@ import androidx.activity.ComponentActivity import androidx.compose.ui.test.assertIsDisplayed import androidx.compose.ui.test.junit4.createAndroidComposeRule import androidx.compose.ui.test.onNodeWithText -import com.google.samples.apps.nowinandroid.core.model.data.previewNewsResources +import com.google.samples.apps.nowinandroid.core.domain.model.previewUserNewsResources import org.junit.Rule import org.junit.Test @@ -30,7 +30,7 @@ class NewsResourceCardTest { @Test fun testMetaDataDisplay_withCodelabResource() { - val newsWithKnownResourceType = previewNewsResources[0] + val newsWithKnownResourceType = previewUserNewsResources[0] var dateFormatted = "" composeTestRule.setContent { @@ -57,7 +57,7 @@ class NewsResourceCardTest { @Test fun testMetaDataDisplay_withUnknownResource() { - val newsWithUnknownResourceType = previewNewsResources[3] + val newsWithUnknownResourceType = previewUserNewsResources[3] var dateFormatted = "" composeTestRule.setContent { diff --git a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt index 6eb6e7859..d6d3ff55e 100644 --- a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt +++ b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt @@ -61,7 +61,6 @@ import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.domain.model.previewUserNewsResources import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType -import com.google.samples.apps.nowinandroid.core.model.data.previewNewsResources import java.time.ZoneId import java.time.format.DateTimeFormatter import java.util.Locale diff --git a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardList.kt b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardList.kt index c2bdb6580..c7441c182 100644 --- a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardList.kt +++ b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardList.kt @@ -38,7 +38,7 @@ import com.google.samples.apps.nowinandroid.core.model.data.NewsResource */ fun LazyListScope.newsResourceCardItems( items: List, - newsResourceMapper: (item: T) -> UserNewsResource, //TODO remove this? + newsResourceMapper: (item: T) -> UserNewsResource, // TODO remove this? isBookmarkedMapper: (item: T) -> Boolean, onToggleBookmark: (item: T) -> Unit, onItemClick: ((item: T) -> Unit)? = null, diff --git a/feature/bookmarks/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreenTest.kt b/feature/bookmarks/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreenTest.kt index 3421f885a..bd9ca2056 100644 --- a/feature/bookmarks/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreenTest.kt +++ b/feature/bookmarks/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreenTest.kt @@ -31,8 +31,7 @@ import androidx.compose.ui.test.onNodeWithContentDescription import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick import androidx.compose.ui.test.performScrollToNode -import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource -import com.google.samples.apps.nowinandroid.core.model.data.previewNewsResources +import com.google.samples.apps.nowinandroid.core.domain.model.previewUserNewsResources import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState import kotlin.test.assertEquals import kotlin.test.assertTrue @@ -70,8 +69,7 @@ class BookmarksScreenTest { composeTestRule.setContent { BookmarksScreen( feedState = NewsFeedUiState.Success( - previewNewsResources.take(2) - .map { UserNewsResource(it, true) } + previewUserNewsResources.take(2) ), removeFromBookmarks = { } ) @@ -79,7 +77,7 @@ class BookmarksScreenTest { composeTestRule .onNodeWithText( - previewNewsResources[0].title, + previewUserNewsResources[0].title, substring = true ) .assertExists() @@ -88,14 +86,14 @@ class BookmarksScreenTest { composeTestRule.onNode(hasScrollToNodeAction()) .performScrollToNode( hasText( - previewNewsResources[1].title, + previewUserNewsResources[1].title, substring = true ) ) composeTestRule .onNodeWithText( - previewNewsResources[1].title, + previewUserNewsResources[1].title, substring = true ) .assertExists() @@ -109,11 +107,10 @@ class BookmarksScreenTest { composeTestRule.setContent { BookmarksScreen( feedState = NewsFeedUiState.Success( - previewNewsResources.take(2) - .map { UserNewsResource(it, true) } + previewUserNewsResources.take(2) ), removeFromBookmarks = { newsResourceId -> - assertEquals(previewNewsResources[0].id, newsResourceId) + assertEquals(previewUserNewsResources[0].id, newsResourceId) removeFromBookmarksCalled = true } ) @@ -127,7 +124,7 @@ class BookmarksScreenTest { ).filter( hasAnyAncestor( hasText( - previewNewsResources[0].title, + previewUserNewsResources[0].title, substring = true ) ) diff --git a/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreen.kt b/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreen.kt index 9dbad373b..789fbec31 100644 --- a/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreen.kt +++ b/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreen.kt @@ -52,9 +52,7 @@ import androidx.lifecycle.compose.ExperimentalLifecycleComposeApi import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaLoadingWheel import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme -import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.domain.model.previewUserNewsResources -import com.google.samples.apps.nowinandroid.core.model.data.previewNewsResources import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState.Loading import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState.Success diff --git a/feature/foryou/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt b/feature/foryou/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt index ee6e2795b..70f60811b 100644 --- a/feature/foryou/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt +++ b/feature/foryou/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt @@ -29,9 +29,8 @@ import androidx.compose.ui.test.onNodeWithContentDescription import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performScrollToNode import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic -import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource +import com.google.samples.apps.nowinandroid.core.domain.model.previewUserNewsResources import com.google.samples.apps.nowinandroid.core.model.data.Topic -import com.google.samples.apps.nowinandroid.core.model.data.previewNewsResources import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState import org.junit.Rule import org.junit.Test @@ -225,9 +224,7 @@ class ForYouScreenTest { isSyncing = false, onboardingUiState = OnboardingUiState.NotShown, feedState = NewsFeedUiState.Success( - feed = previewNewsResources.map { - UserNewsResource(it, false) - } + feed = previewUserNewsResources ), onTopicCheckedChanged = { _, _ -> }, saveFollowedTopics = {}, @@ -237,7 +234,7 @@ class ForYouScreenTest { composeTestRule .onNodeWithText( - previewNewsResources[0].title, + previewUserNewsResources[0].title, substring = true ) .assertExists() @@ -246,14 +243,14 @@ class ForYouScreenTest { composeTestRule.onNode(hasScrollToNodeAction()) .performScrollToNode( hasText( - previewNewsResources[1].title, + previewUserNewsResources[1].title, substring = true ) ) composeTestRule .onNodeWithText( - previewNewsResources[1].title, + previewUserNewsResources[1].title, substring = true ) .assertExists() diff --git a/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt b/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt index fb4d83c7e..0e62a9b0b 100644 --- a/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt +++ b/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt @@ -83,9 +83,7 @@ import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaOverl import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic -import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.domain.model.previewUserNewsResources -import com.google.samples.apps.nowinandroid.core.model.data.previewNewsResources import com.google.samples.apps.nowinandroid.core.model.data.previewTopics import com.google.samples.apps.nowinandroid.core.ui.DevicePreviews import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState diff --git a/feature/foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt b/feature/foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt index 35b8a2f5a..5ab8d92db 100644 --- a/feature/foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt +++ b/feature/foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt @@ -263,7 +263,9 @@ class ForYouViewModelTest { val collectJob2 = launch(UnconfinedTestDispatcher()) { viewModel.feedState.collect() } topicsRepository.sendTopics(sampleTopics) - userDataRepository.setFollowedTopicIds(setOf("0", "1")) + + val followedTopicIds = setOf("0", "1") + userDataRepository.setFollowedTopicIds(followedTopicIds) viewModel.dismissOnboarding() assertEquals( @@ -290,10 +292,10 @@ class ForYouViewModelTest { headerImageUrl = it.headerImageUrl, publishDate = it.publishDate, type = it.type, - topics = it.topics.map{ topic -> + topics = it.topics.map { topic -> FollowableTopic( topic = topic, - isFollowed = false + isFollowed = followedTopicIds.contains(topic.id) ) }, isSaved = false @@ -319,41 +321,9 @@ class ForYouViewModelTest { assertEquals( OnboardingUiState.Shown( - topics = listOf( - FollowableTopic( - topic = Topic( - id = "0", - name = "Headlines", - shortDescription = "", - longDescription = "long description", - url = "URL", - imageUrl = "image URL", - ), - isFollowed = false - ), - FollowableTopic( - topic = Topic( - id = "1", - name = "UI", - shortDescription = "", - longDescription = "long description", - url = "URL", - imageUrl = "image URL", - ), - isFollowed = false - ), - FollowableTopic( - topic = Topic( - id = "2", - name = "Tools", - shortDescription = "", - longDescription = "long description", - url = "URL", - imageUrl = "image URL", - ), - isFollowed = false - ) - ), + topics = sampleTopics.map { + FollowableTopic(it, false) + } ), viewModel.onboardingUiState.value ) @@ -364,45 +334,14 @@ class ForYouViewModelTest { viewModel.feedState.value ) - viewModel.updateTopicSelection("1", isChecked = true) + val followedTopicId = sampleTopics[1].id + viewModel.updateTopicSelection(followedTopicId, isChecked = true) assertEquals( OnboardingUiState.Shown( - topics = listOf( - FollowableTopic( - topic = Topic( - id = "0", - name = "Headlines", - shortDescription = "", - longDescription = "long description", - url = "URL", - imageUrl = "image URL", - ), - isFollowed = false - ), - FollowableTopic( - topic = Topic( - id = "1", - name = "UI", - shortDescription = "", - longDescription = "long description", - url = "URL", - imageUrl = "image URL", - ), - isFollowed = true - ), - FollowableTopic( - topic = Topic( - id = "2", - name = "Tools", - shortDescription = "", - longDescription = "long description", - url = "URL", - imageUrl = "image URL", - ), - isFollowed = false - ) - ), + topics = sampleTopics.map { + FollowableTopic(it, it.id == followedTopicId) + } ), viewModel.onboardingUiState.value ) @@ -417,10 +356,10 @@ class ForYouViewModelTest { headerImageUrl = sampleNewsResources[1].headerImageUrl, publishDate = sampleNewsResources[1].publishDate, type = sampleNewsResources[1].type, - topics = sampleNewsResources[1].topics.map{ topic -> + topics = sampleNewsResources[1].topics.map { topic -> FollowableTopic( topic = topic, - isFollowed = false + isFollowed = topic.id == followedTopicId ) }, isSaved = false @@ -433,10 +372,10 @@ class ForYouViewModelTest { headerImageUrl = sampleNewsResources[2].headerImageUrl, publishDate = sampleNewsResources[2].publishDate, type = sampleNewsResources[2].type, - topics = sampleNewsResources[2].topics.map{ topic -> + topics = sampleNewsResources[2].topics.map { topic -> FollowableTopic( topic = topic, - isFollowed = false + isFollowed = topic.id == followedTopicId ) }, isSaved = false @@ -520,8 +459,10 @@ class ForYouViewModelTest { launch(UnconfinedTestDispatcher()) { viewModel.onboardingUiState.collect() } val collectJob2 = launch(UnconfinedTestDispatcher()) { viewModel.feedState.collect() } + val followedTopicIds = setOf("1") + topicsRepository.sendTopics(sampleTopics) - userDataRepository.setFollowedTopicIds(setOf("1")) + userDataRepository.setFollowedTopicIds(followedTopicIds) userDataRepository.setShouldHideOnboarding(true) newsRepository.sendNewsResources(sampleNewsResources) viewModel.updateNewsResourceSaved("2", true) @@ -541,10 +482,10 @@ class ForYouViewModelTest { headerImageUrl = sampleNewsResources[1].headerImageUrl, publishDate = sampleNewsResources[1].publishDate, type = sampleNewsResources[1].type, - topics = sampleNewsResources[1].topics.map{ topic -> + topics = sampleNewsResources[1].topics.map { topic -> FollowableTopic( topic = topic, - isFollowed = false + isFollowed = followedTopicIds.contains(topic.id) ) }, isSaved = true @@ -557,10 +498,10 @@ class ForYouViewModelTest { headerImageUrl = sampleNewsResources[2].headerImageUrl, publishDate = sampleNewsResources[2].publishDate, type = sampleNewsResources[2].type, - topics = sampleNewsResources[2].topics.map{ topic -> + topics = sampleNewsResources[2].topics.map { topic -> FollowableTopic( topic = topic, - isFollowed = false + isFollowed = followedTopicIds.contains(topic.id) ) }, isSaved = false diff --git a/feature/topic/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreenTest.kt b/feature/topic/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreenTest.kt index 0f6d2dcc0..c635b7a53 100644 --- a/feature/topic/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreenTest.kt +++ b/feature/topic/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreenTest.kt @@ -26,7 +26,6 @@ import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performScrollToNode import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource -import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType.Video import com.google.samples.apps.nowinandroid.core.model.data.Topic import kotlinx.datetime.Instant @@ -99,14 +98,7 @@ class TopicScreenTest { composeTestRule.setContent { TopicScreen( topicUiState = TopicUiState.Loading, - newsUiState = NewsUiState.Success( - sampleNewsResources.mapIndexed { index, newsResource -> - UserNewsResource( - newsResource = newsResource, - isSaved = index % 2 == 0, - ) - } - ), + newsUiState = NewsUiState.Success(sampleUserNewsResources), onBackClick = { }, onFollowClick = { }, onBookmarkChanged = { _, _ -> }, @@ -126,12 +118,7 @@ class TopicScreenTest { TopicScreen( topicUiState = TopicUiState.Success(testTopic), newsUiState = NewsUiState.Success( - sampleNewsResources.mapIndexed { index, newsResource -> - UserNewsResource( - newsResource = newsResource, - isSaved = index % 2 == 0, - ) - } + sampleUserNewsResources ), onBackClick = { }, onFollowClick = { }, @@ -143,7 +130,7 @@ class TopicScreenTest { composeTestRule .onAllNodes(hasScrollToNodeAction()) .onFirst() - .performScrollToNode(hasText(sampleNewsResources.first().title)) + .performScrollToNode(hasText(sampleUserNewsResources.first().title)) } } @@ -188,8 +175,8 @@ private val testTopics = listOf( ) ) -private val sampleNewsResources = listOf( - NewsResource( +private val sampleUserNewsResources = listOf( + UserNewsResource( id = "1", title = "Thanks for helping us reach 1M YouTube Subscribers", content = "Thank you everyone for following the Now in Android series and everything the " + @@ -201,14 +188,18 @@ private val sampleNewsResources = listOf( publishDate = Instant.parse("2021-11-09T00:00:00.000Z"), type = Video, topics = listOf( - Topic( - id = "0", - name = "Headlines", - shortDescription = "", - longDescription = TOPIC_DESC, - url = "", - imageUrl = "" + FollowableTopic( + topic = Topic( + id = "0", + name = "Headlines", + shortDescription = "", + longDescription = TOPIC_DESC, + url = "", + imageUrl = "" + ), + isFollowed = false ) - ) + ), + isSaved = true ) ) diff --git a/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreen.kt b/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreen.kt index 3e79318eb..263c04d78 100644 --- a/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreen.kt +++ b/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreen.kt @@ -53,9 +53,7 @@ import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaLoadi import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic -import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.domain.model.previewUserNewsResources -import com.google.samples.apps.nowinandroid.core.model.data.previewNewsResources import com.google.samples.apps.nowinandroid.core.model.data.previewTopics import com.google.samples.apps.nowinandroid.core.ui.DevicePreviews import com.google.samples.apps.nowinandroid.core.ui.TrackScrollJank From a8f55d9d38231b2911c56597f1ffe4308dd5e900 Mon Sep 17 00:00:00 2001 From: magicalmeghan Date: Mon, 19 Dec 2022 17:21:11 -0800 Subject: [PATCH 06/20] Renamed SaveableNewsResource to UserNewsResource --- .../samples/apps/nowinandroid/core/ui/NewsResourceCard.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt index d6d3ff55e..9f9129b49 100644 --- a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt +++ b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt @@ -242,7 +242,7 @@ fun NewsResourceTopics( for (followableTopic in topics) { NiaTopicTag( expanded = expandedTopicId == followableTopic.topic.id, - followed = true, // ToDo: Check if topic is followed + followed = followableTopic.isFollowed, onDropdownMenuToggle = { show -> expandedTopicId = if (show) followableTopic.topic.id else null }, From 9a900f9900f40283a08e47b982d45ffa5d138d4f Mon Sep 17 00:00:00 2001 From: magicalmeghan Date: Tue, 20 Dec 2022 17:03:25 -0800 Subject: [PATCH 07/20] Added first draft of tests --- .../domain/GetUserNewsResourcesUseCaseTest.kt | 14 ++++++++++++++ .../nowinandroid/core/ui/NewsResourceCardTest.kt | 16 ++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt b/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt index d711d851e..5ba0d66cb 100644 --- a/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt +++ b/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt @@ -144,6 +144,20 @@ class GetUserNewsResourcesUseCaseTest { saveableNewsResources.first() ) } + + //verify that news resources contain the correct FollowedTopics + @Test + fun newsResourcesContainCorrectFollowedTopics() = runTest { + assertEquals( + sampleNewsResources[0].topics, listOf(sampleTopic1) + ) + assertEquals( + sampleNewsResources[1].topics, listOf(sampleTopic1, sampleTopic2) + ) + assertEquals( + sampleNewsResources[2].topics, listOf(sampleTopic2) + ) + } } private val sampleTopic1 = Topic( diff --git a/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt b/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt index 70ce0662f..748a8d1a5 100644 --- a/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt +++ b/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt @@ -75,4 +75,20 @@ class NewsResourceCardTest { .onNodeWithText(dateFormatted) .assertIsDisplayed() } + + // Test that chip color is different if topic is followed + @Test + fun testChipColor() { + val newsWithUnknownResourceType = previewUserNewsResources[1] + + composeTestRule.setContent { + NewsResourceTopics(topics = newsWithUnknownResourceType.topics) + } + + composeTestRule + .onNodeWithText("UI") + //figure out how to get the color of the chip and compare it to + // MaterialTheme.colorScheme.primaryContainer + + } } From 80898660793dbbe8cf36263af8844f729d209320 Mon Sep 17 00:00:00 2001 From: magicalmeghan Date: Wed, 21 Dec 2022 16:21:50 -0800 Subject: [PATCH 08/20] Added second draft of tests --- .../domain/GetUserNewsResourcesUseCaseTest.kt | 73 ++++++++++++++++--- .../core/ui/NewsResourceCardTest.kt | 16 ++-- .../nowinandroid/core/ui/NewsResourceCard.kt | 19 +++-- 3 files changed, 85 insertions(+), 23 deletions(-) diff --git a/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt b/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt index 5ba0d66cb..5fc822124 100644 --- a/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt +++ b/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt @@ -145,17 +145,72 @@ class GetUserNewsResourcesUseCaseTest { ) } - //verify that news resources contain the correct FollowedTopics + //whenTopicFollowed_UserNewsResources @Test - fun newsResourcesContainCorrectFollowedTopics() = runTest { - assertEquals( - sampleNewsResources[0].topics, listOf(sampleTopic1) - ) - assertEquals( - sampleNewsResources[1].topics, listOf(sampleTopic1, sampleTopic2) - ) + fun checkNewsResourcesContainCorrectFollowedTopics() = runTest { + + // Obtain the saveable news resources stream. + val saveableNewsResources = useCase() + + // Send some news resources. + newsRepository.sendNewsResources(sampleNewsResources) + + // Set a followed topic for the user. + userDataRepository.setFollowedTopicIds(setOf(sampleTopic1.id)) + + // Check that the followed topic is marked followed in the UserNewsResources assertEquals( - sampleNewsResources[2].topics, listOf(sampleTopic2) + listOf( + UserNewsResource( + sampleNewsResources[0].id, + sampleNewsResources[0].title, + sampleNewsResources[0].content, + sampleNewsResources[0].url, + sampleNewsResources[0].headerImageUrl, + sampleNewsResources[0].publishDate, + sampleNewsResources[0].type, + sampleNewsResources[0].topics.map { topic -> + FollowableTopic( + topic = topic, + isFollowed = topic.id == sampleTopic1.id + ) + }, + false + ), + UserNewsResource( + sampleNewsResources[1].id, + sampleNewsResources[1].title, + sampleNewsResources[1].content, + sampleNewsResources[1].url, + sampleNewsResources[1].headerImageUrl, + sampleNewsResources[1].publishDate, + sampleNewsResources[1].type, + sampleNewsResources[1].topics.map { topic -> + FollowableTopic( + topic = topic, + isFollowed = topic.id == sampleTopic1.id + ) + }, + false + ), + UserNewsResource( + sampleNewsResources[2].id, + sampleNewsResources[2].title, + sampleNewsResources[2].content, + sampleNewsResources[2].url, + sampleNewsResources[2].headerImageUrl, + sampleNewsResources[2].publishDate, + sampleNewsResources[2].type, + sampleNewsResources[2].topics.map { topic -> + FollowableTopic( + topic = topic, + isFollowed = topic.id == sampleTopic1.id + ) + }, + false + ), + ), + saveableNewsResources.first() ) } } diff --git a/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt b/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt index 748a8d1a5..3a8ce415d 100644 --- a/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt +++ b/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt @@ -17,6 +17,7 @@ package com.google.samples.apps.nowinandroid.core.ui import androidx.activity.ComponentActivity +import androidx.compose.ui.test.assertContentDescriptionEquals import androidx.compose.ui.test.assertIsDisplayed import androidx.compose.ui.test.junit4.createAndroidComposeRule import androidx.compose.ui.test.onNodeWithText @@ -76,19 +77,16 @@ class NewsResourceCardTest { .assertIsDisplayed() } - // Test that chip color is different if topic is followed @Test - fun testChipColor() { - val newsWithUnknownResourceType = previewUserNewsResources[1] + fun testTopicsChipColorBackground_matchesFollowedState() { + val followableTopics = previewUserNewsResources[1].topics composeTestRule.setContent { - NewsResourceTopics(topics = newsWithUnknownResourceType.topics) + NewsResourceTopics(topics = followableTopics) } composeTestRule - .onNodeWithText("UI") - //figure out how to get the color of the chip and compare it to - // MaterialTheme.colorScheme.primaryContainer - + .onNodeWithText(followableTopics[1].topic.name) + .assertContentDescriptionEquals("UI is followed") } -} +} \ No newline at end of file diff --git a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt index 9f9129b49..c13d3f986 100644 --- a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt +++ b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt @@ -46,12 +46,12 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalInspectionMode import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource +import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.onClick import androidx.compose.ui.semantics.semantics import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import coil.compose.AsyncImage -import com.google.samples.apps.nowinandroid.core.designsystem.R as DesignsystemR import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaIconToggleButton import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaTopicTag import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons @@ -61,11 +61,12 @@ import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.domain.model.previewUserNewsResources import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType -import java.time.ZoneId -import java.time.format.DateTimeFormatter -import java.util.Locale import kotlinx.datetime.Instant import kotlinx.datetime.toJavaInstant +import java.time.ZoneId +import java.time.format.DateTimeFormatter +import java.util.* +import com.google.samples.apps.nowinandroid.core.designsystem.R as DesignsystemR /** * [NewsResource] card used on the following screens: For You, Saved @@ -249,7 +250,15 @@ fun NewsResourceTopics( onFollowClick = { }, // ToDo onUnfollowClick = { }, // ToDo onBrowseClick = { }, // ToDo - text = { Text(text = followableTopic.topic.name.uppercase(Locale.getDefault())) } + text = { + Text(text = followableTopic.topic.name.uppercase(Locale.getDefault()), + modifier = Modifier.semantics { + contentDescription = followableTopic.topic.name + + if (followableTopic.isFollowed) " is followed" + else " is not followed" + //make sure this is the right place to add this - remove hardcoded strings + }) + } ) } } From d9e18607be1d3f5b16333fc8ab0dc7e168d8d8f0 Mon Sep 17 00:00:00 2001 From: magicalmeghan Date: Wed, 21 Dec 2022 23:30:45 -0800 Subject: [PATCH 09/20] Added second draft of tests --- .../nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt b/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt index 5fc822124..66a001184 100644 --- a/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt +++ b/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt @@ -145,7 +145,6 @@ class GetUserNewsResourcesUseCaseTest { ) } - //whenTopicFollowed_UserNewsResources @Test fun checkNewsResourcesContainCorrectFollowedTopics() = runTest { From ffb5aeba8633f56f14355fcd6e5914cd1337c38a Mon Sep 17 00:00:00 2001 From: magicalmeghan Date: Thu, 22 Dec 2022 13:58:51 -0800 Subject: [PATCH 10/20] Added third draft of tests --- .../domain/GetUserNewsResourcesUseCaseTest.kt | 77 ++----------------- .../core/ui/NewsResourceCardTest.kt | 1 + 2 files changed, 7 insertions(+), 71 deletions(-) diff --git a/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt b/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt index 66a001184..d8fd950de 100644 --- a/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt +++ b/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt @@ -53,6 +53,9 @@ class GetUserNewsResourcesUseCaseTest { setOf(sampleNewsResources[0].id, sampleNewsResources[2].id) ) + // Set a followed topic for the user. + userDataRepository.setFollowedTopicIds(setOf(sampleTopic1.id)) + // Check that the correct news resources are returned with their bookmarked state. assertEquals( listOf( @@ -67,7 +70,7 @@ class GetUserNewsResourcesUseCaseTest { sampleNewsResources[0].topics.map { topic -> FollowableTopic( topic = topic, - isFollowed = false + isFollowed = topic.id == sampleTopic1.id ) }, true @@ -83,7 +86,7 @@ class GetUserNewsResourcesUseCaseTest { sampleNewsResources[1].topics.map { topic -> FollowableTopic( topic = topic, - isFollowed = false + isFollowed = topic.id == sampleTopic1.id ) }, false @@ -99,7 +102,7 @@ class GetUserNewsResourcesUseCaseTest { sampleNewsResources[2].topics.map { topic -> FollowableTopic( topic = topic, - isFollowed = false + isFollowed = topic.id == sampleTopic1.id ) }, true @@ -144,74 +147,6 @@ class GetUserNewsResourcesUseCaseTest { saveableNewsResources.first() ) } - - @Test - fun checkNewsResourcesContainCorrectFollowedTopics() = runTest { - - // Obtain the saveable news resources stream. - val saveableNewsResources = useCase() - - // Send some news resources. - newsRepository.sendNewsResources(sampleNewsResources) - - // Set a followed topic for the user. - userDataRepository.setFollowedTopicIds(setOf(sampleTopic1.id)) - - // Check that the followed topic is marked followed in the UserNewsResources - assertEquals( - listOf( - UserNewsResource( - sampleNewsResources[0].id, - sampleNewsResources[0].title, - sampleNewsResources[0].content, - sampleNewsResources[0].url, - sampleNewsResources[0].headerImageUrl, - sampleNewsResources[0].publishDate, - sampleNewsResources[0].type, - sampleNewsResources[0].topics.map { topic -> - FollowableTopic( - topic = topic, - isFollowed = topic.id == sampleTopic1.id - ) - }, - false - ), - UserNewsResource( - sampleNewsResources[1].id, - sampleNewsResources[1].title, - sampleNewsResources[1].content, - sampleNewsResources[1].url, - sampleNewsResources[1].headerImageUrl, - sampleNewsResources[1].publishDate, - sampleNewsResources[1].type, - sampleNewsResources[1].topics.map { topic -> - FollowableTopic( - topic = topic, - isFollowed = topic.id == sampleTopic1.id - ) - }, - false - ), - UserNewsResource( - sampleNewsResources[2].id, - sampleNewsResources[2].title, - sampleNewsResources[2].content, - sampleNewsResources[2].url, - sampleNewsResources[2].headerImageUrl, - sampleNewsResources[2].publishDate, - sampleNewsResources[2].type, - sampleNewsResources[2].topics.map { topic -> - FollowableTopic( - topic = topic, - isFollowed = topic.id == sampleTopic1.id - ) - }, - false - ), - ), - saveableNewsResources.first() - ) - } } private val sampleTopic1 = Topic( diff --git a/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt b/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt index 3a8ce415d..a46626cab 100644 --- a/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt +++ b/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt @@ -89,4 +89,5 @@ class NewsResourceCardTest { .onNodeWithText(followableTopics[1].topic.name) .assertContentDescriptionEquals("UI is followed") } + //TODO add a test for not followed - figure out whether to put it here or to make a new test } \ No newline at end of file From 99227b06b5df702f214ed78cf70a7b5374dc7d62 Mon Sep 17 00:00:00 2001 From: Don Turner Date: Fri, 23 Dec 2022 15:51:59 +0000 Subject: [PATCH 11/20] Spotless --- .../nowinandroid/core/ui/NewsResourceCardTest.kt | 4 ++-- .../nowinandroid/core/ui/NewsResourceCard.kt | 16 +++++++++------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt b/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt index a46626cab..d1f5d7e87 100644 --- a/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt +++ b/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt @@ -89,5 +89,5 @@ class NewsResourceCardTest { .onNodeWithText(followableTopics[1].topic.name) .assertContentDescriptionEquals("UI is followed") } - //TODO add a test for not followed - figure out whether to put it here or to make a new test -} \ No newline at end of file + // TODO add a test for not followed - figure out whether to put it here or to make a new test +} diff --git a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt index 900df4f3f..d2024f694 100644 --- a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt +++ b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt @@ -52,6 +52,7 @@ import androidx.compose.ui.semantics.semantics import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import coil.compose.AsyncImage +import com.google.samples.apps.nowinandroid.core.designsystem.R as DesignsystemR import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaIconToggleButton import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaTopicTag import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons @@ -61,12 +62,11 @@ import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.domain.model.previewUserNewsResources import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType -import kotlinx.datetime.Instant -import kotlinx.datetime.toJavaInstant import java.time.ZoneId import java.time.format.DateTimeFormatter -import java.util.* -import com.google.samples.apps.nowinandroid.core.designsystem.R as DesignsystemR +import java.util.Locale +import kotlinx.datetime.Instant +import kotlinx.datetime.toJavaInstant /** * [NewsResource] card used on the following screens: For You, Saved @@ -252,13 +252,15 @@ fun NewsResourceTopics( onUnfollowClick = { }, // ToDo onBrowseClick = { }, // ToDo text = { - Text(text = followableTopic.topic.name.uppercase(Locale.getDefault()), + Text( + text = followableTopic.topic.name.uppercase(Locale.getDefault()), modifier = Modifier.semantics { contentDescription = followableTopic.topic.name + if (followableTopic.isFollowed) " is followed" else " is not followed" - //make sure this is the right place to add this - remove hardcoded strings - }) + // make sure this is the right place to add this - remove hardcoded strings + } + ) } ) } From 355b0540aa034ae47785268af11666a56a6a1b5c Mon Sep 17 00:00:00 2001 From: Don Turner Date: Wed, 4 Jan 2023 19:19:54 +0000 Subject: [PATCH 12/20] Move construction of UserNewsResource into separate function Change-Id: I7c1f6427cd7d95c2016349fec301b88455b33cf2 --- .../domain/GetUserNewsResourcesUseCase.kt | 26 +---- .../core/domain/model/UserNewsResource.kt | 34 +++++- .../domain/GetUserNewsResourcesUseCaseTest.kt | 110 +++++------------- .../core/domain/UserNewsResourceTest.kt | 106 +++++++++++++++++ .../repository/TestUserDataRepository.kt | 7 ++ .../core/ui/NewsResourceCardTest.kt | 2 +- .../nowinandroid/core/ui/NewsResourceCard.kt | 2 +- .../feature/foryou/ForYouViewModelTest.kt | 10 +- .../feature/topic/TopicScreenTest.kt | 2 +- 9 files changed, 186 insertions(+), 113 deletions(-) create mode 100644 core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/UserNewsResourceTest.kt diff --git a/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCase.kt b/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCase.kt index 19d65581f..39bd38e1e 100644 --- a/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCase.kt +++ b/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCase.kt @@ -18,7 +18,6 @@ package com.google.samples.apps.nowinandroid.core.domain import com.google.samples.apps.nowinandroid.core.data.repository.NewsRepository import com.google.samples.apps.nowinandroid.core.data.repository.UserDataRepository -import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.model.data.UserData @@ -48,30 +47,15 @@ class GetUserNewsResourcesUseCase @Inject constructor( newsRepository.getNewsResources() } else { newsRepository.getNewsResources(filterTopicIds = filterTopicIds) - }.mapToSaveableNewsResources(userDataRepository.userData) + }.mapToUserNewsResources(userDataRepository.userData) } -private fun Flow>.mapToSaveableNewsResources( - userData: Flow +private fun Flow>.mapToUserNewsResources( + userDataStream: Flow ): Flow> = filterNot { it.isEmpty() } - .combine(userData) { newsResources, userData -> + .combine(userDataStream) { newsResources, userData -> newsResources.map { newsResource -> - UserNewsResource( - id = newsResource.id, - title = newsResource.title, - content = newsResource.content, - url = newsResource.url, - headerImageUrl = newsResource.headerImageUrl, - publishDate = newsResource.publishDate, - type = newsResource.type, - topics = newsResource.topics.map { topic -> - FollowableTopic( - topic = topic, - isFollowed = userData.followedTopics.contains(topic.id) - ) - }, - isSaved = userData.bookmarkedNewsResources.contains(newsResource.id) - ) + UserNewsResource.from(newsResource, userData) } } diff --git a/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/UserNewsResource.kt b/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/UserNewsResource.kt index b8cef84a7..280f6b78a 100644 --- a/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/UserNewsResource.kt +++ b/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/UserNewsResource.kt @@ -21,6 +21,7 @@ import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType.Codelab import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType.Unknown import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType.Video +import com.google.samples.apps.nowinandroid.core.model.data.UserData import kotlinx.datetime.Instant import kotlinx.datetime.LocalDateTime import kotlinx.datetime.TimeZone @@ -39,9 +40,30 @@ data class UserNewsResource( val headerImageUrl: String?, val publishDate: Instant, val type: NewsResourceType, - val topics: List, + val followableTopics: List, val isSaved: Boolean -) +) { + companion object { + fun from(newsResource: NewsResource, userData: UserData): UserNewsResource { + return UserNewsResource( + id = newsResource.id, + title = newsResource.title, + content = newsResource.content, + url = newsResource.url, + headerImageUrl = newsResource.headerImageUrl, + publishDate = newsResource.publishDate, + type = newsResource.type, + followableTopics = newsResource.topics.map { topic -> + FollowableTopic( + topic = topic, + isFollowed = userData.followedTopics.contains(topic.id) + ) + }, + isSaved = userData.bookmarkedNewsResources.contains(newsResource.id) + ) + } + } +} val previewUserNewsResources = listOf( UserNewsResource( @@ -60,7 +82,7 @@ val previewUserNewsResources = listOf( nanosecond = 0 ).toInstant(TimeZone.UTC), type = Codelab, - topics = listOf(previewFollowableTopics[1]), + followableTopics = listOf(previewFollowableTopics[1]), isSaved = true ), UserNewsResource( @@ -74,7 +96,7 @@ val previewUserNewsResources = listOf( headerImageUrl = "https://i.ytimg.com/vi/-fJ6poHQrjM/maxresdefault.jpg", publishDate = Instant.parse("2021-11-09T00:00:00.000Z"), type = Video, - topics = listOf(previewFollowableTopics[0], previewFollowableTopics[1]), + followableTopics = listOf(previewFollowableTopics[0], previewFollowableTopics[1]), isSaved = false ), UserNewsResource( @@ -88,7 +110,7 @@ val previewUserNewsResources = listOf( headerImageUrl = "https://i.ytimg.com/vi/ZARz0pjm5YM/maxresdefault.jpg", publishDate = Instant.parse("2021-11-01T00:00:00.000Z"), type = Video, - topics = listOf(previewFollowableTopics[2]), + followableTopics = listOf(previewFollowableTopics[2]), isSaved = false ), UserNewsResource( @@ -100,7 +122,7 @@ val previewUserNewsResources = listOf( headerImageUrl = "", publishDate = Instant.parse("2022-10-01T00:00:00.000Z"), type = Unknown, - topics = listOf(previewFollowableTopics[2]), + followableTopics = listOf(previewFollowableTopics[2]), isSaved = true ) ) diff --git a/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt b/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt index d8fd950de..80d6013c9 100644 --- a/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt +++ b/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt @@ -16,11 +16,13 @@ package com.google.samples.apps.nowinandroid.core.domain -import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource +import com.google.samples.apps.nowinandroid.core.model.data.DarkThemeConfig.FOLLOW_SYSTEM import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType.Video +import com.google.samples.apps.nowinandroid.core.model.data.ThemeBrand.DEFAULT import com.google.samples.apps.nowinandroid.core.model.data.Topic +import com.google.samples.apps.nowinandroid.core.model.data.UserData import com.google.samples.apps.nowinandroid.core.testing.repository.TestNewsRepository import com.google.samples.apps.nowinandroid.core.testing.repository.TestUserDataRepository import com.google.samples.apps.nowinandroid.core.testing.util.MainDispatcherRule @@ -44,107 +46,59 @@ class GetUserNewsResourcesUseCaseTest { @Test fun whenNoFilters_allNewsResourcesAreReturned() = runTest { - // Obtain the saveable news resources stream. - val saveableNewsResources = useCase() + // Obtain the user news resources stream. + val userNewsResources = useCase() - // Send some news resources and bookmarks. + // Send some news resources and user data into the data repositories. newsRepository.sendNewsResources(sampleNewsResources) - userDataRepository.setNewsResourceBookmarks( - setOf(sampleNewsResources[0].id, sampleNewsResources[2].id) + + // Construct the test user data with bookmarks and followed topics. + val userData = UserData( + bookmarkedNewsResources = setOf(sampleNewsResources[0].id, sampleNewsResources[2].id), + followedTopics = setOf(sampleTopic1.id), + themeBrand = DEFAULT, + darkThemeConfig = FOLLOW_SYSTEM, + shouldHideOnboarding = false ) - // Set a followed topic for the user. - userDataRepository.setFollowedTopicIds(setOf(sampleTopic1.id)) + userDataRepository.setUserData(userData) // Check that the correct news resources are returned with their bookmarked state. assertEquals( listOf( - UserNewsResource( - sampleNewsResources[0].id, - sampleNewsResources[0].title, - sampleNewsResources[0].content, - sampleNewsResources[0].url, - sampleNewsResources[0].headerImageUrl, - sampleNewsResources[0].publishDate, - sampleNewsResources[0].type, - sampleNewsResources[0].topics.map { topic -> - FollowableTopic( - topic = topic, - isFollowed = topic.id == sampleTopic1.id - ) - }, - true - ), - UserNewsResource( - sampleNewsResources[1].id, - sampleNewsResources[1].title, - sampleNewsResources[1].content, - sampleNewsResources[1].url, - sampleNewsResources[1].headerImageUrl, - sampleNewsResources[1].publishDate, - sampleNewsResources[1].type, - sampleNewsResources[1].topics.map { topic -> - FollowableTopic( - topic = topic, - isFollowed = topic.id == sampleTopic1.id - ) - }, - false - ), - UserNewsResource( - sampleNewsResources[2].id, - sampleNewsResources[2].title, - sampleNewsResources[2].content, - sampleNewsResources[2].url, - sampleNewsResources[2].headerImageUrl, - sampleNewsResources[2].publishDate, - sampleNewsResources[2].type, - sampleNewsResources[2].topics.map { topic -> - FollowableTopic( - topic = topic, - isFollowed = topic.id == sampleTopic1.id - ) - }, - true - ), + UserNewsResource.from(sampleNewsResources[0], userData), + UserNewsResource.from(sampleNewsResources[1], userData), + UserNewsResource.from(sampleNewsResources[2], userData), ), - saveableNewsResources.first() + userNewsResources.first() ) } @Test fun whenFilteredByTopicId_matchingNewsResourcesAreReturned() = runTest { - // Obtain a stream of saveable news resources for the given topic id. - val saveableNewsResources = useCase(filterTopicIds = setOf(sampleTopic1.id)) + // Obtain a stream of user news resources for the given topic id. + val userNewsResources = useCase(filterTopicIds = setOf(sampleTopic1.id)) - // Send some news resources and bookmarks. + // Send test data into the repositories. newsRepository.sendNewsResources(sampleNewsResources) - userDataRepository.setNewsResourceBookmarks(setOf()) + val userData = UserData( + bookmarkedNewsResources = emptySet(), + followedTopics = emptySet(), + themeBrand = DEFAULT, + darkThemeConfig = FOLLOW_SYSTEM, + shouldHideOnboarding = false + ) + userDataRepository.setUserData(userData) // Check that only news resources with the given topic id are returned. assertEquals( sampleNewsResources .filter { it.topics.contains(sampleTopic1) } .map { - UserNewsResource( - id = it.id, - title = it.title, - content = it.content, - url = it.url, - headerImageUrl = it.headerImageUrl, - publishDate = it.publishDate, - type = it.type, - topics = it.topics.map { topic -> - FollowableTopic( - topic = topic, - isFollowed = false - ) - }, - isSaved = false - ) + UserNewsResource.from(it, userData) }, - saveableNewsResources.first() + userNewsResources.first() ) } } diff --git a/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/UserNewsResourceTest.kt b/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/UserNewsResourceTest.kt new file mode 100644 index 000000000..6268b28f8 --- /dev/null +++ b/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/UserNewsResourceTest.kt @@ -0,0 +1,106 @@ +/* + * Copyright 2023 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.domain + +import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic +import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource +import com.google.samples.apps.nowinandroid.core.model.data.DarkThemeConfig.FOLLOW_SYSTEM +import com.google.samples.apps.nowinandroid.core.model.data.NewsResource +import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType.Article +import com.google.samples.apps.nowinandroid.core.model.data.ThemeBrand.DEFAULT +import com.google.samples.apps.nowinandroid.core.model.data.Topic +import com.google.samples.apps.nowinandroid.core.model.data.UserData +import kotlinx.datetime.Clock +import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue +import org.junit.Test + +class UserNewsResourceTest { + + /** + * Given: Some user data and news resources + * When: They are combined using `UserNewsResource.from` + * Then: The correct UserNewsResources are constructed + */ + @Test + fun userNewsResourcesAreConstructedFromNewsResourcesAndUserData() { + + val newsResource1 = NewsResource( + id = "N1", + title = "Test news title", + content = "Test news content", + url = "Test URL", + headerImageUrl = "Test image URL", + publishDate = Clock.System.now(), + type = Article, + topics = listOf( + Topic( + id = "T1", + name = "Topic 1", + shortDescription = "Topic 1 short description", + longDescription = "Topic 1 long description", + url = "Topic 1 URL", + imageUrl = "Topic 1 image URL" + ), + Topic( + id = "T2", + name = "Topic 2", + shortDescription = "Topic 2 short description", + longDescription = "Topic 2 long description", + url = "Topic 2 URL", + imageUrl = "Topic 2 image URL" + ), + ) + ) + + val userData = UserData( + bookmarkedNewsResources = setOf("N1"), + followedTopics = setOf("T1"), + themeBrand = DEFAULT, + darkThemeConfig = FOLLOW_SYSTEM, + shouldHideOnboarding = true + ) + + val userNewsResource = UserNewsResource.from(newsResource1, userData) + + // Check that the simple field mappings have been done correctly. + assertEquals(newsResource1.id, userNewsResource.id) + assertEquals(newsResource1.title, userNewsResource.title) + assertEquals(newsResource1.content, userNewsResource.content) + assertEquals(newsResource1.url, userNewsResource.url) + assertEquals(newsResource1.headerImageUrl, userNewsResource.headerImageUrl) + assertEquals(newsResource1.publishDate, userNewsResource.publishDate) + + // Check that each Topic has been converted to a FollowedTopic correctly. + assertEquals(newsResource1.topics.size, userNewsResource.followableTopics.size) + for (topic in newsResource1.topics) { + + // Construct the expected FollowableTopic. + val followableTopic = FollowableTopic( + topic = topic, + isFollowed = userData.followedTopics.contains(topic.id) + ) + assertTrue(userNewsResource.followableTopics.contains(followableTopic)) + } + + // Check that the saved flag is set correctly. + assertEquals( + userData.bookmarkedNewsResources.contains(newsResource1.id), + userNewsResource.isSaved + ) + } +} diff --git a/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/repository/TestUserDataRepository.kt b/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/repository/TestUserDataRepository.kt index 30ccbd402..04d5b3b10 100644 --- a/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/repository/TestUserDataRepository.kt +++ b/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/repository/TestUserDataRepository.kt @@ -98,4 +98,11 @@ class TestUserDataRepository : UserDataRepository { */ fun getCurrentFollowedTopics(): Set? = _userData.replayCache.firstOrNull()?.followedTopics + + /** + * A test-only API to allow setting of user data directly. + */ + fun setUserData(userData: UserData) { + _userData.tryEmit(userData) + } } diff --git a/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt b/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt index d1f5d7e87..69ea5fb14 100644 --- a/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt +++ b/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt @@ -79,7 +79,7 @@ class NewsResourceCardTest { @Test fun testTopicsChipColorBackground_matchesFollowedState() { - val followableTopics = previewUserNewsResources[1].topics + val followableTopics = previewUserNewsResources[1].followableTopics composeTestRule.setContent { NewsResourceTopics(topics = followableTopics) diff --git a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt index d2024f694..8a0a04dbf 100644 --- a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt +++ b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt @@ -116,7 +116,7 @@ fun NewsResourceCardExpanded( Spacer(modifier = Modifier.height(12.dp)) NewsResourceShortDescription(userNewsResource.content) Spacer(modifier = Modifier.height(12.dp)) - NewsResourceTopics(userNewsResource.topics) + NewsResourceTopics(userNewsResource.followableTopics) } } } diff --git a/feature/foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt b/feature/foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt index 5ab8d92db..7069c5ff5 100644 --- a/feature/foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt +++ b/feature/foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt @@ -292,7 +292,7 @@ class ForYouViewModelTest { headerImageUrl = it.headerImageUrl, publishDate = it.publishDate, type = it.type, - topics = it.topics.map { topic -> + followableTopics = it.topics.map { topic -> FollowableTopic( topic = topic, isFollowed = followedTopicIds.contains(topic.id) @@ -356,7 +356,7 @@ class ForYouViewModelTest { headerImageUrl = sampleNewsResources[1].headerImageUrl, publishDate = sampleNewsResources[1].publishDate, type = sampleNewsResources[1].type, - topics = sampleNewsResources[1].topics.map { topic -> + followableTopics = sampleNewsResources[1].topics.map { topic -> FollowableTopic( topic = topic, isFollowed = topic.id == followedTopicId @@ -372,7 +372,7 @@ class ForYouViewModelTest { headerImageUrl = sampleNewsResources[2].headerImageUrl, publishDate = sampleNewsResources[2].publishDate, type = sampleNewsResources[2].type, - topics = sampleNewsResources[2].topics.map { topic -> + followableTopics = sampleNewsResources[2].topics.map { topic -> FollowableTopic( topic = topic, isFollowed = topic.id == followedTopicId @@ -482,7 +482,7 @@ class ForYouViewModelTest { headerImageUrl = sampleNewsResources[1].headerImageUrl, publishDate = sampleNewsResources[1].publishDate, type = sampleNewsResources[1].type, - topics = sampleNewsResources[1].topics.map { topic -> + followableTopics = sampleNewsResources[1].topics.map { topic -> FollowableTopic( topic = topic, isFollowed = followedTopicIds.contains(topic.id) @@ -498,7 +498,7 @@ class ForYouViewModelTest { headerImageUrl = sampleNewsResources[2].headerImageUrl, publishDate = sampleNewsResources[2].publishDate, type = sampleNewsResources[2].type, - topics = sampleNewsResources[2].topics.map { topic -> + followableTopics = sampleNewsResources[2].topics.map { topic -> FollowableTopic( topic = topic, isFollowed = followedTopicIds.contains(topic.id) diff --git a/feature/topic/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreenTest.kt b/feature/topic/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreenTest.kt index c635b7a53..6e94aba9d 100644 --- a/feature/topic/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreenTest.kt +++ b/feature/topic/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreenTest.kt @@ -187,7 +187,7 @@ private val sampleUserNewsResources = listOf( headerImageUrl = "https://i.ytimg.com/vi/-fJ6poHQrjM/maxresdefault.jpg", publishDate = Instant.parse("2021-11-09T00:00:00.000Z"), type = Video, - topics = listOf( + followableTopics = listOf( FollowableTopic( topic = Topic( id = "0", From 24df51349d6341af62e2ebe63e28073cd24f6ab3 Mon Sep 17 00:00:00 2001 From: Don Turner Date: Thu, 5 Jan 2023 12:58:13 +0000 Subject: [PATCH 13/20] Move mapping logic into secondary constructor Change-Id: I032326f502d27f2d3bd9fb8273ae44df878d172c --- .../domain/GetUserNewsResourcesUseCase.kt | 2 +- .../core/domain/model/UserNewsResource.kt | 43 +++---- .../domain/GetUserNewsResourcesUseCaseTest.kt | 8 +- .../core/domain/UserNewsResourceTest.kt | 2 +- .../repository/TestUserDataRepository.kt | 2 +- .../feature/foryou/ForYouViewModelTest.kt | 114 +++++------------- 6 files changed, 56 insertions(+), 115 deletions(-) diff --git a/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCase.kt b/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCase.kt index 39bd38e1e..d77f8e9df 100644 --- a/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCase.kt +++ b/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCase.kt @@ -56,6 +56,6 @@ private fun Flow>.mapToUserNewsResources( filterNot { it.isEmpty() } .combine(userDataStream) { newsResources, userData -> newsResources.map { newsResource -> - UserNewsResource.from(newsResource, userData) + UserNewsResource(newsResource, userData) } } diff --git a/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/UserNewsResource.kt b/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/UserNewsResource.kt index 280f6b78a..872f93f16 100644 --- a/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/UserNewsResource.kt +++ b/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/UserNewsResource.kt @@ -30,9 +30,10 @@ import kotlinx.datetime.toInstant /* ktlint-disable max-line-length */ /** - * A [NewsResource] with the additional user information. + * A [NewsResource] with additional user information such as whether the user is following the + * news resource's topics and whether they have saved (bookmarked) this news resource. */ -data class UserNewsResource( +data class UserNewsResource internal constructor( val id: String, val title: String, val content: String, @@ -43,26 +44,26 @@ data class UserNewsResource( val followableTopics: List, val isSaved: Boolean ) { - companion object { - fun from(newsResource: NewsResource, userData: UserData): UserNewsResource { - return UserNewsResource( - id = newsResource.id, - title = newsResource.title, - content = newsResource.content, - url = newsResource.url, - headerImageUrl = newsResource.headerImageUrl, - publishDate = newsResource.publishDate, - type = newsResource.type, - followableTopics = newsResource.topics.map { topic -> - FollowableTopic( - topic = topic, - isFollowed = userData.followedTopics.contains(topic.id) - ) - }, - isSaved = userData.bookmarkedNewsResources.contains(newsResource.id) + constructor(newsResource: NewsResource, userData: UserData) : this( + id = newsResource.id, + title = newsResource.title, + content = newsResource.content, + url = newsResource.url, + headerImageUrl = newsResource.headerImageUrl, + publishDate = newsResource.publishDate, + type = newsResource.type, + followableTopics = newsResource.topics.map { topic -> + FollowableTopic( + topic = topic, + isFollowed = userData.followedTopics.contains(topic.id) ) - } - } + }, + isSaved = userData.bookmarkedNewsResources.contains(newsResource.id) + ) +} + +fun List.mapToUserNewsResources(userData: UserData): List { + return map { UserNewsResource(it, userData) } } val previewUserNewsResources = listOf( diff --git a/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt b/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt index 80d6013c9..61eab3ba8 100644 --- a/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt +++ b/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt @@ -66,9 +66,9 @@ class GetUserNewsResourcesUseCaseTest { // Check that the correct news resources are returned with their bookmarked state. assertEquals( listOf( - UserNewsResource.from(sampleNewsResources[0], userData), - UserNewsResource.from(sampleNewsResources[1], userData), - UserNewsResource.from(sampleNewsResources[2], userData), + UserNewsResource(sampleNewsResources[0], userData), + UserNewsResource(sampleNewsResources[1], userData), + UserNewsResource(sampleNewsResources[2], userData), ), userNewsResources.first() ) @@ -96,7 +96,7 @@ class GetUserNewsResourcesUseCaseTest { sampleNewsResources .filter { it.topics.contains(sampleTopic1) } .map { - UserNewsResource.from(it, userData) + UserNewsResource(it, userData) }, userNewsResources.first() ) diff --git a/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/UserNewsResourceTest.kt b/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/UserNewsResourceTest.kt index 6268b28f8..d1ea7b569 100644 --- a/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/UserNewsResourceTest.kt +++ b/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/UserNewsResourceTest.kt @@ -75,7 +75,7 @@ class UserNewsResourceTest { shouldHideOnboarding = true ) - val userNewsResource = UserNewsResource.from(newsResource1, userData) + val userNewsResource = UserNewsResource(newsResource1, userData) // Check that the simple field mappings have been done correctly. assertEquals(newsResource1.id, userNewsResource.id) diff --git a/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/repository/TestUserDataRepository.kt b/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/repository/TestUserDataRepository.kt index 04d5b3b10..8dba1bfc7 100644 --- a/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/repository/TestUserDataRepository.kt +++ b/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/repository/TestUserDataRepository.kt @@ -25,7 +25,7 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.filterNotNull -private val emptyUserData = UserData( +val emptyUserData = UserData( bookmarkedNewsResources = emptySet(), followedTopics = emptySet(), themeBrand = ThemeBrand.DEFAULT, diff --git a/feature/foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt b/feature/foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt index 7069c5ff5..4427b44fe 100644 --- a/feature/foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt +++ b/feature/foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt @@ -20,12 +20,14 @@ import com.google.samples.apps.nowinandroid.core.domain.GetFollowableTopicsUseCa import com.google.samples.apps.nowinandroid.core.domain.GetUserNewsResourcesUseCase import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource +import com.google.samples.apps.nowinandroid.core.domain.model.mapToUserNewsResources import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType.Video import com.google.samples.apps.nowinandroid.core.model.data.Topic import com.google.samples.apps.nowinandroid.core.testing.repository.TestNewsRepository import com.google.samples.apps.nowinandroid.core.testing.repository.TestTopicsRepository import com.google.samples.apps.nowinandroid.core.testing.repository.TestUserDataRepository +import com.google.samples.apps.nowinandroid.core.testing.repository.emptyUserData import com.google.samples.apps.nowinandroid.core.testing.util.MainDispatcherRule import com.google.samples.apps.nowinandroid.core.testing.util.TestNetworkMonitor import com.google.samples.apps.nowinandroid.core.testing.util.TestSyncStatusMonitor @@ -265,7 +267,8 @@ class ForYouViewModelTest { topicsRepository.sendTopics(sampleTopics) val followedTopicIds = setOf("0", "1") - userDataRepository.setFollowedTopicIds(followedTopicIds) + val userData = emptyUserData.copy(followedTopics = followedTopicIds) + userDataRepository.setUserData(userData) viewModel.dismissOnboarding() assertEquals( @@ -282,25 +285,7 @@ class ForYouViewModelTest { ) assertEquals( NewsFeedUiState.Success( - feed = - sampleNewsResources.map { - UserNewsResource( - id = it.id, - title = it.title, - content = it.content, - url = it.url, - headerImageUrl = it.headerImageUrl, - publishDate = it.publishDate, - type = it.type, - followableTopics = it.topics.map { topic -> - FollowableTopic( - topic = topic, - isFollowed = followedTopicIds.contains(topic.id) - ) - }, - isSaved = false - ) - } + feed = sampleNewsResources.mapToUserNewsResources(userData) ), viewModel.feedState.value ) @@ -345,41 +330,14 @@ class ForYouViewModelTest { ), viewModel.onboardingUiState.value ) + + val userData = emptyUserData.copy(followedTopics = setOf(followedTopicId)) + assertEquals( NewsFeedUiState.Success( feed = listOf( - UserNewsResource( - id = sampleNewsResources[1].id, - title = sampleNewsResources[1].title, - content = sampleNewsResources[1].content, - url = sampleNewsResources[1].url, - headerImageUrl = sampleNewsResources[1].headerImageUrl, - publishDate = sampleNewsResources[1].publishDate, - type = sampleNewsResources[1].type, - followableTopics = sampleNewsResources[1].topics.map { topic -> - FollowableTopic( - topic = topic, - isFollowed = topic.id == followedTopicId - ) - }, - isSaved = false - ), - UserNewsResource( - id = sampleNewsResources[2].id, - title = sampleNewsResources[2].title, - content = sampleNewsResources[2].content, - url = sampleNewsResources[2].url, - headerImageUrl = sampleNewsResources[2].headerImageUrl, - publishDate = sampleNewsResources[2].publishDate, - type = sampleNewsResources[2].type, - followableTopics = sampleNewsResources[2].topics.map { topic -> - FollowableTopic( - topic = topic, - isFollowed = topic.id == followedTopicId - ) - }, - isSaved = false - ) + UserNewsResource(sampleNewsResources[1], userData), + UserNewsResource(sampleNewsResources[2], userData), ) ), viewModel.feedState.value @@ -460,12 +418,24 @@ class ForYouViewModelTest { val collectJob2 = launch(UnconfinedTestDispatcher()) { viewModel.feedState.collect() } val followedTopicIds = setOf("1") + val userData = emptyUserData.copy( + followedTopics = followedTopicIds, + shouldHideOnboarding = true + ) topicsRepository.sendTopics(sampleTopics) - userDataRepository.setFollowedTopicIds(followedTopicIds) - userDataRepository.setShouldHideOnboarding(true) + userDataRepository.setUserData(userData) newsRepository.sendNewsResources(sampleNewsResources) - viewModel.updateNewsResourceSaved("2", true) + + val bookmarkedNewsResourceId = "2" + viewModel.updateNewsResourceSaved( + newsResourceId = bookmarkedNewsResourceId, + isChecked = true + ) + + val userDataExpected = userData.copy( + bookmarkedNewsResources = setOf(bookmarkedNewsResourceId) + ) assertEquals( OnboardingUiState.NotShown, @@ -474,38 +444,8 @@ class ForYouViewModelTest { assertEquals( NewsFeedUiState.Success( feed = listOf( - UserNewsResource( - id = sampleNewsResources[1].id, - title = sampleNewsResources[1].title, - content = sampleNewsResources[1].content, - url = sampleNewsResources[1].url, - headerImageUrl = sampleNewsResources[1].headerImageUrl, - publishDate = sampleNewsResources[1].publishDate, - type = sampleNewsResources[1].type, - followableTopics = sampleNewsResources[1].topics.map { topic -> - FollowableTopic( - topic = topic, - isFollowed = followedTopicIds.contains(topic.id) - ) - }, - isSaved = true - ), - UserNewsResource( - id = sampleNewsResources[2].id, - title = sampleNewsResources[2].title, - content = sampleNewsResources[2].content, - url = sampleNewsResources[2].url, - headerImageUrl = sampleNewsResources[2].headerImageUrl, - publishDate = sampleNewsResources[2].publishDate, - type = sampleNewsResources[2].type, - followableTopics = sampleNewsResources[2].topics.map { topic -> - FollowableTopic( - topic = topic, - isFollowed = followedTopicIds.contains(topic.id) - ) - }, - isSaved = false - ), + UserNewsResource(newsResource = sampleNewsResources[1], userDataExpected), + UserNewsResource(newsResource = sampleNewsResources[2], userDataExpected) ) ), viewModel.feedState.value From 6207fe3bcf34d95fd653ca5e24ea5e4dc1cd3994 Mon Sep 17 00:00:00 2001 From: Don Turner Date: Thu, 5 Jan 2023 13:09:23 +0000 Subject: [PATCH 14/20] mapToUserNewsResources converts List to List Change-Id: I072effef0f66caf51227ba8c64f0857fb837308d --- .../nowinandroid/core/domain/GetUserNewsResourcesUseCase.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCase.kt b/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCase.kt index d77f8e9df..07cd6d856 100644 --- a/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCase.kt +++ b/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCase.kt @@ -19,6 +19,7 @@ package com.google.samples.apps.nowinandroid.core.domain import com.google.samples.apps.nowinandroid.core.data.repository.NewsRepository import com.google.samples.apps.nowinandroid.core.data.repository.UserDataRepository import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource +import com.google.samples.apps.nowinandroid.core.domain.model.mapToUserNewsResources import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.model.data.UserData import javax.inject.Inject @@ -55,7 +56,5 @@ private fun Flow>.mapToUserNewsResources( ): Flow> = filterNot { it.isEmpty() } .combine(userDataStream) { newsResources, userData -> - newsResources.map { newsResource -> - UserNewsResource(newsResource, userData) - } + newsResources.mapToUserNewsResources(userData) } From 66046a86b06aecb73c96cccd6b08c4945afb8759 Mon Sep 17 00:00:00 2001 From: magicalmeghan Date: Thu, 5 Jan 2023 14:03:20 -0500 Subject: [PATCH 15/20] Updated NewsResourceCardTest --- .../core/ui/NewsResourceCardTest.kt | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt b/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt index 69ea5fb14..a6db7e08a 100644 --- a/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt +++ b/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt @@ -21,6 +21,7 @@ import androidx.compose.ui.test.assertContentDescriptionEquals import androidx.compose.ui.test.assertIsDisplayed import androidx.compose.ui.test.junit4.createAndroidComposeRule import androidx.compose.ui.test.onNodeWithText +import com.google.samples.apps.nowinandroid.core.domain.model.previewFollowableTopics import com.google.samples.apps.nowinandroid.core.domain.model.previewUserNewsResources import org.junit.Rule import org.junit.Test @@ -79,15 +80,20 @@ class NewsResourceCardTest { @Test fun testTopicsChipColorBackground_matchesFollowedState() { - val followableTopics = previewUserNewsResources[1].followableTopics - composeTestRule.setContent { - NewsResourceTopics(topics = followableTopics) + NewsResourceTopics(topics = previewFollowableTopics) } - composeTestRule - .onNodeWithText(followableTopics[1].topic.name) - .assertContentDescriptionEquals("UI is followed") + for(followableTopic in previewFollowableTopics){ + val topicName = followableTopic.topic.name + val expectedContentDescription = if (followableTopic.isFollowed) { + "$topicName is followed" + } else { + "$topicName is not followed" + } + composeTestRule + .onNodeWithText(topicName.uppercase()) + .assertContentDescriptionEquals(expectedContentDescription) + } } - // TODO add a test for not followed - figure out whether to put it here or to make a new test } From dd81618f898ba86db0f97ae19ff1bd1dd2b4c798 Mon Sep 17 00:00:00 2001 From: Don Turner Date: Thu, 5 Jan 2023 19:22:01 +0000 Subject: [PATCH 16/20] Fix UI tests Change-Id: Ie42077d20523c28a61c75bccfdc11d8a34d8a8a9 --- .../feature/topic/TopicScreenTest.kt | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/feature/topic/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreenTest.kt b/feature/topic/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreenTest.kt index 6e94aba9d..a7514ea63 100644 --- a/feature/topic/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreenTest.kt +++ b/feature/topic/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreenTest.kt @@ -26,8 +26,11 @@ import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performScrollToNode import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource +import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType.Video import com.google.samples.apps.nowinandroid.core.model.data.Topic +import com.google.samples.apps.nowinandroid.core.model.data.UserData +import com.google.samples.apps.nowinandroid.core.testing.repository.emptyUserData import kotlinx.datetime.Instant import org.junit.Before import org.junit.Rule @@ -177,29 +180,27 @@ private val testTopics = listOf( private val sampleUserNewsResources = listOf( UserNewsResource( - id = "1", - title = "Thanks for helping us reach 1M YouTube Subscribers", - content = "Thank you everyone for following the Now in Android series and everything the " + - "Android Developers YouTube channel has to offer. During the Android Developer " + - "Summit, our YouTube channel reached 1 million subscribers! Here’s a small video to " + - "thank you all.", - url = "https://youtu.be/-fJ6poHQrjM", - headerImageUrl = "https://i.ytimg.com/vi/-fJ6poHQrjM/maxresdefault.jpg", - publishDate = Instant.parse("2021-11-09T00:00:00.000Z"), - type = Video, - followableTopics = listOf( - FollowableTopic( - topic = Topic( + newsResource = + NewsResource( + id = "1", + title = "Thanks for helping us reach 1M YouTube Subscribers", + content = "Thank you everyone for following the Now in Android series and everything the " + + "Android Developers YouTube channel has to offer. During the Android Developer " + + "Summit, our YouTube channel reached 1 million subscribers! Here’s a small video to " + + "thank you all.", + url = "https://youtu.be/-fJ6poHQrjM", + headerImageUrl = "https://i.ytimg.com/vi/-fJ6poHQrjM/maxresdefault.jpg", + publishDate = Instant.parse("2021-11-09T00:00:00.000Z"), + type = Video, + topics = listOf (Topic( id = "0", name = "Headlines", shortDescription = "", longDescription = TOPIC_DESC, url = "", imageUrl = "" - ), - isFollowed = false - ) - ), - isSaved = true + )) + ), + userData = emptyUserData.copy(bookmarkedNewsResources = setOf("1")) ) ) From cafac8eb0964b40f0795b295989952c13cb984a8 Mon Sep 17 00:00:00 2001 From: Don Turner Date: Thu, 5 Jan 2023 19:28:10 +0000 Subject: [PATCH 17/20] fix spotless, tidy test data Change-Id: I4ceb7b85e5a8dd4d4f20088b2594c6b4030299bb --- .../domain/GetUserNewsResourcesUseCaseTest.kt | 22 +++---------- .../core/ui/NewsResourceCardTest.kt | 2 +- .../feature/topic/TopicScreenTest.kt | 31 ++++++++++--------- 3 files changed, 22 insertions(+), 33 deletions(-) diff --git a/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt b/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt index 61eab3ba8..11e46e41d 100644 --- a/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt +++ b/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt @@ -17,14 +17,12 @@ package com.google.samples.apps.nowinandroid.core.domain import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource -import com.google.samples.apps.nowinandroid.core.model.data.DarkThemeConfig.FOLLOW_SYSTEM import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType.Video -import com.google.samples.apps.nowinandroid.core.model.data.ThemeBrand.DEFAULT import com.google.samples.apps.nowinandroid.core.model.data.Topic -import com.google.samples.apps.nowinandroid.core.model.data.UserData import com.google.samples.apps.nowinandroid.core.testing.repository.TestNewsRepository import com.google.samples.apps.nowinandroid.core.testing.repository.TestUserDataRepository +import com.google.samples.apps.nowinandroid.core.testing.repository.emptyUserData import com.google.samples.apps.nowinandroid.core.testing.util.MainDispatcherRule import kotlin.test.assertEquals import kotlinx.coroutines.flow.first @@ -53,12 +51,9 @@ class GetUserNewsResourcesUseCaseTest { newsRepository.sendNewsResources(sampleNewsResources) // Construct the test user data with bookmarks and followed topics. - val userData = UserData( + val userData = emptyUserData.copy( bookmarkedNewsResources = setOf(sampleNewsResources[0].id, sampleNewsResources[2].id), - followedTopics = setOf(sampleTopic1.id), - themeBrand = DEFAULT, - darkThemeConfig = FOLLOW_SYSTEM, - shouldHideOnboarding = false + followedTopics = setOf(sampleTopic1.id) ) userDataRepository.setUserData(userData) @@ -82,21 +77,14 @@ class GetUserNewsResourcesUseCaseTest { // Send test data into the repositories. newsRepository.sendNewsResources(sampleNewsResources) - val userData = UserData( - bookmarkedNewsResources = emptySet(), - followedTopics = emptySet(), - themeBrand = DEFAULT, - darkThemeConfig = FOLLOW_SYSTEM, - shouldHideOnboarding = false - ) - userDataRepository.setUserData(userData) + userDataRepository.setUserData(emptyUserData) // Check that only news resources with the given topic id are returned. assertEquals( sampleNewsResources .filter { it.topics.contains(sampleTopic1) } .map { - UserNewsResource(it, userData) + UserNewsResource(it, emptyUserData) }, userNewsResources.first() ) diff --git a/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt b/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt index a6db7e08a..6fbe0b0e4 100644 --- a/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt +++ b/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt @@ -84,7 +84,7 @@ class NewsResourceCardTest { NewsResourceTopics(topics = previewFollowableTopics) } - for(followableTopic in previewFollowableTopics){ + for (followableTopic in previewFollowableTopics) { val topicName = followableTopic.topic.name val expectedContentDescription = if (followableTopic.isFollowed) { "$topicName is followed" diff --git a/feature/topic/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreenTest.kt b/feature/topic/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreenTest.kt index a7514ea63..df9e83315 100644 --- a/feature/topic/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreenTest.kt +++ b/feature/topic/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreenTest.kt @@ -29,7 +29,6 @@ import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType.Video import com.google.samples.apps.nowinandroid.core.model.data.Topic -import com.google.samples.apps.nowinandroid.core.model.data.UserData import com.google.samples.apps.nowinandroid.core.testing.repository.emptyUserData import kotlinx.datetime.Instant import org.junit.Before @@ -181,26 +180,28 @@ private val testTopics = listOf( private val sampleUserNewsResources = listOf( UserNewsResource( newsResource = - NewsResource( - id = "1", - title = "Thanks for helping us reach 1M YouTube Subscribers", - content = "Thank you everyone for following the Now in Android series and everything the " + - "Android Developers YouTube channel has to offer. During the Android Developer " + - "Summit, our YouTube channel reached 1 million subscribers! Here’s a small video to " + - "thank you all.", - url = "https://youtu.be/-fJ6poHQrjM", - headerImageUrl = "https://i.ytimg.com/vi/-fJ6poHQrjM/maxresdefault.jpg", - publishDate = Instant.parse("2021-11-09T00:00:00.000Z"), - type = Video, - topics = listOf (Topic( + NewsResource( + id = "1", + title = "Thanks for helping us reach 1M YouTube Subscribers", + content = "Thank you everyone for following the Now in Android series and" + + " everything the Android Developers YouTube channel has to offer. During the " + + "Android Developer Summit, our YouTube channel reached 1 million subscribers!" + + " Here’s a small video to thank you all.", + url = "https://youtu.be/-fJ6poHQrjM", + headerImageUrl = "https://i.ytimg.com/vi/-fJ6poHQrjM/maxresdefault.jpg", + publishDate = Instant.parse("2021-11-09T00:00:00.000Z"), + type = Video, + topics = listOf( + Topic( id = "0", name = "Headlines", shortDescription = "", longDescription = TOPIC_DESC, url = "", imageUrl = "" - )) - ), + ) + ) + ), userData = emptyUserData.copy(bookmarkedNewsResources = setOf("1")) ) ) From 5137cd77776a345423753181a4857df910f49993 Mon Sep 17 00:00:00 2001 From: magicalmeghan Date: Thu, 5 Jan 2023 14:48:41 -0500 Subject: [PATCH 18/20] removed hardcoded strings --- .../samples/apps/nowinandroid/core/ui/NewsResourceCard.kt | 8 +++++--- core/ui/src/main/res/values/strings.xml | 3 +++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt index 8a0a04dbf..68196a5af 100644 --- a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt +++ b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt @@ -236,6 +236,8 @@ fun NewsResourceTopics( // Store the ID of the Topic which has its "following" menu expanded, if any. // To avoid UI confusion, only one topic can have an expanded menu at a time. var expandedTopicId by remember { mutableStateOf(null) } + val isFollowed = stringResource(R.string.topic_is_followed) + val isNotFollowed = stringResource(R.string.topic_is_not_followed) Row( modifier = modifier.horizontalScroll(rememberScrollState()), // causes narrow chips @@ -255,10 +257,10 @@ fun NewsResourceTopics( Text( text = followableTopic.topic.name.uppercase(Locale.getDefault()), modifier = Modifier.semantics { + contentDescription = followableTopic.topic.name + - if (followableTopic.isFollowed) " is followed" - else " is not followed" - // make sure this is the right place to add this - remove hardcoded strings + if (followableTopic.isFollowed) isFollowed + else isNotFollowed } ) } diff --git a/core/ui/src/main/res/values/strings.xml b/core/ui/src/main/res/values/strings.xml index 6d7c98eb1..fff33bf3a 100644 --- a/core/ui/src/main/res/values/strings.xml +++ b/core/ui/src/main/res/values/strings.xml @@ -21,4 +21,7 @@ Open Resource Link %1$s • %2$s + + is followed + is not followed From 45e3cfd9892deadc655b5cc86640eb2afc246edf Mon Sep 17 00:00:00 2001 From: magicalmeghan Date: Thu, 5 Jan 2023 15:37:35 -0500 Subject: [PATCH 19/20] fixed string issue for testTopicsChipColorBackground_matchesFollowedState test --- .../samples/apps/nowinandroid/core/ui/NewsResourceCard.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt index 68196a5af..59b18ca9c 100644 --- a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt +++ b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt @@ -258,7 +258,7 @@ fun NewsResourceTopics( text = followableTopic.topic.name.uppercase(Locale.getDefault()), modifier = Modifier.semantics { - contentDescription = followableTopic.topic.name + + contentDescription = followableTopic.topic.name + " " + if (followableTopic.isFollowed) isFollowed else isNotFollowed } From bad3ea60f5f162743e42fe868f20fab92ddf2dba Mon Sep 17 00:00:00 2001 From: Don Turner Date: Thu, 5 Jan 2023 20:54:15 +0000 Subject: [PATCH 20/20] Refactor Topics news feed, tidy a few other bits up Change-Id: Id4c9d1bce484137b363ec4cd21a45ca9863a2e7f --- .../domain/GetUserNewsResourcesUseCaseTest.kt | 12 ++----- .../nowinandroid/core/ui/NewsResourceCard.kt | 18 +++++++---- .../core/ui/NewsResourceCardList.kt | 32 ++++++++----------- core/ui/src/main/res/values/strings.xml | 4 +-- .../nowinandroid/feature/topic/TopicScreen.kt | 11 +++---- 5 files changed, 35 insertions(+), 42 deletions(-) diff --git a/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt b/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt index 11e46e41d..fe50ecf4d 100644 --- a/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt +++ b/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetUserNewsResourcesUseCaseTest.kt @@ -16,7 +16,7 @@ package com.google.samples.apps.nowinandroid.core.domain -import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource +import com.google.samples.apps.nowinandroid.core.domain.model.mapToUserNewsResources import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType.Video import com.google.samples.apps.nowinandroid.core.model.data.Topic @@ -60,11 +60,7 @@ class GetUserNewsResourcesUseCaseTest { // Check that the correct news resources are returned with their bookmarked state. assertEquals( - listOf( - UserNewsResource(sampleNewsResources[0], userData), - UserNewsResource(sampleNewsResources[1], userData), - UserNewsResource(sampleNewsResources[2], userData), - ), + sampleNewsResources.mapToUserNewsResources(userData), userNewsResources.first() ) } @@ -83,9 +79,7 @@ class GetUserNewsResourcesUseCaseTest { assertEquals( sampleNewsResources .filter { it.topics.contains(sampleTopic1) } - .map { - UserNewsResource(it, emptyUserData) - }, + .mapToUserNewsResources(emptyUserData), userNewsResources.first() ) } diff --git a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt index 59b18ca9c..76657067e 100644 --- a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt +++ b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt @@ -236,8 +236,6 @@ fun NewsResourceTopics( // Store the ID of the Topic which has its "following" menu expanded, if any. // To avoid UI confusion, only one topic can have an expanded menu at a time. var expandedTopicId by remember { mutableStateOf(null) } - val isFollowed = stringResource(R.string.topic_is_followed) - val isNotFollowed = stringResource(R.string.topic_is_not_followed) Row( modifier = modifier.horizontalScroll(rememberScrollState()), // causes narrow chips @@ -254,13 +252,21 @@ fun NewsResourceTopics( onUnfollowClick = { }, // ToDo onBrowseClick = { }, // ToDo text = { + val contentDescription = if (followableTopic.isFollowed) { + stringResource( + R.string.topic_chip_content_description_when_followed, + followableTopic.topic.name + ) + } else { + stringResource( + R.string.topic_chip_content_description_when_not_followed, + followableTopic.topic.name + ) + } Text( text = followableTopic.topic.name.uppercase(Locale.getDefault()), modifier = Modifier.semantics { - - contentDescription = followableTopic.topic.name + " " + - if (followableTopic.isFollowed) isFollowed - else isNotFollowed + this.contentDescription = contentDescription } ) } diff --git a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardList.kt b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardList.kt index c7441c182..e0bd22785 100644 --- a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardList.kt +++ b/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardList.kt @@ -24,42 +24,36 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.platform.LocalContext import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource -import com.google.samples.apps.nowinandroid.core.model.data.NewsResource /** - * Extension function for displaying a [List] of [NewsResourceCardExpanded] backed by a generic - * [List] [T]. + * Extension function for displaying a [List] of [NewsResourceCardExpanded] backed by a list of + * [UserNewsResource]s. * - * [newsResourceMapper] maps type [T] to a [NewsResource] - * [isBookmarkedMapper] maps type [T] to whether the [NewsResource] is bookmarked * [onToggleBookmark] defines the action invoked when a user wishes to bookmark an item * [onItemClick] optional parameter for action to be performed when the card is clicked. The * default action launches an intent matching the card. */ -fun LazyListScope.newsResourceCardItems( - items: List, - newsResourceMapper: (item: T) -> UserNewsResource, // TODO remove this? - isBookmarkedMapper: (item: T) -> Boolean, - onToggleBookmark: (item: T) -> Unit, - onItemClick: ((item: T) -> Unit)? = null, +fun LazyListScope.userNewsResourceCardItems( + items: List, + onToggleBookmark: (item: UserNewsResource) -> Unit, + onItemClick: ((item: UserNewsResource) -> Unit)? = null, itemModifier: Modifier = Modifier, ) = items( items = items, - key = { newsResourceMapper(it).id }, - itemContent = { item -> - val newsResource = newsResourceMapper(item) - val resourceUrl = Uri.parse(newsResource.url) + key = { it.id }, + itemContent = { userNewsResource -> + val resourceUrl = Uri.parse(userNewsResource.url) val backgroundColor = MaterialTheme.colorScheme.background.toArgb() val context = LocalContext.current NewsResourceCardExpanded( - userNewsResource = newsResource, - isBookmarked = isBookmarkedMapper(item), - onToggleBookmark = { onToggleBookmark(item) }, + userNewsResource = userNewsResource, + isBookmarked = userNewsResource.isSaved, + onToggleBookmark = { onToggleBookmark(userNewsResource) }, onClick = { when (onItemClick) { null -> launchCustomChromeTab(context, resourceUrl, backgroundColor) - else -> onItemClick(item) + else -> onItemClick(userNewsResource) } }, modifier = itemModifier diff --git a/core/ui/src/main/res/values/strings.xml b/core/ui/src/main/res/values/strings.xml index fff33bf3a..bfb1d38de 100644 --- a/core/ui/src/main/res/values/strings.xml +++ b/core/ui/src/main/res/values/strings.xml @@ -22,6 +22,6 @@ Open Resource Link %1$s • %2$s - is followed - is not followed + %1$s is followed + %1$s is not followed diff --git a/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreen.kt b/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreen.kt index 263c04d78..b3263839f 100644 --- a/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreen.kt +++ b/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreen.kt @@ -57,7 +57,7 @@ import com.google.samples.apps.nowinandroid.core.domain.model.previewUserNewsRes import com.google.samples.apps.nowinandroid.core.model.data.previewTopics import com.google.samples.apps.nowinandroid.core.ui.DevicePreviews import com.google.samples.apps.nowinandroid.core.ui.TrackScrollJank -import com.google.samples.apps.nowinandroid.core.ui.newsResourceCardItems +import com.google.samples.apps.nowinandroid.core.ui.userNewsResourceCardItems import com.google.samples.apps.nowinandroid.feature.topic.R.string import com.google.samples.apps.nowinandroid.feature.topic.TopicUiState.Loading @@ -145,7 +145,7 @@ private fun LazyListScope.TopicBody( TopicHeader(name, description, imageUrl) } - TopicCards(news, onBookmarkChanged) + userNewsResourceCards(news, onBookmarkChanged) } @Composable @@ -173,16 +173,15 @@ private fun TopicHeader(name: String, description: String, imageUrl: String) { } } -private fun LazyListScope.TopicCards( +// TODO: Could/should this be replaced with [LazyGridScope.newsFeed]? +private fun LazyListScope.userNewsResourceCards( news: NewsUiState, onBookmarkChanged: (String, Boolean) -> Unit ) { when (news) { is NewsUiState.Success -> { - newsResourceCardItems( + userNewsResourceCardItems( items = news.news, - newsResourceMapper = { it }, - isBookmarkedMapper = { it.isSaved }, onToggleBookmark = { onBookmarkChanged(it.id, !it.isSaved) }, itemModifier = Modifier.padding(24.dp) )