Skip to content

Commit d7cca1d

Browse files
committed
Used persisted UI connection state when saving. Fixes #450.
1 parent 186d380 commit d7cca1d

13 files changed

Lines changed: 278 additions & 33 deletions

File tree

app/src/androidTest/java/com/mitteloupe/whoami/screen/HistoryScreen.kt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.mitteloupe.whoami.screen
22

33
import androidx.recyclerview.widget.RecyclerView
44
import androidx.recyclerview.widget.RecyclerView.ViewHolder
5+
import androidx.test.espresso.Espresso
56
import androidx.test.espresso.Espresso.onView
67
import androidx.test.espresso.assertion.ViewAssertions.matches
78
import androidx.test.espresso.contrib.RecyclerViewActions.actionOnItemAtPosition
@@ -72,14 +73,23 @@ class HistoryScreen {
7273
)
7374
}
7475

75-
fun tapDeleteForRecord(position: Int) {
76+
fun seeRecord(position: Int, ipAddress: String, city: String, postCode: String) {
77+
seeIpRecord(ipAddress = ipAddress, position = position)
78+
seeLocation(city = city, postCode = postCode, position = position)
79+
}
80+
81+
fun tapDeleteButtonForRecord(position: Int) {
7682
onView(recordsList)
7783
.perform(scrollToPosition<ViewHolder>(position.zeroBased))
7884
.perform(
7985
actionOnItemAtPosition<ViewHolder>(position.zeroBased, clickChildView(deleteButton))
8086
)
8187
}
8288

89+
fun tapBackButton() {
90+
Espresso.pressBack()
91+
}
92+
8393
private val Int.zeroBased
8494
get() = this - 1
8595
}

app/src/androidTest/java/com/mitteloupe/whoami/screen/HomeScreen.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ class HomeScreen {
2020
private val postCodeLabel = hasText("CM14")
2121
private val timeZoneLabel = hasText("Europe/London")
2222
private val internetServiceProviderLabel = hasText("TalkTalk Limited")
23+
private val saveDetailsButton = hasText("Save Details")
2324
private val openSourceNoticesButton = hasText("Open Source Notices")
2425

2526
fun ComposeContentTestRule.seeIpAddressLabel() {
@@ -58,7 +59,11 @@ class HomeScreen {
5859
assertIsDisplayed(internetServiceProviderLabel)
5960
}
6061

61-
fun ComposeContentTestRule.tapOpenSourceNotices() {
62+
fun ComposeContentTestRule.tapSaveDetailsButton() {
63+
onNode(saveDetailsButton).performTouchInput { click() }
64+
}
65+
66+
fun ComposeContentTestRule.tapOpenSourceNoticesButton() {
6267
onNode(openSourceNoticesButton).performTouchInput { click() }
6368
}
6469

app/src/androidTest/java/com/mitteloupe/whoami/test/HistoryHighlightedIpAddressTest.kt

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,4 @@ class HistoryHighlightedIpAddressTest : BaseTest() {
5252
seeNonHighlightedRecord(ipAddress = ipAddress2, position = 2)
5353
}
5454
}
55-
56-
private fun HistoryScreen.seeRecord(
57-
position: Int,
58-
ipAddress: String,
59-
city: String,
60-
postCode: String
61-
) {
62-
seeIpRecord(ipAddress = ipAddress, position = position)
63-
seeLocation(city = city, postCode = postCode, position = position)
64-
}
6555
}

app/src/androidTest/java/com/mitteloupe/whoami/test/HistoryTest.kt

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ class HistoryTest : BaseTest() {
6363
)
6464
}
6565
seeRecord(position = 2, ipAddress = "1.1.1.1", city = "Aberdeen", postCode = "AA11 2BB")
66-
tapDeleteForRecord(position = 1)
66+
tapDeleteButtonForRecord(position = 1)
6767
retry(repeat = 20) {
6868
seeRecord(
6969
position = 1,
@@ -92,14 +92,4 @@ class HistoryTest : BaseTest() {
9292
}
9393
}
9494
}
95-
96-
private fun HistoryScreen.seeRecord(
97-
position: Int,
98-
ipAddress: String,
99-
city: String,
100-
postCode: String
101-
) {
102-
seeIpRecord(ipAddress = ipAddress, position = position)
103-
seeLocation(city = city, postCode = postCode, position = position)
104-
}
10595
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package com.mitteloupe.whoami.test
2+
3+
import androidx.compose.ui.test.ExperimentalTestApi
4+
import androidx.compose.ui.test.junit4.createAndroidComposeRule
5+
import com.mitteloupe.whoami.di.TestActivity
6+
import com.mitteloupe.whoami.launcher.fromScreen
7+
import com.mitteloupe.whoami.screen.HistoryScreen
8+
import com.mitteloupe.whoami.screen.HomeScreen
9+
import com.mitteloupe.whoami.server.REQUEST_RESPONSE_GET_IP
10+
import com.mitteloupe.whoami.server.REQUEST_RESPONSE_GET_IP_DETAILS
11+
import com.mitteloupe.whoami.test.annotation.ServerRequestResponse
12+
import com.mitteloupe.whoami.test.launcher.AppLauncher
13+
import com.mitteloupe.whoami.test.test.BaseTest
14+
import com.mitteloupe.whoami.test.test.retry
15+
import com.mitteloupe.whoami.ui.main.route.Home
16+
import dagger.hilt.android.testing.HiltAndroidTest
17+
import javax.inject.Inject
18+
import org.junit.Test
19+
20+
@HiltAndroidTest
21+
@ExperimentalTestApi
22+
class HomeSaveRecordTest : BaseTest() {
23+
override val composeTestRule = createAndroidComposeRule<TestActivity>()
24+
25+
override val startActivityLauncher: AppLauncher by lazy {
26+
fromScreen(composeTestRule, Home)
27+
}
28+
29+
@Inject
30+
lateinit var homeScreen: HomeScreen
31+
32+
@Inject
33+
lateinit var historyScreen: HistoryScreen
34+
35+
@Test
36+
@ServerRequestResponse([REQUEST_RESPONSE_GET_IP, REQUEST_RESPONSE_GET_IP_DETAILS])
37+
fun givenConnectedWhenNavigatingAwayAndBackThenSavesRecord() {
38+
with(composeTestRule) {
39+
with(homeScreen) {
40+
seeCityLabel()
41+
tapSaveDetailsButton()
42+
}
43+
44+
with(historyScreen) {
45+
retry(repeat = 20) {
46+
seeRecord(
47+
position = 1,
48+
ipAddress = "1.2.3.4",
49+
city = "Brentwood",
50+
postCode = "CM14"
51+
)
52+
}
53+
tapBackButton()
54+
}
55+
56+
with(homeScreen) {
57+
seeCityLabel()
58+
tapSaveDetailsButton()
59+
}
60+
61+
with(historyScreen) {
62+
retry(repeat = 20) {
63+
seeRecord(
64+
position = 1,
65+
ipAddress = "1.2.3.4",
66+
city = "Brentwood",
67+
postCode = "CM14"
68+
)
69+
}
70+
}
71+
}
72+
}
73+
}

