diff --git a/app/build.gradle.kts b/app/build.gradle.kts index df5cfa2963..bca633d5d1 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -121,12 +121,3 @@ dependencies { implementation(libs.kotlinx.coroutines.guava) implementation(libs.coil.kt) } - -// androidx.test is forcing JUnit, 4.12. This forces it to use 4.13 -configurations.configureEach { - resolutionStrategy { - force(libs.junit4) - // Temporary workaround for https://issuetracker.google.com/174733673 - force("org.objenesis:objenesis:2.6") - } -} diff --git a/app/src/main/java/com/google/samples/apps/nowinandroid/MainActivityViewModel.kt b/app/src/main/java/com/google/samples/apps/nowinandroid/MainActivityViewModel.kt index ebea4b9656..09f4597a74 100644 --- a/app/src/main/java/com/google/samples/apps/nowinandroid/MainActivityViewModel.kt +++ b/app/src/main/java/com/google/samples/apps/nowinandroid/MainActivityViewModel.kt @@ -43,6 +43,6 @@ class MainActivityViewModel @Inject constructor( } sealed interface MainActivityUiState { - object Loading : MainActivityUiState + data object Loading : MainActivityUiState data class Success(val userData: UserData) : MainActivityUiState } diff --git a/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt index feffbd68a6..3ea2290f52 100644 --- a/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt @@ -21,7 +21,6 @@ import com.google.samples.apps.nowinandroid.configureGradleManagedDevices import com.google.samples.apps.nowinandroid.configureKotlinAndroid import com.google.samples.apps.nowinandroid.configurePrintApksTask import com.google.samples.apps.nowinandroid.disableUnnecessaryAndroidTests -import com.google.samples.apps.nowinandroid.libs import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.kotlin.dsl.configure @@ -46,13 +45,6 @@ class AndroidLibraryConventionPlugin : Plugin { configurePrintApksTask(this) disableUnnecessaryAndroidTests(target) } - configurations.configureEach { - resolutionStrategy { - force(libs.findLibrary("junit4").get()) - // Temporary workaround for https://issuetracker.google.com/174733673 - force("org.objenesis:objenesis:2.6") - } - } dependencies { add("androidTestImplementation", kotlin("test")) add("testImplementation", kotlin("test")) diff --git a/core/common/src/main/java/com/google/samples/apps/nowinandroid/core/decoder/StringDecoder.kt b/core/common/src/main/java/com/google/samples/apps/nowinandroid/core/decoder/StringDecoder.kt deleted file mode 100644 index 29437cc71e..0000000000 --- a/core/common/src/main/java/com/google/samples/apps/nowinandroid/core/decoder/StringDecoder.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.samples.apps.nowinandroid.core.decoder - -interface StringDecoder { - fun decodeString(encodedString: String): String -} diff --git a/core/common/src/main/java/com/google/samples/apps/nowinandroid/core/decoder/UriDecoder.kt b/core/common/src/main/java/com/google/samples/apps/nowinandroid/core/decoder/UriDecoder.kt deleted file mode 100644 index b114bdab64..0000000000 --- a/core/common/src/main/java/com/google/samples/apps/nowinandroid/core/decoder/UriDecoder.kt +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.samples.apps.nowinandroid.core.decoder - -import android.net.Uri -import javax.inject.Inject - -class UriDecoder @Inject constructor() : StringDecoder { - override fun decodeString(encodedString: String): String = Uri.decode(encodedString) -} diff --git a/core/common/src/main/java/com/google/samples/apps/nowinandroid/core/decoder/di/StringDecoderModule.kt b/core/common/src/main/java/com/google/samples/apps/nowinandroid/core/decoder/di/StringDecoderModule.kt deleted file mode 100644 index e39b0e1f82..0000000000 --- a/core/common/src/main/java/com/google/samples/apps/nowinandroid/core/decoder/di/StringDecoderModule.kt +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.samples.apps.nowinandroid.core.decoder.di - -import com.google.samples.apps.nowinandroid.core.decoder.StringDecoder -import com.google.samples.apps.nowinandroid.core.decoder.UriDecoder -import dagger.Binds -import dagger.Module -import dagger.hilt.InstallIn -import dagger.hilt.components.SingletonComponent - -@Module -@InstallIn(SingletonComponent::class) -abstract class StringDecoderModule { - @Binds - abstract fun bindStringDecoder(uriDecoder: UriDecoder): StringDecoder -} diff --git a/core/common/src/main/java/com/google/samples/apps/nowinandroid/core/result/Result.kt b/core/common/src/main/java/com/google/samples/apps/nowinandroid/core/result/Result.kt index 4a06b8b9d0..6ae12d634e 100644 --- a/core/common/src/main/java/com/google/samples/apps/nowinandroid/core/result/Result.kt +++ b/core/common/src/main/java/com/google/samples/apps/nowinandroid/core/result/Result.kt @@ -24,7 +24,7 @@ import kotlinx.coroutines.flow.onStart sealed interface Result { data class Success(val data: T) : Result data class Error(val exception: Throwable? = null) : Result - object Loading : Result + data object Loading : Result } fun Flow.asResult(): Flow> { diff --git a/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/decoder/FakeStringDecoder.kt b/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/decoder/FakeStringDecoder.kt deleted file mode 100644 index 7282661cce..0000000000 --- a/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/decoder/FakeStringDecoder.kt +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.samples.apps.nowinandroid.core.testing.decoder - -import com.google.samples.apps.nowinandroid.core.decoder.StringDecoder -import javax.inject.Inject - -class FakeStringDecoder @Inject constructor() : StringDecoder { - override fun decodeString(encodedString: String): String = encodedString -} diff --git a/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/di/TestStringDecoderModule.kt b/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/di/TestStringDecoderModule.kt deleted file mode 100644 index 0873ee5461..0000000000 --- a/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/di/TestStringDecoderModule.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.samples.apps.nowinandroid.core.testing.di - -import com.google.samples.apps.nowinandroid.core.decoder.StringDecoder -import com.google.samples.apps.nowinandroid.core.decoder.di.StringDecoderModule -import com.google.samples.apps.nowinandroid.core.testing.decoder.FakeStringDecoder -import dagger.Binds -import dagger.Module -import dagger.hilt.components.SingletonComponent -import dagger.hilt.testing.TestInstallIn - -@Module -@TestInstallIn( - components = [SingletonComponent::class], - replaces = [StringDecoderModule::class], -) -abstract class TestStringDecoderModule { - @Binds - abstract fun bindsStringDecoder(fakeStringDecoder: FakeStringDecoder): StringDecoder -} 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 16cd3edf7e..4a9f5d7c9a 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 @@ -112,7 +112,7 @@ sealed interface NewsFeedUiState { /** * The feed is still loading. */ - object Loading : NewsFeedUiState + data object Loading : NewsFeedUiState /** * The feed is loaded with the given list of news resources. diff --git a/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/OnboardingUiState.kt b/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/OnboardingUiState.kt index 58f4f16836..70634b4c53 100644 --- a/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/OnboardingUiState.kt +++ b/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/OnboardingUiState.kt @@ -25,17 +25,17 @@ sealed interface OnboardingUiState { /** * The onboarding state is loading. */ - object Loading : OnboardingUiState + data object Loading : OnboardingUiState /** * The onboarding state was unable to load. */ - object LoadFailed : OnboardingUiState + data object LoadFailed : OnboardingUiState /** * There is no onboarding state. */ - object NotShown : OnboardingUiState + data object NotShown : OnboardingUiState /** * There is a onboarding state, with the given lists of topics. diff --git a/feature/interests/src/main/java/com/google/samples/apps/nowinandroid/feature/interests/InterestsViewModel.kt b/feature/interests/src/main/java/com/google/samples/apps/nowinandroid/feature/interests/InterestsViewModel.kt index debc49bcd7..c3d5ab6e8a 100644 --- a/feature/interests/src/main/java/com/google/samples/apps/nowinandroid/feature/interests/InterestsViewModel.kt +++ b/feature/interests/src/main/java/com/google/samples/apps/nowinandroid/feature/interests/InterestsViewModel.kt @@ -53,11 +53,11 @@ class InterestsViewModel @Inject constructor( } sealed interface InterestsUiState { - object Loading : InterestsUiState + data object Loading : InterestsUiState data class Interests( val topics: List, ) : InterestsUiState - object Empty : InterestsUiState + data object Empty : InterestsUiState } 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 2b2565f9e8..7f8c6067ee 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 @@ -23,7 +23,6 @@ import com.google.samples.apps.nowinandroid.core.data.repository.NewsResourceQue 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.data.repository.UserNewsResourceRepository -import com.google.samples.apps.nowinandroid.core.decoder.StringDecoder import com.google.samples.apps.nowinandroid.core.model.data.FollowableTopic import com.google.samples.apps.nowinandroid.core.model.data.Topic import com.google.samples.apps.nowinandroid.core.model.data.UserNewsResource @@ -43,13 +42,12 @@ import javax.inject.Inject @HiltViewModel class TopicViewModel @Inject constructor( savedStateHandle: SavedStateHandle, - stringDecoder: StringDecoder, private val userDataRepository: UserDataRepository, topicsRepository: TopicsRepository, userNewsResourceRepository: UserNewsResourceRepository, ) : ViewModel() { - private val topicArgs: TopicArgs = TopicArgs(savedStateHandle, stringDecoder) + private val topicArgs: TopicArgs = TopicArgs(savedStateHandle) val topicId = topicArgs.topicId diff --git a/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/navigation/TopicNavigation.kt b/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/navigation/TopicNavigation.kt index 0954a52ac3..c29b57d47c 100644 --- a/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/navigation/TopicNavigation.kt +++ b/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/navigation/TopicNavigation.kt @@ -16,7 +16,6 @@ package com.google.samples.apps.nowinandroid.feature.topic.navigation -import android.net.Uri import androidx.annotation.VisibleForTesting import androidx.lifecycle.SavedStateHandle import androidx.navigation.NavController @@ -24,19 +23,23 @@ import androidx.navigation.NavGraphBuilder import androidx.navigation.NavType import androidx.navigation.compose.composable import androidx.navigation.navArgument -import com.google.samples.apps.nowinandroid.core.decoder.StringDecoder import com.google.samples.apps.nowinandroid.feature.topic.TopicRoute +import java.net.URLDecoder +import java.net.URLEncoder +import kotlin.text.Charsets.UTF_8 + +private val URL_CHARACTER_ENCODING = UTF_8.name() @VisibleForTesting internal const val topicIdArg = "topicId" internal class TopicArgs(val topicId: String) { - constructor(savedStateHandle: SavedStateHandle, stringDecoder: StringDecoder) : - this(stringDecoder.decodeString(checkNotNull(savedStateHandle[topicIdArg]))) + constructor(savedStateHandle: SavedStateHandle) : + this(URLDecoder.decode(checkNotNull(savedStateHandle[topicIdArg]), URL_CHARACTER_ENCODING)) } fun NavController.navigateToTopic(topicId: String) { - val encodedId = Uri.encode(topicId) + val encodedId = URLEncoder.encode(topicId, URL_CHARACTER_ENCODING) this.navigate("topic_route/$encodedId") { launchSingleTop = true } 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 ff7a88160b..d365232d72 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 @@ -22,7 +22,6 @@ import com.google.samples.apps.nowinandroid.core.model.data.FollowableTopic 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.decoder.FakeStringDecoder 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 @@ -63,7 +62,6 @@ class TopicViewModelTest { fun setup() { viewModel = TopicViewModel( savedStateHandle = SavedStateHandle(mapOf(topicIdArg to testInputTopics[0].topic.id)), - stringDecoder = FakeStringDecoder(), userDataRepository = userDataRepository, topicsRepository = topicsRepository, userNewsResourceRepository = userNewsResourceRepository,