Skip to content

Commit 2576f9d

Browse files
authored
Moved data source output merging logic to repository. (#368)
1 parent 2404237 commit 2576f9d

File tree

4 files changed

+84
-123
lines changed

4 files changed

+84
-123
lines changed

home/data/src/main/java/com/mitteloupe/whoami/home/data/mapper/ConnectionDetailsDomainResolver.kt

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,17 @@ import com.mitteloupe.whoami.datasource.connection.model.ConnectionStateDataMode
44
import com.mitteloupe.whoami.datasource.connection.model.ConnectionStateDataModel.Connected
55
import com.mitteloupe.whoami.datasource.connection.model.ConnectionStateDataModel.Disconnected
66
import com.mitteloupe.whoami.datasource.connection.model.ConnectionStateDataModel.Unset
7-
import com.mitteloupe.whoami.datasource.ipaddressinformation.exception.NoIpAddressInformationDataException
87
import com.mitteloupe.whoami.datasource.ipaddressinformation.model.IpAddressInformationDataModel
98
import com.mitteloupe.whoami.home.domain.model.ConnectionDetailsDomainModel
109

1110
class ConnectionDetailsDomainResolver {
1211
fun toDomain(
1312
connectionState: ConnectionStateDataModel,
14-
ipAddressProvider: () -> String,
15-
ipAddressInformationProvider: (ipAddress: String) -> IpAddressInformationDataModel
13+
ipAddress: String?,
14+
ipAddressInformation: IpAddressInformationDataModel?
1615
): ConnectionDetailsDomainModel = when (connectionState) {
1716
Connected -> {
18-
val ipAddress = ipAddressProvider()
19-
val ipAddressInformation = try {
20-
ipAddressInformationProvider(ipAddress)
21-
} catch (_: NoIpAddressInformationDataException) {
22-
null
23-
}
17+
requireNotNull(ipAddress)
2418
ConnectionDetailsDomainModel.Connected(
2519
ipAddress = ipAddress,
2620
city = ipAddressInformation?.city,

home/data/src/main/java/com/mitteloupe/whoami/home/data/repository/ConnectionDetailsRepository.kt

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
package com.mitteloupe.whoami.home.data.repository
22

33
import com.mitteloupe.whoami.datasource.connection.datasource.ConnectionDataSource
4+
import com.mitteloupe.whoami.datasource.connection.model.ConnectionStateDataModel.Connected
5+
import com.mitteloupe.whoami.datasource.connection.model.ConnectionStateDataModel.Disconnected
6+
import com.mitteloupe.whoami.datasource.connection.model.ConnectionStateDataModel.Unset
47
import com.mitteloupe.whoami.datasource.ipaddress.datasource.IpAddressDataSource
58
import com.mitteloupe.whoami.datasource.ipaddressinformation.datasource.IpAddressInformationDataSource
9+
import com.mitteloupe.whoami.datasource.ipaddressinformation.exception.NoIpAddressInformationDataException
610
import com.mitteloupe.whoami.home.data.mapper.ConnectionDetailsDomainResolver
711
import com.mitteloupe.whoami.home.data.mapper.ThrowableDomainMapper
812
import com.mitteloupe.whoami.home.domain.model.ConnectionDetailsDomainModel
@@ -23,13 +27,21 @@ class ConnectionDetailsRepository(
2327
private val throwableDomainMapper: ThrowableDomainMapper
2428
) : GetConnectionDetailsRepository {
2529
override fun connectionDetails(): Flow<ConnectionDetailsDomainModel> =
26-
connectionDataSource.observeIsConnected().map { connected ->
30+
connectionDataSource.observeIsConnected().map { connectionState ->
31+
val (optionalIpAddress, ipAddressInformation) = when (connectionState) {
32+
Connected -> {
33+
val ipAddress = ipAddressDataSource.ipAddress()
34+
ipAddress to try {
35+
ipAddressInformationDataSource.ipAddressInformation(ipAddress)
36+
} catch (_: NoIpAddressInformationDataException) {
37+
null
38+
}
39+
}
40+
41+
Disconnected, Unset -> null to null
42+
}
2743
connectionDetailsDomainResolver
28-
.toDomain(
29-
connected,
30-
{ ipAddressDataSource.ipAddress() },
31-
ipAddressInformationDataSource::ipAddressInformation
32-
)
44+
.toDomain(connectionState, optionalIpAddress, ipAddressInformation)
3345
}.retryWhen { cause, _ ->
3446
emit(Error(throwableDomainMapper.toDomain(cause)))
3547
delay(RETRY_DELAY_MILLISECONDS)

home/data/src/test/java/com/mitteloupe/whoami/home/data/mapper/ConnectionDetailsDomainResolverTest.kt

Lines changed: 22 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import com.mitteloupe.whoami.datasource.connection.model.ConnectionStateDataMode
44
import com.mitteloupe.whoami.datasource.connection.model.ConnectionStateDataModel.Connected
55
import com.mitteloupe.whoami.datasource.connection.model.ConnectionStateDataModel.Disconnected
66
import com.mitteloupe.whoami.datasource.connection.model.ConnectionStateDataModel.Unset
7-
import com.mitteloupe.whoami.datasource.ipaddressinformation.exception.NoIpAddressInformationDataException
87
import com.mitteloupe.whoami.datasource.ipaddressinformation.model.IpAddressInformationDataModel
98
import com.mitteloupe.whoami.home.domain.model.ConnectionDetailsDomainModel
109
import org.junit.Assert.assertEquals
@@ -20,7 +19,7 @@ private const val IP_ADDRESS = "1.2.3.4"
2019
class ConnectionDetailsDomainResolverTest(
2120
@Suppress("unused") private val testTitle: String,
2221
private val connectionState: ConnectionStateDataModel,
23-
private val ipAddressInformationProvider: (String) -> IpAddressInformationDataModel,
22+
private val ipAddressInformation: IpAddressInformationDataModel,
2423
private val expectedDomainModel: ConnectionDetailsDomainModel
2524
) {
2625
companion object {
@@ -47,21 +46,6 @@ class ConnectionDetailsDomainResolverTest(
4746
postCode = "E17 1CO",
4847
timeZone = "GMT"
4948
),
50-
testCase(
51-
testTitle = "connected with information exception",
52-
connectionState = Connected,
53-
ipAddressInformationProvider = { throw NoIpAddressInformationDataException() },
54-
expectedDomainModel = ConnectionDetailsDomainModel.Connected(
55-
ipAddress = IP_ADDRESS,
56-
city = null,
57-
region = null,
58-
countryCode = null,
59-
geolocation = null,
60-
internetServiceProviderName = null,
61-
postCode = null,
62-
timeZone = null
63-
)
64-
),
6549
testCase(
6650
testTitle = "disconnected",
6751
connectionState = Disconnected,
@@ -86,18 +70,15 @@ class ConnectionDetailsDomainResolverTest(
8670
) = testCase(
8771
"connected with $testTitle",
8872
Connected,
89-
{ ipAddress ->
90-
assertEquals(IP_ADDRESS, ipAddress)
91-
IpAddressInformationDataModel(
92-
city = city,
93-
region = region,
94-
country = countryCode,
95-
geolocation = geolocation,
96-
internetServiceProviderName = internetServiceProviderName,
97-
postCode = postCode,
98-
timeZone = timeZone
99-
)
100-
},
73+
IpAddressInformationDataModel(
74+
city = city,
75+
region = region,
76+
country = countryCode,
77+
geolocation = geolocation,
78+
internetServiceProviderName = internetServiceProviderName,
79+
postCode = postCode,
80+
timeZone = timeZone
81+
),
10182
ConnectionDetailsDomainModel.Connected(
10283
ipAddress = IP_ADDRESS,
10384
city = city,
@@ -113,37 +94,38 @@ class ConnectionDetailsDomainResolverTest(
11394
private fun testCase(
11495
testTitle: String,
11596
connectionState: ConnectionStateDataModel,
116-
ipAddressInformationProvider: (String) -> IpAddressInformationDataModel = {
117-
throw UnsupportedOperationException("No attempt to fetch information was expected")
118-
},
97+
ipAddressInformation: IpAddressInformationDataModel = IpAddressInformationDataModel(
98+
city = null,
99+
region = null,
100+
country = null,
101+
geolocation = null,
102+
internetServiceProviderName = null,
103+
postCode = null,
104+
timeZone = null
105+
),
119106
expectedDomainModel: ConnectionDetailsDomainModel
120107
) = arrayOf(
121108
testTitle,
122109
connectionState,
123-
ipAddressInformationProvider,
110+
ipAddressInformation,
124111
expectedDomainModel
125112
)
126113
}
127114

128115
private lateinit var classUnderTest: ConnectionDetailsDomainResolver
129116

130-
private lateinit var ipAddressProvider: () -> String
131-
132117
@Before
133118
fun setUp() {
134119
classUnderTest = ConnectionDetailsDomainResolver()
135120
}
136121

137122
@Test
138123
fun `When toDomain`() {
139-
// Given
140-
ipAddressProvider = { IP_ADDRESS }
141-
142124
// When
143125
val actualValue = classUnderTest.toDomain(
144126
connectionState,
145-
ipAddressProvider,
146-
ipAddressInformationProvider
127+
IP_ADDRESS,
128+
ipAddressInformation
147129
)
148130

149131
// Then

home/data/src/test/java/com/mitteloupe/whoami/home/data/repository/ConnectionDetailsRepositoryTest.kt

Lines changed: 41 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,16 @@ import org.junit.Assert.assertEquals
1919
import org.junit.Before
2020
import org.junit.Test
2121

22+
private val defaultIpAddressInformation = IpAddressInformationDataModel(
23+
city = "Paris",
24+
region = "Paris",
25+
country = "France",
26+
geolocation = "0.0,0.0",
27+
internetServiceProviderName = "Le ISP",
28+
postCode = "12345",
29+
timeZone = "GMT +1"
30+
)
31+
2232
class ConnectionDetailsRepositoryTest {
2333
private lateinit var classUnderTest: ConnectionDetailsRepository
2434

@@ -54,13 +64,9 @@ class ConnectionDetailsRepositoryTest {
5464
fun `Given unset connection when connectionDetails then returns unset state`() = runBlocking {
5565
// Given
5666
val givenState = ConnectionStateDataModel.Unset
57-
every { connectionDataSource.observeIsConnected() } returns flow {
58-
emit(givenState)
59-
}
67+
givenConnectionState(givenState)
6068
val expectedState = ConnectionDetailsDomainModel.Unset
61-
every {
62-
connectionDetailsDomainResolver.toDomain(eq(givenState), any(), any())
63-
} returns expectedState
69+
givenConnectionDetailsDomainResolverMaps(givenState, expectedState)
6470

6571
// When
6672
val actualValue = classUnderTest.connectionDetails().toList()
@@ -74,13 +80,9 @@ class ConnectionDetailsRepositoryTest {
7480
runBlocking {
7581
// Given
7682
val givenState = ConnectionStateDataModel.Disconnected
77-
every { connectionDataSource.observeIsConnected() } returns flow {
78-
emit(givenState)
79-
}
83+
givenConnectionState(givenState)
8084
val expectedState = ConnectionDetailsDomainModel.Disconnected
81-
every {
82-
connectionDetailsDomainResolver.toDomain(eq(givenState), any(), any())
83-
} returns expectedState
85+
givenConnectionDetailsDomainResolverMaps(givenState, expectedState)
8486

8587
// When
8688
val actualValue = classUnderTest.connectionDetails().toList()
@@ -93,11 +95,14 @@ class ConnectionDetailsRepositoryTest {
9395
fun `Given connected when connectionDetails then returns connected state`() = runBlocking {
9496
// Given
9597
val givenState = ConnectionStateDataModel.Connected
96-
every { connectionDataSource.observeIsConnected() } returns flow {
97-
emit(givenState)
98-
}
98+
givenConnectionState(givenState)
99+
val givenIpAddress = "1.2.3.4"
100+
givenIpAddress(givenIpAddress)
101+
every {
102+
ipAddressInformationDataSource.ipAddressInformation(givenIpAddress)
103+
} returns defaultIpAddressInformation
99104
val expectedState = ConnectionDetailsDomainModel.Connected(
100-
ipAddress = "1.2.3.4",
105+
ipAddress = givenIpAddress,
101106
city = "Paris",
102107
region = "Paris",
103108
countryCode = "France",
@@ -107,20 +112,7 @@ class ConnectionDetailsRepositoryTest {
107112
timeZone = "GMT +1"
108113
)
109114

110-
val ipAddress = "1.1.1.1"
111-
112-
every {
113-
connectionDetailsDomainResolver.toDomain(eq(givenState), any(), any())
114-
} answers { call ->
115-
@Suppress("UNCHECKED_CAST")
116-
testIpAddressReadCorrectly(ipAddress, call.invocation.args[1] as () -> String)
117-
@Suppress("UNCHECKED_CAST")
118-
testConnectionDetailsReadCorrectly(
119-
ipAddress,
120-
call.invocation.args[2] as (String) -> IpAddressInformationDataModel
121-
)
122-
expectedState
123-
}
115+
givenConnectionDetailsDomainResolverMaps(givenState, expectedState)
124116

125117
// When
126118
val actualValue = classUnderTest.connectionDetails().toList()
@@ -134,15 +126,16 @@ class ConnectionDetailsRepositoryTest {
134126
runBlocking {
135127
// Given
136128
val givenState = ConnectionStateDataModel.Connected
137-
every { connectionDataSource.observeIsConnected() } returns flow {
138-
emit(givenState)
139-
}
129+
givenConnectionState(givenState)
130+
val givenIpAddress = "1.1.1.1"
131+
givenIpAddress(givenIpAddress)
140132
val throwable = Throwable()
133+
every {
134+
ipAddressInformationDataSource.ipAddressInformation(givenIpAddress)
135+
} throws throwable andThen defaultIpAddressInformation
141136

142137
val expectedState2 = ConnectionDetailsDomainModel.Disconnected
143-
every {
144-
connectionDetailsDomainResolver.toDomain(eq(givenState), any(), any())
145-
} throws throwable andThen expectedState2
138+
givenConnectionDetailsDomainResolverMaps(givenState, expectedState2)
146139

147140
val expectedDomainException = UnknownDomainException(throwable)
148141
every { throwableDomainMapper.toDomain(throwable) } returns expectedDomainException
@@ -155,42 +148,22 @@ class ConnectionDetailsRepositoryTest {
155148
assertEquals(listOf(expectedState1, expectedState2), actualValue)
156149
}
157150

158-
private fun testIpAddressReadCorrectly(
159-
expectedIpAddress: String,
160-
ipAddressProvider: () -> String
161-
) {
162-
// Given
163-
every { ipAddressDataSource.ipAddress() } returns expectedIpAddress
164-
165-
// When
166-
val actualIpAddress = ipAddressProvider()
167-
168-
// Then
169-
assertEquals(expectedIpAddress, actualIpAddress)
151+
private fun givenConnectionState(givenState: ConnectionStateDataModel) {
152+
every { connectionDataSource.observeIsConnected() } returns flow {
153+
emit(givenState)
154+
}
170155
}
171156

172-
private fun testConnectionDetailsReadCorrectly(
173-
ipAddress: String,
174-
ipAddressInformationProvider: (String) -> IpAddressInformationDataModel
157+
private fun givenConnectionDetailsDomainResolverMaps(
158+
givenState: ConnectionStateDataModel,
159+
expectedState: ConnectionDetailsDomainModel
175160
) {
176-
// Given
177-
val expectedIpAddressInformation = IpAddressInformationDataModel(
178-
city = "Paris",
179-
region = "Paris",
180-
country = "France",
181-
geolocation = "0.0,0.0",
182-
internetServiceProviderName = "Le ISP",
183-
postCode = "12345",
184-
timeZone = "GMT +1"
185-
)
186161
every {
187-
ipAddressInformationDataSource.ipAddressInformation(ipAddress)
188-
} returns expectedIpAddressInformation
189-
190-
// When
191-
val actualIpAddressInformation = ipAddressInformationProvider(ipAddress)
162+
connectionDetailsDomainResolver.toDomain(eq(givenState), any(), any())
163+
} returns expectedState
164+
}
192165

193-
// Then
194-
assertEquals(expectedIpAddressInformation, actualIpAddressInformation)
166+
private fun givenIpAddress(givenIpAddress: String) {
167+
every { ipAddressDataSource.ipAddress() } returns givenIpAddress
195168
}
196169
}

0 commit comments

Comments
 (0)