app/src/androidTest/java/com/mitteloupe/whoami/test/HomeTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ class HomeTest : BaseTest() {
6565
Intents.init()
6666
with(composeTestRule) {
6767
with(homeScreen) {
68-
tapOpenSourceNotices()
68+
tapOpenSourceNoticesButton()
6969
}
7070

7171
with(openSourceNoticesScreen) {

app/src/main/java/com/mitteloupe/whoami/di/HomeUiModule.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import com.mitteloupe.whoami.architecture.ui.navigation.mapper.NavigationEventDe
77
import com.mitteloupe.whoami.home.presentation.navigation.HomePresentationNavigationEvent
88
import com.mitteloupe.whoami.home.presentation.viewmodel.HomeViewModel
99
import com.mitteloupe.whoami.home.ui.di.HomeDependencies
10+
import com.mitteloupe.whoami.home.ui.mapper.ConnectionDetailsPresentationMapper
1011
import com.mitteloupe.whoami.home.ui.mapper.ConnectionDetailsUiMapper
1112
import com.mitteloupe.whoami.home.ui.mapper.ErrorUiMapper
1213
import com.mitteloupe.whoami.home.ui.mapper.HomeNotificationUiMapper
@@ -39,13 +40,17 @@ object HomeUiModule {
3940
@Provides
4041
fun providesErrorUiMapper(resources: Resources) = ErrorUiMapper(resources)
4142

43+
@Provides
44+
fun providesConnectionDetailsPresentationMapper() = ConnectionDetailsPresentationMapper()
45+
4246
@Provides
4347
fun providesConnectionDetailsUiMapper() = ConnectionDetailsUiMapper()
4448

4549
@Provides
4650
fun providesHomeDependencies(
4751
homeViewModel: HomeViewModel,
4852
homeViewStateUiMapper: HomeViewStateUiMapper,
53+
connectionDetailsPresentationMapper: ConnectionDetailsPresentationMapper,
4954
connectionDetailsUiMapper: ConnectionDetailsUiMapper,
5055
homeNavigationMapper: @JvmSuppressWildcards
5156
NavigationEventDestinationMapper<HomePresentationNavigationEvent>,
@@ -55,6 +60,7 @@ object HomeUiModule {
5560
) = HomeDependencies(
5661
homeViewModel,
5762
homeViewStateUiMapper,
63+
connectionDetailsPresentationMapper,
5864
connectionDetailsUiMapper,
5965
homeNavigationMapper,
6066
homeNotificationMapper,

app/src/main/java/com/mitteloupe/whoami/ui/main/AppNavHost.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package com.mitteloupe.whoami.ui.main
22

33
import android.view.View
4+
import androidx.compose.foundation.layout.WindowInsets
45
import androidx.compose.foundation.layout.fillMaxSize
6+
import androidx.compose.foundation.layout.statusBars
7+
import androidx.compose.foundation.layout.windowInsetsPadding
58
import androidx.compose.runtime.Composable
69
import androidx.compose.runtime.getValue
710
import androidx.compose.runtime.mutableIntStateOf
@@ -39,7 +42,9 @@ fun AppNavHostDependencies.AppNavHost(
3942
val history: History = backStackEntry.toRoute()
4043
FragmentContainer(
4144
containerId = containerId,
42-
modifier = Modifier.fillMaxSize(),
45+
modifier = Modifier
46+
.fillMaxSize()
47+
.windowInsetsPadding(WindowInsets.statusBars),
4348
fragmentManager = supportFragmentManager,
4449
commit = { containerId ->
4550
replace(containerId, HistoryFragment.newInstance(history.highlightedIpAddress))

home/ui/src/main/java/com/mitteloupe/whoami/home/ui/di/HomeDependencies.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@ import com.mitteloupe.whoami.home.presentation.model.HomePresentationNotificatio
88
import com.mitteloupe.whoami.home.presentation.model.HomeViewState
99
import com.mitteloupe.whoami.home.presentation.navigation.HomePresentationNavigationEvent
1010
import com.mitteloupe.whoami.home.presentation.viewmodel.HomeViewModel
11+
import com.mitteloupe.whoami.home.ui.mapper.ConnectionDetailsPresentationMapper
1112
import com.mitteloupe.whoami.home.ui.mapper.ConnectionDetailsUiMapper
1213
import com.mitteloupe.whoami.home.ui.mapper.ErrorUiMapper
1314
import com.mitteloupe.whoami.home.ui.mapper.HomeViewStateUiMapper
1415

1516
data class HomeDependencies(
1617
val homeViewModel: HomeViewModel,
1718
val homeViewStateUiMapper: HomeViewStateUiMapper,
19+
val connectionDetailsPresentationMapper: ConnectionDetailsPresentationMapper,
1820
val connectionDetailsUiMapper: ConnectionDetailsUiMapper,
1921
private val homeNavigationMapper:
2022
NavigationEventDestinationMapper<HomePresentationNavigationEvent>,
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.mitteloupe.whoami.home.ui.mapper
2+
3+
import com.mitteloupe.whoami.home.presentation.model.HomeViewState
4+
import com.mitteloupe.whoami.home.ui.model.ConnectionDetailsUiModel
5+
import java.util.*
6+
7+
private val locales by lazy {
8+
Locale.getISOCountries().map { country -> Locale("en", country) }
9+
}
10+
11+
class ConnectionDetailsPresentationMapper {
12+
fun toPresentation(connectionDetails: ConnectionDetailsUiModel) = HomeViewState.Connected(
13+
ipAddress = connectionDetails.ipAddress,
14+
city = connectionDetails.cityIconLabel?.label,
15+
region = connectionDetails.regionIconLabel?.label,
16+
geolocation = connectionDetails.geolocationIconLabel?.label?.replace(", ", ","),
17+
postCode = connectionDetails.postCode?.label,
18+
timeZone = connectionDetails.timeZone?.label,
19+
internetServiceProviderName = connectionDetails.internetServiceProviderName?.label,
20+
countryCode = connectionDetails.countryIconLabel?.label?.let { countryName ->
21+
locales.firstOrNull { locale ->
22+
locale.displayCountry == countryName
23+
}
24+
}?.country
25+
)
26+
}

0 commit comments

Comments
 (0)