|
|
|
@ -14,43 +14,49 @@
|
|
|
|
|
* limitations under the License.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
package com.google.samples.apps.nowinandroid.ui.interests2pane
|
|
|
|
|
package com.google.samples.apps.nowinandroid.ui
|
|
|
|
|
|
|
|
|
|
import androidx.activity.compose.BackHandler
|
|
|
|
|
import androidx.compose.material3.adaptive.Posture
|
|
|
|
|
import androidx.compose.material3.adaptive.WindowAdaptiveInfo
|
|
|
|
|
import androidx.compose.ui.test.DeviceConfigurationOverride
|
|
|
|
|
import androidx.compose.ui.test.ForcedSize
|
|
|
|
|
import androidx.annotation.StringRes
|
|
|
|
|
import androidx.compose.ui.test.assertIsDisplayed
|
|
|
|
|
import androidx.compose.ui.test.assertIsNotDisplayed
|
|
|
|
|
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
|
|
|
|
|
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
|
|
|
|
import androidx.compose.ui.test.onNodeWithTag
|
|
|
|
|
import androidx.compose.ui.test.onNodeWithText
|
|
|
|
|
import androidx.compose.ui.test.performClick
|
|
|
|
|
import androidx.compose.ui.unit.DpSize
|
|
|
|
|
import androidx.compose.ui.unit.dp
|
|
|
|
|
import androidx.test.espresso.Espresso
|
|
|
|
|
import androidx.window.core.layout.WindowSizeClass
|
|
|
|
|
import com.google.samples.apps.nowinandroid.core.data.repository.TopicsRepository
|
|
|
|
|
import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
|
|
|
|
|
import com.google.samples.apps.nowinandroid.core.model.data.Topic
|
|
|
|
|
import com.google.samples.apps.nowinandroid.ui.stringResource
|
|
|
|
|
import com.google.samples.apps.nowinandroid.ui.interests2pane.InterestsListDetailScreen
|
|
|
|
|
import com.google.samples.apps.nowinandroid.uitesthiltmanifest.HiltComponentActivity
|
|
|
|
|
import dagger.hilt.android.testing.BindValue
|
|
|
|
|
import dagger.hilt.android.testing.HiltAndroidRule
|
|
|
|
|
import dagger.hilt.android.testing.HiltAndroidTest
|
|
|
|
|
import dagger.hilt.android.testing.HiltTestApplication
|
|
|
|
|
import kotlinx.coroutines.flow.first
|
|
|
|
|
import kotlinx.coroutines.runBlocking
|
|
|
|
|
import org.junit.Before
|
|
|
|
|
import org.junit.Rule
|
|
|
|
|
import org.junit.Test
|
|
|
|
|
import org.junit.rules.TemporaryFolder
|
|
|
|
|
import org.junit.runner.RunWith
|
|
|
|
|
import org.robolectric.RobolectricTestRunner
|
|
|
|
|
import org.robolectric.annotation.Config
|
|
|
|
|
import javax.inject.Inject
|
|
|
|
|
import kotlin.properties.ReadOnlyProperty
|
|
|
|
|
import kotlin.test.assertTrue
|
|
|
|
|
import com.google.samples.apps.nowinandroid.feature.topic.R as FeatureTopicR
|
|
|
|
|
|
|
|
|
|
private const val EXPANDED_WIDTH = "w1200dp-h840dp"
|
|
|
|
|
private const val COMPACT_WIDTH = "w412dp-h915dp"
|
|
|
|
|
|
|
|
|
|
@HiltAndroidTest
|
|
|
|
|
@RunWith(RobolectricTestRunner::class)
|
|
|
|
|
@Config(application = HiltTestApplication::class)
|
|
|
|
|
class InterestsListDetailScreenTest {
|
|
|
|
|
|
|
|
|
|
@get:Rule(order = 0)
|
|
|
|
|
val hiltRule = HiltAndroidRule(this)
|
|
|
|
|
|
|
|
|
@ -64,6 +70,11 @@ class InterestsListDetailScreenTest {
|
|
|
|
|
@Inject
|
|
|
|
|
lateinit var topicsRepository: TopicsRepository
|
|
|
|
|
|
|
|
|
|
/** Convenience function for getting all topics during tests, */
|
|
|
|
|
private fun getTopics(): List<Topic> = runBlocking {
|
|
|
|
|
topicsRepository.getTopics().first().sortedBy { it.name }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// The strings used for matching in these tests.
|
|
|
|
|
private val placeholderText by composeTestRule.stringResource(FeatureTopicR.string.feature_topic_select_an_interest)
|
|
|
|
|
private val listPaneTag = "interests:topics"
|
|
|
|
@ -71,39 +82,18 @@ class InterestsListDetailScreenTest {
|
|
|
|
|
private val Topic.testTag
|
|
|
|
|
get() = "topic:${this.id}"
|
|
|
|
|
|
|
|
|
|
// Overrides for device sizes.
|
|
|
|
|
private enum class TestDeviceConfig(widthDp: Float, heightDp: Float) {
|
|
|
|
|
Compact(412f, 915f),
|
|
|
|
|
Expanded(1200f, 840f),
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
val sizeOverride = DeviceConfigurationOverride.ForcedSize(DpSize(widthDp.dp, heightDp.dp))
|
|
|
|
|
val adaptiveInfo = WindowAdaptiveInfo(
|
|
|
|
|
windowSizeClass = WindowSizeClass.compute(widthDp, heightDp),
|
|
|
|
|
windowPosture = Posture(),
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Before
|
|
|
|
|
fun setup() {
|
|
|
|
|
hiltRule.inject()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Convenience function for getting all topics during tests, */
|
|
|
|
|
private fun getTopics(): List<Topic> = runBlocking {
|
|
|
|
|
topicsRepository.getTopics().first()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
@Config(qualifiers = EXPANDED_WIDTH)
|
|
|
|
|
fun expandedWidth_initialState_showsTwoPanesWithPlaceholder() {
|
|
|
|
|
composeTestRule.apply {
|
|
|
|
|
setContent {
|
|
|
|
|
with(TestDeviceConfig.Expanded) {
|
|
|
|
|
DeviceConfigurationOverride(override = sizeOverride) {
|
|
|
|
|
NiaTheme {
|
|
|
|
|
InterestsListDetailScreen(windowAdaptiveInfo = adaptiveInfo)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
InterestsListDetailScreen()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -113,15 +103,12 @@ class InterestsListDetailScreenTest {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
@Config(qualifiers = COMPACT_WIDTH)
|
|
|
|
|
fun compactWidth_initialState_showsListPane() {
|
|
|
|
|
composeTestRule.apply {
|
|
|
|
|
setContent {
|
|
|
|
|
with(TestDeviceConfig.Compact) {
|
|
|
|
|
DeviceConfigurationOverride(override = sizeOverride) {
|
|
|
|
|
NiaTheme {
|
|
|
|
|
InterestsListDetailScreen(windowAdaptiveInfo = adaptiveInfo)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
InterestsListDetailScreen()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -131,15 +118,12 @@ class InterestsListDetailScreenTest {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
@Config(qualifiers = EXPANDED_WIDTH)
|
|
|
|
|
fun expandedWidth_topicSelected_updatesDetailPane() {
|
|
|
|
|
composeTestRule.apply {
|
|
|
|
|
setContent {
|
|
|
|
|
with(TestDeviceConfig.Expanded) {
|
|
|
|
|
DeviceConfigurationOverride(override = sizeOverride) {
|
|
|
|
|
NiaTheme {
|
|
|
|
|
InterestsListDetailScreen(windowAdaptiveInfo = adaptiveInfo)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
InterestsListDetailScreen()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -153,15 +137,12 @@ class InterestsListDetailScreenTest {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
@Config(qualifiers = COMPACT_WIDTH)
|
|
|
|
|
fun compactWidth_topicSelected_showsTopicDetailPane() {
|
|
|
|
|
composeTestRule.apply {
|
|
|
|
|
setContent {
|
|
|
|
|
with(TestDeviceConfig.Compact) {
|
|
|
|
|
DeviceConfigurationOverride(override = sizeOverride) {
|
|
|
|
|
NiaTheme {
|
|
|
|
|
InterestsListDetailScreen(windowAdaptiveInfo = adaptiveInfo)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
InterestsListDetailScreen()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -175,27 +156,25 @@ class InterestsListDetailScreenTest {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
@Config(qualifiers = EXPANDED_WIDTH)
|
|
|
|
|
fun expandedWidth_backPressFromTopicDetail_leavesInterests() {
|
|
|
|
|
var unhandledBackPress = false
|
|
|
|
|
composeTestRule.apply {
|
|
|
|
|
setContent {
|
|
|
|
|
with(TestDeviceConfig.Expanded) {
|
|
|
|
|
DeviceConfigurationOverride(override = sizeOverride) {
|
|
|
|
|
NiaTheme {
|
|
|
|
|
// Back press should not be handled by the two pane layout, and thus
|
|
|
|
|
// "fall through" to this BackHandler.
|
|
|
|
|
BackHandler {
|
|
|
|
|
unhandledBackPress = true
|
|
|
|
|
}
|
|
|
|
|
InterestsListDetailScreen(windowAdaptiveInfo = adaptiveInfo)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
InterestsListDetailScreen()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
val firstTopic = getTopics().first()
|
|
|
|
|
onNodeWithText(firstTopic.name).performClick()
|
|
|
|
|
|
|
|
|
|
waitForIdle()
|
|
|
|
|
Espresso.pressBack()
|
|
|
|
|
|
|
|
|
|
assertTrue(unhandledBackPress)
|
|
|
|
@ -203,21 +182,19 @@ class InterestsListDetailScreenTest {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
@Config(qualifiers = COMPACT_WIDTH)
|
|
|
|
|
fun compactWidth_backPressFromTopicDetail_showsListPane() {
|
|
|
|
|
composeTestRule.apply {
|
|
|
|
|
setContent {
|
|
|
|
|
with(TestDeviceConfig.Compact) {
|
|
|
|
|
DeviceConfigurationOverride(override = sizeOverride) {
|
|
|
|
|
NiaTheme {
|
|
|
|
|
InterestsListDetailScreen(windowAdaptiveInfo = adaptiveInfo)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
InterestsListDetailScreen()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
val firstTopic = getTopics().first()
|
|
|
|
|
onNodeWithText(firstTopic.name).performClick()
|
|
|
|
|
|
|
|
|
|
waitForIdle()
|
|
|
|
|
Espresso.pressBack()
|
|
|
|
|
|
|
|
|
|
onNodeWithTag(listPaneTag).assertIsDisplayed()
|
|
|
|
@ -226,3 +203,8 @@ class InterestsListDetailScreenTest {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun AndroidComposeTestRule<*, *>.stringResource(
|
|
|
|
|
@StringRes resId: Int,
|
|
|
|
|
): ReadOnlyProperty<Any, String> =
|
|
|
|
|
ReadOnlyProperty { _, _ -> activity.getString(resId) }
|