mirror of
https://github.com/bitfireAT/davx5-ose
synced 2024-09-06 18:01:11 +00:00
Tests for ConnectionUtils (bitfireAT/davx5#372)
* Add tests for internetAvailable() * Add tests for wifiAvailable() * Add TODO for test case * Add tests for internetAvailable() covering multiple network connections * Minor KDoc --------- Co-authored-by: Ricki Hirner <hirner@bitfire.at>
This commit is contained in:
parent
52e26e34d5
commit
464ba7d76e
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
|
||||
*/
|
||||
|
||||
package at.bitfire.davdroid.network
|
||||
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.Network
|
||||
import android.net.NetworkCapabilities
|
||||
import android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET
|
||||
import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN
|
||||
import android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED
|
||||
import android.net.NetworkCapabilities.TRANSPORT_WIFI
|
||||
import dagger.hilt.android.testing.HiltAndroidTest
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import junit.framework.TestCase.assertFalse
|
||||
import junit.framework.TestCase.assertTrue
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
|
||||
@HiltAndroidTest
|
||||
class ConnectionUtilsTest {
|
||||
|
||||
private val connectivityManager = mockk<ConnectivityManager>()
|
||||
private val network1 = mockk<Network>()
|
||||
private val network2 = mockk<Network>()
|
||||
private val capabilities = mockk<NetworkCapabilities>()
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
every { connectivityManager.allNetworks } returns arrayOf(network1, network2)
|
||||
every { connectivityManager.getNetworkInfo(network1) } returns mockk()
|
||||
every { connectivityManager.getNetworkInfo(network2) } returns mockk()
|
||||
every { connectivityManager.getNetworkCapabilities(network1) } returns capabilities
|
||||
every { connectivityManager.getNetworkCapabilities(network2) } returns capabilities
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testWifiAvailable_capabilitiesNull() {
|
||||
every { connectivityManager.getNetworkCapabilities(network1) } returns null
|
||||
every { connectivityManager.getNetworkCapabilities(network2) } returns null
|
||||
assertFalse(ConnectionUtils.wifiAvailable(connectivityManager))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testWifiAvailable() {
|
||||
every { capabilities.hasTransport(TRANSPORT_WIFI) } returns false
|
||||
every { capabilities.hasCapability(NET_CAPABILITY_VALIDATED) } returns false
|
||||
assertFalse(ConnectionUtils.wifiAvailable(connectivityManager))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testWifiAvailable_wifi() {
|
||||
every { capabilities.hasTransport(TRANSPORT_WIFI) } returns true
|
||||
every { capabilities.hasCapability(NET_CAPABILITY_VALIDATED) } returns false
|
||||
assertFalse(ConnectionUtils.wifiAvailable(connectivityManager))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testWifiAvailable_validated() {
|
||||
every { capabilities.hasTransport(TRANSPORT_WIFI) } returns false
|
||||
every { capabilities.hasCapability(NET_CAPABILITY_VALIDATED) } returns true
|
||||
assertFalse(ConnectionUtils.wifiAvailable(connectivityManager))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testWifiAvailable_wifiValidated() {
|
||||
every { capabilities.hasTransport(TRANSPORT_WIFI) } returns true
|
||||
every { capabilities.hasCapability(NET_CAPABILITY_VALIDATED) } returns true
|
||||
assertTrue(ConnectionUtils.wifiAvailable(connectivityManager))
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun testInternetAvailable_capabilitiesNull() {
|
||||
every { connectivityManager.getNetworkCapabilities(network1) } returns null
|
||||
every { connectivityManager.getNetworkCapabilities(network2) } returns null
|
||||
assertFalse(ConnectionUtils.internetAvailable(connectivityManager, false))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testInternetAvailable_Internet() {
|
||||
every { capabilities.hasCapability(NET_CAPABILITY_INTERNET) } returns true
|
||||
every { capabilities.hasCapability(NET_CAPABILITY_VALIDATED) } returns false
|
||||
assertFalse(ConnectionUtils.internetAvailable(connectivityManager, false))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testInternetAvailable_Validated() {
|
||||
every { capabilities.hasCapability(NET_CAPABILITY_INTERNET) } returns false
|
||||
every { capabilities.hasCapability(NET_CAPABILITY_VALIDATED) } returns true
|
||||
assertFalse(ConnectionUtils.internetAvailable(connectivityManager, false))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testInternetAvailable_InternetValidated() {
|
||||
every { capabilities.hasCapability(NET_CAPABILITY_INTERNET) } returns true
|
||||
every { capabilities.hasCapability(NET_CAPABILITY_VALIDATED) } returns true
|
||||
assertTrue(ConnectionUtils.internetAvailable(connectivityManager, false))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testInternetAvailable_ignoreVpns() {
|
||||
every { capabilities.hasCapability(NET_CAPABILITY_INTERNET) } returns true
|
||||
every { capabilities.hasCapability(NET_CAPABILITY_VALIDATED) } returns true
|
||||
every { capabilities.hasCapability(NET_CAPABILITY_NOT_VPN) } returns false
|
||||
assertFalse(ConnectionUtils.internetAvailable(connectivityManager, true))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testInternetAvailable_ignoreVpns_Notvpn() {
|
||||
every { capabilities.hasCapability(NET_CAPABILITY_INTERNET) } returns true
|
||||
every { capabilities.hasCapability(NET_CAPABILITY_VALIDATED) } returns true
|
||||
every { capabilities.hasCapability(NET_CAPABILITY_NOT_VPN) } returns true
|
||||
assertTrue(ConnectionUtils.internetAvailable(connectivityManager, true))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testInternetAvailable_twoConnectionsFirstOneWithoutInternet() {
|
||||
// The real case that failed in davx5-ose#395 is that the connection list contains (in this order)
|
||||
// 1. a mobile network without INTERNET, but with VALIDATED
|
||||
// 2. a WiFi network with INTERNET and VALIDATED
|
||||
|
||||
// The "return false" of hasINTERNET will trigger at the first connection, the
|
||||
// "andThen true" will trigger for the second connection
|
||||
every { capabilities.hasCapability(NET_CAPABILITY_INTERNET) } returns false andThen true
|
||||
every { capabilities.hasCapability(NET_CAPABILITY_VALIDATED) } returns true
|
||||
|
||||
// There is an internet connection if any(!) connection has both INTERNET and VALIDATED.
|
||||
assertTrue(ConnectionUtils.internetAvailable(connectivityManager, false))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testInternetAvailable_twoConnectionsFirstOneWithoutValidated() {
|
||||
every { capabilities.hasCapability(NET_CAPABILITY_INTERNET) } returns true
|
||||
every { capabilities.hasCapability(NET_CAPABILITY_VALIDATED) } returns false andThen true
|
||||
assertTrue(ConnectionUtils.internetAvailable(connectivityManager, false))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testInternetAvailable_twoConnectionsFirstOneWithoutNotvpn() {
|
||||
every { capabilities.hasCapability(NET_CAPABILITY_INTERNET) } returns true
|
||||
every { capabilities.hasCapability(NET_CAPABILITY_VALIDATED) } returns true
|
||||
every { capabilities.hasCapability(NET_CAPABILITY_NOT_VPN) } returns false andThen true
|
||||
assertTrue(ConnectionUtils.internetAvailable(connectivityManager, true))
|
||||
}
|
||||
|
||||
}
|
|
@ -4,21 +4,18 @@
|
|||
|
||||
package at.bitfire.davdroid.network
|
||||
|
||||
import android.content.Context
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.NetworkCapabilities
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.core.content.getSystemService
|
||||
import at.bitfire.davdroid.log.Logger
|
||||
import java.util.logging.Level
|
||||
|
||||
object ConnectionUtils {
|
||||
|
||||
/**
|
||||
* Checks whether we are connected to working WiFi
|
||||
* Checks whether we are connected to validated WiFi
|
||||
*/
|
||||
internal fun wifiAvailable(context: Context): Boolean {
|
||||
val connectivityManager = context.getSystemService<ConnectivityManager>()!!
|
||||
internal fun wifiAvailable(connectivityManager: ConnectivityManager): Boolean {
|
||||
connectivityManager.allNetworks.forEach { network ->
|
||||
connectivityManager.getNetworkCapabilities(network)?.let { capabilities ->
|
||||
if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) &&
|
||||
|
@ -33,7 +30,7 @@ object ConnectionUtils {
|
|||
* Checks whether we are connected to the Internet.
|
||||
*
|
||||
* On API 26+ devices, if a VPN is used, WorkManager might start the SyncWorker without an
|
||||
* internet connection (because NET_CAPABILITY_VALIDATED is always set for VPN connections).
|
||||
* Internet connection (because [NetworkCapabilities.NET_CAPABILITY_VALIDATED] is always set for VPN connections).
|
||||
* To prevent the start without internet access, we don't check for VPN connections by default
|
||||
* (by using [NetworkCapabilities.NET_CAPABILITY_NOT_VPN]).
|
||||
*
|
||||
|
@ -44,8 +41,7 @@ object ConnectionUtils {
|
|||
* @return whether we are connected to the Internet
|
||||
*/
|
||||
@RequiresApi(23)
|
||||
internal fun internetAvailable(context: Context, ignoreVpns: Boolean): Boolean {
|
||||
val connectivityManager = context.getSystemService<ConnectivityManager>()!!
|
||||
internal fun internetAvailable(connectivityManager: ConnectivityManager, ignoreVpns: Boolean): Boolean {
|
||||
return connectivityManager.allNetworks.any { network ->
|
||||
val capabilities = connectivityManager.getNetworkCapabilities(network)
|
||||
Logger.log.log(Level.FINE, "Looking for validated Internet over this connection.",
|
||||
|
|
|
@ -10,6 +10,7 @@ import android.content.ContentResolver
|
|||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.SyncResult
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.wifi.WifiManager
|
||||
import android.os.Build
|
||||
import android.provider.CalendarContract
|
||||
|
@ -254,7 +255,8 @@ class SyncWorker @AssistedInject constructor(
|
|||
return true // yes, continue
|
||||
|
||||
// WiFi required, is it available?
|
||||
if (!wifiAvailable(context)) {
|
||||
val connectivityManager = context.getSystemService<ConnectivityManager>()!!
|
||||
if (!wifiAvailable(connectivityManager)) {
|
||||
Logger.log.info("Not on connected WiFi, stopping")
|
||||
return false
|
||||
}
|
||||
|
@ -282,7 +284,8 @@ class SyncWorker @AssistedInject constructor(
|
|||
|
||||
// Check internet connection
|
||||
val ignoreVpns = AccountSettings(applicationContext, account).getIgnoreVpns()
|
||||
if (Build.VERSION.SDK_INT >= 23 && !internetAvailable(applicationContext, ignoreVpns)) {
|
||||
val connectivityManager = applicationContext.getSystemService<ConnectivityManager>()!!
|
||||
if (Build.VERSION.SDK_INT >= 23 && !internetAvailable(connectivityManager, ignoreVpns)) {
|
||||
Logger.log.info("WorkManager started SyncWorker without Internet connection. Aborting.")
|
||||
return Result.failure()
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue