Skip to content

Commit

Permalink
Improve NetworkHelper readability & unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
1ud0v1c committed Oct 10, 2023
1 parent ded7d1a commit 63c1681
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,37 +10,31 @@ import android.os.Build
* @see: https://developer.android.com/training/monitoring-device-state/connectivity-status-type
*/
object NetworkHelper {

fun isOnline(context: Context): Boolean {
val connectivityManager: ConnectivityManager? =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager?
connectivityManager?.let {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
it.getNetworkCapabilities(it.activeNetwork)?.run {
return when {
hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> {
true
}
hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> {
true
}
hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> {
true
}
else -> {
false
}
}
}
} else {
it.activeNetworkInfo?.run {
if (type == ConnectivityManager.TYPE_WIFI) {
return true
} else if (type == ConnectivityManager.TYPE_MOBILE) {
return true
}
}
val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as? ConnectivityManager
if (connectivityManager == null) return false

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
val networkInfo = connectivityManager.activeNetworkInfo
if (networkInfo == null) return false

return when (networkInfo.type) {
ConnectivityManager.TYPE_WIFI -> true
ConnectivityManager.TYPE_MOBILE -> true
else -> false
}
}
return false

val networkCapabilities = connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
if (networkCapabilities == null) return false

return when {
networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
else -> false
}
}

}
37 changes: 26 additions & 11 deletions app/src/test/java/com/ludovic/vimont/nasaapod/NetworkMock.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,35 @@ object NetworkMock {
return context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
}

fun mockNetworkAccess(context: Context) {
fun mockNetworkAccess(context: Context, shouldBeConnected: Boolean) {
val connectivityManager: ConnectivityManager = getConnectivityManager(context)
val shadowConnectivityManager = Shadows.shadowOf(connectivityManager)
val networkInfo: NetworkInfo = ShadowNetworkInfo.newInstance(
NetworkInfo.DetailedState.CONNECTED,
ConnectivityManager.TYPE_WIFI,
0,
false,
NetworkInfo.State.CONNECTED
)
val network: Network = ShadowNetwork.newInstance(1)
val networkCapabilities: NetworkCapabilities = ShadowNetworkCapabilities.newInstance()
Shadows.shadowOf(networkCapabilities).addTransportType(NetworkCapabilities.TRANSPORT_WIFI)

val networkInfo = if (shouldBeConnected) {
ShadowNetworkInfo.newInstance(
/* detailedState = */ NetworkInfo.DetailedState.CONNECTED,
/* type = */ ConnectivityManager.TYPE_WIFI,
/* subType = */ 0,
/* isAvailable = */ false,
/* state = */ NetworkInfo.State.CONNECTED
)
} else {
ShadowNetworkInfo.newInstance(
/* detailedState = */ NetworkInfo.DetailedState.DISCONNECTED,
/* type = */ ConnectivityManager.TYPE_WIFI,
/* subType = */ 0,
/* isAvailable = */ false,
/* state = */ NetworkInfo.State.DISCONNECTED
)
}
shadowConnectivityManager.setActiveNetworkInfo(networkInfo)

val network = ShadowNetwork.newInstance(1)
val networkCapabilities: NetworkCapabilities = ShadowNetworkCapabilities.newInstance()
if (shouldBeConnected) {
Shadows.shadowOf(networkCapabilities).addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
}
shadowConnectivityManager.setNetworkCapabilities(network, networkCapabilities)
}

}
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
package com.ludovic.vimont.nasaapod.helper.network

import android.content.Context
import android.os.Looper.getMainLooper
import androidx.test.core.app.ApplicationProvider
import com.ludovic.vimont.nasaapod.NetworkMock
import org.junit.After
import org.junit.Assert
import org.junit.Test
import org.junit.runner.RunWith
import org.koin.core.context.GlobalContext
import org.koin.test.KoinTest
import org.robolectric.RobolectricTestRunner
import org.robolectric.Shadows.shadowOf
import kotlin.test.assertFalse
import kotlin.test.assertTrue

@RunWith(RobolectricTestRunner::class)
class NetworkHelperTest : KoinTest {
Expand All @@ -23,10 +22,33 @@ class NetworkHelperTest : KoinTest {
}

@Test
fun testIsOnline() {
shadowOf(getMainLooper()).idle()
Assert.assertTrue(NetworkHelper.isOnline(context))
NetworkMock.mockNetworkAccess(context)
Assert.assertTrue(NetworkHelper.isOnline(context))
fun `isOnline should return true, if the network is available`() {
// Given
NetworkMock.mockNetworkAccess(
context = context,
shouldBeConnected = true,
)

// When
val isOnline = NetworkHelper.isOnline(context)

// Then
assertTrue(isOnline)
}

@Test
fun `isOnline should return false, if the network cannot be reached`() {
// Given
NetworkMock.mockNetworkAccess(
context = context,
shouldBeConnected = false,
)

// When
val isOnline = NetworkHelper.isOnline(context)

// Then
assertFalse(isOnline)
}

}

0 comments on commit 63c1681

Please sign in to comment.