From e91fd008362537882c75f4a27199bb38257b25b3 Mon Sep 17 00:00:00 2001 From: "Markus M. May" Date: Tue, 1 May 2018 21:46:37 +0200 Subject: [PATCH] Add Unit-Test, as well as fixtures for SSID handling --- .../androidaps/events/EventNetworkChange.java | 6 +- .../NSClientInternal/NSClientPlugin.java | 138 ++++-------------- .../NsClientReceiverDelegate.java | 132 +++++++++++++++++ .../services/NSClientService.java | 2 +- .../NsClientReceiverDelegateTest.java | 115 +++++++++++++++ 5 files changed, 282 insertions(+), 111 deletions(-) create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NsClientReceiverDelegate.java create mode 100644 app/src/test/java/info/nightscout/androidaps/plugins/NSClientInternal/NsClientReceiverDelegateTest.java diff --git a/app/src/main/java/info/nightscout/androidaps/events/EventNetworkChange.java b/app/src/main/java/info/nightscout/androidaps/events/EventNetworkChange.java index ed639d643d..03df71f31b 100644 --- a/app/src/main/java/info/nightscout/androidaps/events/EventNetworkChange.java +++ b/app/src/main/java/info/nightscout/androidaps/events/EventNetworkChange.java @@ -5,6 +5,10 @@ public class EventNetworkChange extends Event { public boolean mobileConnected = false; public boolean wifiConnected = false; - public String ssid; + public String ssid = ""; public boolean roaming = false; + + public String getSsid() { + return ssid.replace("SSID: ","").replaceAll("\"",""); + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientPlugin.java index 8a19834ca5..4e65e46a0f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientPlugin.java @@ -3,11 +3,7 @@ package info.nightscout.androidaps.plugins.NSClientInternal; import android.content.ComponentName; import android.content.Context; import android.content.Intent; -import android.content.IntentFilter; import android.content.ServiceConnection; -import android.net.ConnectivityManager; -import android.net.wifi.WifiManager; -import android.os.BatteryManager; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; @@ -37,8 +33,6 @@ import info.nightscout.androidaps.plugins.NSClientInternal.events.EventNSClientN import info.nightscout.androidaps.plugins.NSClientInternal.events.EventNSClientStatus; import info.nightscout.androidaps.plugins.NSClientInternal.events.EventNSClientUpdateGUI; import info.nightscout.androidaps.plugins.NSClientInternal.services.NSClientService; -import info.nightscout.androidaps.receivers.ChargingStateReceiver; -import info.nightscout.androidaps.receivers.NetworkChangeReceiver; import info.nightscout.utils.SP; import info.nightscout.utils.ToastUtils; @@ -60,17 +54,13 @@ public class NSClientPlugin extends PluginBase { Spanned textLog = Html.fromHtml(""); public boolean paused = false; - public boolean allowed = true; - public boolean allowedChargingsState = true; - public boolean allowedNetworkState = true; boolean autoscroll = true; public String status = ""; public NSClientService nsClientService = null; - private NetworkChangeReceiver networkChangeReceiver = new NetworkChangeReceiver(); - private ChargingStateReceiver chargingStateReceiver = new ChargingStateReceiver(); + private NsClientReceiverDelegate nsClientReceiverDelegate; private NSClientPlugin() { super(new PluginDescription() @@ -92,8 +82,16 @@ public class NSClientPlugin extends PluginBase { handlerThread.start(); handler = new Handler(handlerThread.getLooper()); } + + nsClientReceiverDelegate = + new NsClientReceiverDelegate(MainApp.instance().getApplicationContext(), MainApp.bus()); } + public boolean isAllowed() { + return nsClientReceiverDelegate.allowed; + } + + @Override protected void onStart() { MainApp.bus().register(this); @@ -102,32 +100,7 @@ public class NSClientPlugin extends PluginBase { context.bindService(intent, mConnection, Context.BIND_AUTO_CREATE); super.onStart(); - registerReceivers(); - - } - - protected void registerReceivers() { - Context context = MainApp.instance().getApplicationContext(); - // register NetworkChangeReceiver --> https://developer.android.com/training/monitoring-device-state/connectivity-monitoring.html - // Nougat is not providing Connectivity-Action anymore ;-( - context.registerReceiver(networkChangeReceiver, - new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); - context.registerReceiver(networkChangeReceiver, - new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION)); - - EventNetworkChange event = networkChangeReceiver.grabNetworkStatus(context); - if (event != null) - MainApp.bus().post(event); - - context.registerReceiver(chargingStateReceiver, - new IntentFilter(Intent.ACTION_POWER_CONNECTED)); - context.registerReceiver(chargingStateReceiver, - new IntentFilter(Intent.ACTION_POWER_DISCONNECTED)); - - EventChargingState eventChargingState = chargingStateReceiver.grabChargingState(context); - if (eventChargingState != null) - MainApp.bus().post(eventChargingState); - + nsClientReceiverDelegate.registerReceivers(); } @Override @@ -135,10 +108,26 @@ public class NSClientPlugin extends PluginBase { MainApp.bus().unregister(this); Context context = MainApp.instance().getApplicationContext(); context.unbindService(mConnection); - context.unregisterReceiver(networkChangeReceiver); - context.unregisterReceiver(chargingStateReceiver); + + nsClientReceiverDelegate.unregisterReceivers(); } + @Subscribe + public void onStatusEvent(EventPreferenceChange ev) { + nsClientReceiverDelegate.onStatusEvent(ev); + } + + @Subscribe + public void onStatusEvent(final EventChargingState ev) { + nsClientReceiverDelegate.onStatusEvent(ev); + } + + @Subscribe + public void onStatusEvent(final EventNetworkChange ev) { + nsClientReceiverDelegate.onStatusEvent(ev); + } + + private ServiceConnection mConnection = new ServiceConnection() { public void onServiceDisconnected(ComponentName name) { @@ -154,81 +143,12 @@ public class NSClientPlugin extends PluginBase { } }; - @Subscribe - public void onStatusEvent(EventPreferenceChange ev) { - if (ev.isChanged(R.string.key_ns_wifionly) || - ev.isChanged(R.string.key_ns_wifi_ssids) || - ev.isChanged(R.string.key_ns_allowroaming) - ) { - EventNetworkChange event = networkChangeReceiver.grabNetworkStatus(MainApp.instance().getApplicationContext()); - if (event != null) - MainApp.bus().post(event); - } else if (ev.isChanged(R.string.key_ns_chargingonly)) { - EventChargingState event = chargingStateReceiver.grabChargingState(MainApp.instance().getApplicationContext()); - if (event != null) - MainApp.bus().post(event); - } - } - - @Subscribe - public void onStatusEvent(final EventChargingState ev) { - boolean newChargingState = calculateStatus(ev); - - if (newChargingState != allowedChargingsState) { - allowedChargingsState = newChargingState; - processStateChange(); - } - } - - @Subscribe - public void onStatusEvent(final EventNetworkChange ev) { - boolean newNetworkState = calculateStatus(ev); - - if (newNetworkState != allowedNetworkState) { - allowedNetworkState = newNetworkState; - processStateChange(); - } - } - - private void processStateChange() { - boolean newAllowedState = allowedChargingsState && allowedNetworkState; - if (newAllowedState != allowed) { - allowed = newAllowedState; - MainApp.bus().post(new EventPreferenceChange(R.string.key_nsclientinternal_paused)); - } - } - - private boolean calculateStatus(final EventChargingState ev) { - boolean chargingOnly = SP.getBoolean(R.string.ns_chargingonly, false); - - boolean newAllowedState = true; - - if (!ev.isCharging && chargingOnly) newAllowedState = false; - - return newAllowedState; - } - - - private boolean calculateStatus(final EventNetworkChange ev) { - boolean wifiOnly = SP.getBoolean(R.string.key_ns_wifionly, false); - String allowedSSIDs = SP.getString(R.string.key_ns_wifi_ssids, ""); - boolean allowRoaming = SP.getBoolean(R.string.key_ns_allowroaming, true); - - boolean newAllowedState = true; - - if (!ev.wifiConnected && wifiOnly) newAllowedState = false; - if (ev.wifiConnected && !allowedSSIDs.isEmpty() && !allowedSSIDs.contains(ev.ssid)) - newAllowedState = false; - if (!allowRoaming && ev.roaming) newAllowedState = false; - - return newAllowedState; - } @Subscribe public void onStatusEvent(final EventAppExit ignored) { if (nsClientService != null) { MainApp.instance().getApplicationContext().unbindService(mConnection); - MainApp.instance().getApplicationContext().unregisterReceiver(networkChangeReceiver); + nsClientReceiverDelegate.unregisterReceivers(); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NsClientReceiverDelegate.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NsClientReceiverDelegate.java new file mode 100644 index 0000000000..627c67af34 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NsClientReceiverDelegate.java @@ -0,0 +1,132 @@ +package info.nightscout.androidaps.plugins.NSClientInternal; + +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.net.ConnectivityManager; +import android.net.wifi.WifiManager; + +import com.squareup.otto.Bus; + +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.events.EventChargingState; +import info.nightscout.androidaps.events.EventNetworkChange; +import info.nightscout.androidaps.events.EventPreferenceChange; +import info.nightscout.androidaps.receivers.ChargingStateReceiver; +import info.nightscout.androidaps.receivers.NetworkChangeReceiver; +import info.nightscout.utils.SP; + +class NsClientReceiverDelegate { + + private final Context context; + private final Bus bus; + + private NetworkChangeReceiver networkChangeReceiver = new NetworkChangeReceiver(); + private ChargingStateReceiver chargingStateReceiver = new ChargingStateReceiver(); + + private boolean allowedChargingState = true; + private boolean allowedNetworkState = true; + boolean allowed = true; + + NsClientReceiverDelegate(Context context, Bus bus) { + this.context = context; + this.bus = bus; + } + + void registerReceivers() { + Context context = MainApp.instance().getApplicationContext(); + // register NetworkChangeReceiver --> https://developer.android.com/training/monitoring-device-state/connectivity-monitoring.html + // Nougat is not providing Connectivity-Action anymore ;-( + context.registerReceiver(networkChangeReceiver, + new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); + context.registerReceiver(networkChangeReceiver, + new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION)); + + EventNetworkChange event = networkChangeReceiver.grabNetworkStatus(context); + if (event != null) + bus.post(event); + + context.registerReceiver(chargingStateReceiver, + new IntentFilter(Intent.ACTION_POWER_CONNECTED)); + context.registerReceiver(chargingStateReceiver, + new IntentFilter(Intent.ACTION_POWER_DISCONNECTED)); + + EventChargingState eventChargingState = chargingStateReceiver.grabChargingState(context); + if (eventChargingState != null) + bus.post(eventChargingState); + + } + + void unregisterReceivers() { + context.unregisterReceiver(networkChangeReceiver); + context.unregisterReceiver(chargingStateReceiver); + } + + void onStatusEvent(EventPreferenceChange ev) { + if (ev.isChanged(R.string.key_ns_wifionly) || + ev.isChanged(R.string.key_ns_wifi_ssids) || + ev.isChanged(R.string.key_ns_allowroaming) + ) { + EventNetworkChange event = networkChangeReceiver.grabNetworkStatus(MainApp.instance().getApplicationContext()); + if (event != null) + bus.post(event); + } else if (ev.isChanged(R.string.key_ns_chargingonly)) { + EventChargingState event = chargingStateReceiver.grabChargingState(MainApp.instance().getApplicationContext()); + if (event != null) + bus.post(event); + } + } + + void onStatusEvent(final EventChargingState ev) { + boolean newChargingState = calculateStatus(ev); + + if (newChargingState != allowedChargingState) { + allowedChargingState = newChargingState; + processStateChange(); + } + } + + void onStatusEvent(final EventNetworkChange ev) { + boolean newNetworkState = calculateStatus(ev); + + if (newNetworkState != allowedNetworkState) { + allowedNetworkState = newNetworkState; + processStateChange(); + } + } + + void processStateChange() { + boolean newAllowedState = allowedChargingState && allowedNetworkState; + if (newAllowedState != allowed) { + allowed = newAllowedState; + bus.post(new EventPreferenceChange(R.string.key_nsclientinternal_paused)); + } + } + + boolean calculateStatus(final EventChargingState ev) { + boolean chargingOnly = SP.getBoolean(R.string.key_ns_chargingonly, false); + + boolean newAllowedState = true; + + if (!ev.isCharging && chargingOnly) newAllowedState = false; + + return newAllowedState; + } + + boolean calculateStatus(final EventNetworkChange ev) { + boolean wifiOnly = SP.getBoolean(R.string.key_ns_wifionly, false); + String allowedSSIDs = SP.getString(R.string.key_ns_wifi_ssids, ""); + boolean allowRoaming = SP.getBoolean(R.string.key_ns_allowroaming, true); + + boolean newAllowedState = true; + + if (!ev.wifiConnected && wifiOnly) newAllowedState = false; + if (ev.wifiConnected && !allowedSSIDs.trim().isEmpty() && !allowedSSIDs.contains(ev.ssid)) + newAllowedState = false; + if (!allowRoaming && ev.roaming) newAllowedState = false; + + return newAllowedState; + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/services/NSClientService.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/services/NSClientService.java index b842f06726..91c5eccb35 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/services/NSClientService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/services/NSClientService.java @@ -202,7 +202,7 @@ public class NSClientService extends Service { nsAPIhashCode = Hashing.sha1().hashString(nsAPISecret, Charsets.UTF_8).toString(); MainApp.bus().post(new EventNSClientStatus("Initializing")); - if (!MainApp.getSpecificPlugin(NSClientPlugin.class).allowed) { + if (!MainApp.getSpecificPlugin(NSClientPlugin.class).isAllowed()) { MainApp.bus().post(new EventNSClientNewLog("NSCLIENT", "not allowed")); MainApp.bus().post(new EventNSClientStatus("Not allowed")); } else if (MainApp.getSpecificPlugin(NSClientPlugin.class).paused) { diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/NSClientInternal/NsClientReceiverDelegateTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/NSClientInternal/NsClientReceiverDelegateTest.java new file mode 100644 index 0000000000..cc209c1837 --- /dev/null +++ b/app/src/test/java/info/nightscout/androidaps/plugins/NSClientInternal/NsClientReceiverDelegateTest.java @@ -0,0 +1,115 @@ +package info.nightscout.androidaps.plugins.NSClientInternal; + +import android.content.Context; +import com.squareup.otto.Bus; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import info.AAPSMocker; +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.events.EventChargingState; +import info.nightscout.androidaps.events.EventNetworkChange; +import info.nightscout.utils.SP; + +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.when; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({MainApp.class, SP.class, Context.class}) +public class NsClientReceiverDelegateTest { + + private NsClientReceiverDelegate sut; + + @Before + public void prepare() { + AAPSMocker.mockMainApp(); + AAPSMocker.mockApplicationContext(); + + Bus bus = MainApp.bus(); + Context context = MainApp.instance().getApplicationContext(); + + sut = new NsClientReceiverDelegate(context, bus); + } + + @Test + public void testCalculateStatusChargingState() { + PowerMockito.mockStatic(SP.class); + when(SP.getBoolean(anyInt(), anyBoolean())).thenReturn(false); + EventChargingState ev = new EventChargingState(true); + assertTrue(sut.calculateStatus(ev)); + ev = new EventChargingState(false); + assertTrue(sut.calculateStatus(ev)); + + when(SP.getBoolean(anyInt(), anyBoolean())).thenReturn(true); + ev = new EventChargingState(true); + assertTrue(sut.calculateStatus(ev)); + ev = new EventChargingState(false); + assertTrue(!sut.calculateStatus(ev)); + } + + @Test + public void testCalculateStatusNetworkState() { + PowerMockito.mockStatic(SP.class); + // wifiOnly = false + // allowRoaming = false as well + when(SP.getBoolean(anyInt(), anyBoolean())).thenReturn(false); + when(SP.getString(anyInt(), anyString())).thenReturn(""); + EventNetworkChange ev = new EventNetworkChange(); + ev.ssid = ""; + + ev.mobileConnected = true; + ev.wifiConnected = true; + assertTrue(sut.calculateStatus(ev)); + ev.wifiConnected = false; + assertTrue(sut.calculateStatus(ev)); + + // wifiOnly = true + // allowRoaming = true as well + when(SP.getBoolean(anyInt(), anyBoolean())).thenReturn(true); + ev.wifiConnected = true; + assertTrue(sut.calculateStatus(ev)); + ev.wifiConnected = false; + assertTrue(!sut.calculateStatus(ev)); + + // wifiOnly = false + // allowRoaming = false as well + when(SP.getBoolean(anyInt(), anyBoolean())).thenReturn(false); + ev.wifiConnected = false; + ev.roaming = true; + assertTrue(!sut.calculateStatus(ev)); + + // wifiOnly = false + // allowRoaming = true + when(SP.getBoolean(R.string.key_ns_wifionly, false)).thenReturn(false); + when(SP.getBoolean(R.string.key_ns_allowroaming, true)).thenReturn(true); + ev.wifiConnected = false; + ev.roaming = true; + assertTrue(sut.calculateStatus(ev)); + + // wifiOnly = true + // allowRoaming = true + when(SP.getBoolean(R.string.key_ns_wifionly, false)).thenReturn(true); + when(SP.getBoolean(R.string.key_ns_allowroaming, true)).thenReturn(true); + ev.wifiConnected = false; + ev.roaming = true; + assertTrue(!sut.calculateStatus(ev)); + + // wifiOnly = true + // allowRoaming = true + when(SP.getBoolean(R.string.key_ns_wifionly, false)).thenReturn(true); + when(SP.getBoolean(R.string.key_ns_allowroaming, true)).thenReturn(true); + ev.wifiConnected = true; + ev.roaming = true; + assertTrue(sut.calculateStatus(ev)); + } +}