package com.b2msolutions.reyna; import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.net.ConnectivityManager; import android.net.NetworkInfo; import com.b2msolutions.reyna.Dispatcher.Result; import com.b2msolutions.reyna.blackout.Time; import com.b2msolutions.reyna.blackout.TimeRange; import com.b2msolutions.reyna.http.HttpPost; import com.b2msolutions.reyna.shadows.ShadowAndroidHttpClient; import com.b2msolutions.reyna.system.Clock; import com.b2msolutions.reyna.system.Message; import com.b2msolutions.reyna.system.Preferences; import org.apache.http.HttpResponse; import org.apache.http.StatusLine; import org.apache.http.client.HttpClient; import org.apache.http.entity.AbstractHttpEntity; import org.apache.http.entity.ByteArrayEntity; import org.apache.http.entity.StringEntity; import org.apache.http.util.EntityUtils; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowConnectivityManager; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.net.URI; import java.net.URISyntaxException; import java.security.KeyManagementException; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.zip.GZIPOutputStream; import static junit.framework.Assert.assertFalse; import static org.junit.Assert.*; import static org.mockito.Mockito.*; import static org.robolectric.Shadows.shadowOf; @Config(shadows = {ShadowAndroidHttpClient.class}) @RunWith(RobolectricTestRunner.class) public class DispatcherTest { private Context context; private Intent batteryStatus; @Mock NetworkInfo networkInfo; @Mock Date now; @Before public void setup() { MockitoAnnotations.initMocks(this); context = RuntimeEnvironment.application.getApplicationContext(); ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); ShadowConnectivityManager shadowConnectivityManager = shadowOf(connectivityManager); shadowConnectivityManager.setActiveNetworkInfo(networkInfo); when(networkInfo.getType()).thenReturn(ConnectivityManager.TYPE_WIFI); when(networkInfo.isConnectedOrConnecting()).thenReturn(true); } @Test public void sendMessageHappyPathShouldSetExecuteCorrectHttpPostAndReturnOK() throws URISyntaxException, IOException, KeyManagementException, UnrecoverableKeyException, KeyStoreException, NoSuchAlgorithmException, CertificateException { Message message = RepositoryTest.getMessageWithHeaders(); StatusLine statusLine = mock(StatusLine.class); when(statusLine.getStatusCode()).thenReturn(200); HttpResponse httpResponse = mock(HttpResponse.class); when(httpResponse.getStatusLine()).thenReturn(statusLine); HttpPost httpPost = mock(HttpPost.class); HttpClient httpClient = mock(HttpClient.class); when(httpClient.execute(httpPost)).thenReturn(httpResponse); Time time = mock(Time.class); assertEquals(Result.OK, new Dispatcher().sendMessage(message, httpPost, httpClient, this.context)); this.verifyHttpPost(message, httpPost); ArgumentCaptor<StringEntity> stringEntityCaptor = ArgumentCaptor.forClass(StringEntity.class); verify(httpPost).setEntity(stringEntityCaptor.capture()); StringEntity stringEntity = stringEntityCaptor.getValue(); assertEquals(stringEntity.getContentType().getValue(), "text/plain; charset=UTF-8"); assertEquals(EntityUtils.toString(stringEntity), "body"); } @Test public void sendMessageHappyPathWithChineseCharactersShouldSetExecuteCorrectHttpPostAndReturnOK() throws URISyntaxException, IOException, KeyManagementException, UnrecoverableKeyException, KeyStoreException, NoSuchAlgorithmException, CertificateException { Message message = RepositoryTest.getMessageWithHeaders("谷歌拼音输入法"); StatusLine statusLine = mock(StatusLine.class); when(statusLine.getStatusCode()).thenReturn(200); HttpResponse httpResponse = mock(HttpResponse.class); when(httpResponse.getStatusLine()).thenReturn(statusLine); HttpPost httpPost = mock(HttpPost.class); HttpClient httpClient = mock(HttpClient.class); when(httpClient.execute(httpPost)).thenReturn(httpResponse); Clock clock = mock(Clock.class); Dispatcher dispatcher = new Dispatcher(); dispatcher.clock = clock; assertEquals(Result.OK, dispatcher.sendMessage(message, httpPost, httpClient, this.context)); this.verifyHttpPost(message, httpPost); ArgumentCaptor<StringEntity> stringEntityCaptor = ArgumentCaptor.forClass(StringEntity.class); verify(httpPost).setEntity(stringEntityCaptor.capture()); StringEntity stringEntity = stringEntityCaptor.getValue(); assertEquals(stringEntity.getContentType().getValue(), "text/plain; charset=UTF-8"); assertEquals(EntityUtils.toString(stringEntity), "谷歌拼音输入法"); } @Test public void sendMessageHappyPathWithPortShouldSetPort() throws URISyntaxException, IOException, KeyManagementException, UnrecoverableKeyException, KeyStoreException, NoSuchAlgorithmException, CertificateException { Message message = new Message(new URI("https://www.google.com:9008/a/b"), "body", null); StatusLine statusLine = mock(StatusLine.class); when(statusLine.getStatusCode()).thenReturn(200); HttpResponse httpResponse = mock(HttpResponse.class); when(httpResponse.getStatusLine()).thenReturn(statusLine); HttpPost httpPost = mock(HttpPost.class); HttpClient httpClient = mock(HttpClient.class); when(httpClient.execute(httpPost)).thenReturn(httpResponse); Clock clock = mock(Clock.class); Dispatcher dispatcher = new Dispatcher(); dispatcher.clock = clock; assertEquals(Result.OK, dispatcher.sendMessage(message, httpPost, httpClient, this.context)); ArgumentCaptor<StringEntity> stringEntityCaptor = ArgumentCaptor.forClass(StringEntity.class); verify(httpPost).setEntity(stringEntityCaptor.capture()); StringEntity stringEntity = stringEntityCaptor.getValue(); assertEquals(stringEntity.getContentType().getValue(), "text/plain; charset=UTF-8"); assertEquals(EntityUtils.toString(stringEntity), "body"); } @Test public void sendMessageShouldReturnBlackoutWhenInBlackout() { when(this.networkInfo.getType()).thenReturn(ConnectivityManager.TYPE_MOBILE); Calendar now = Calendar.getInstance(); int hourOfDay = now.get(Calendar.HOUR_OF_DAY); TimeRange range = new TimeRange(new Time(hourOfDay - 1, 0), new Time(hourOfDay + 1, 0)); new Preferences(this.context).saveCellularDataBlackout(range); Clock clock = mock(Clock.class); Dispatcher dispatcher = new Dispatcher(); dispatcher.clock = clock; assertEquals(Result.BLACKOUT, dispatcher.sendMessage(null, null, null, this.context)); } @Test public void sendMessageShouldReturnNotConnectedWhenNotConnected() { when(this.networkInfo.isConnectedOrConnecting()).thenReturn(false); Clock clock = mock(Clock.class); Dispatcher dispatcher = new Dispatcher(); dispatcher.clock = clock; assertEquals(Result.NOTCONNECTED, dispatcher.sendMessage(null, null, null, this.context)); } @Test public void whenExecuteThrowsReturnTemporaryError() throws URISyntaxException, IOException { Message message = RepositoryTest.getMessageWithHeaders(); HttpPost httpPost = mock(HttpPost.class); HttpClient httpClient = mock(HttpClient.class); when(httpClient.execute(httpPost)).thenThrow(new RuntimeException("")); Clock clock = mock(Clock.class); Dispatcher dispatcher = new Dispatcher(); dispatcher.clock = clock; assertEquals(Result.TEMPORARY_ERROR, dispatcher.sendMessage(message, httpPost, httpClient, this.context)); this.verifyHttpPost(message, httpPost); } @Test public void getResultShouldReturnExpected() { assertEquals(Result.PERMANENT_ERROR, Dispatcher.getResult(100)); assertEquals(Result.OK, Dispatcher.getResult(200)); assertEquals(Result.PERMANENT_ERROR, Dispatcher.getResult(300)); assertEquals(Result.PERMANENT_ERROR, Dispatcher.getResult(400)); assertEquals(Result.TEMPORARY_ERROR, Dispatcher.getResult(500)); assertEquals(Result.PERMANENT_ERROR, Dispatcher.getResult(600)); } @Test public void sendMessageWithGzipAndContentIsLessThanMinGzipLengthShouldRemoveGzipHeaderAndSendMessageAsString() throws Exception { Message message = RepositoryTest.getMessageWithGzipHeaders("body"); StatusLine statusLine = mock(StatusLine.class); when(statusLine.getStatusCode()).thenReturn(200); HttpResponse httpResponse = mock(HttpResponse.class); when(httpResponse.getStatusLine()).thenReturn(statusLine); HttpPost httpPost = mock(HttpPost.class); HttpClient httpClient = mock(HttpClient.class); when(httpClient.execute(httpPost)).thenReturn(httpResponse); when(httpClient.execute(httpPost)).thenReturn(httpResponse); Clock clock = mock(Clock.class); Dispatcher dispatcher = new Dispatcher(); dispatcher.clock = clock; assertEquals(Result.OK, dispatcher.sendMessage(message, httpPost, httpClient, this.context)); this.verifyHttpPost(message, httpPost); ArgumentCaptor<ByteArrayEntity> byteArrayEntityCaptor = ArgumentCaptor.forClass(ByteArrayEntity.class); verify(httpPost).setEntity(byteArrayEntityCaptor.capture()); ByteArrayEntity entity = byteArrayEntityCaptor.getValue(); assertNull(entity.getContentEncoding()); assertEquals(EntityUtils.toString(entity, "utf-8"), "body"); } @Test public void sendMessageWithGzipHeaderShouldCompressContentAndReturnOK() throws URISyntaxException, IOException, KeyManagementException, UnrecoverableKeyException, KeyStoreException, NoSuchAlgorithmException, CertificateException { Message message = RepositoryTest.getMessageWithGzipHeaders("this any message body more than 10 bytes length"); byte[] data = "this any message body more than 10 bytes length".getBytes("utf-8"); StatusLine statusLine = mock(StatusLine.class); when(statusLine.getStatusCode()).thenReturn(200); HttpResponse httpResponse = mock(HttpResponse.class); when(httpResponse.getStatusLine()).thenReturn(statusLine); HttpPost httpPost = mock(HttpPost.class); HttpClient httpClient = mock(HttpClient.class); when(httpClient.execute(httpPost)).thenReturn(httpResponse); Clock clock = mock(Clock.class); Dispatcher dispatcher = new Dispatcher(); dispatcher.clock = clock; Result actual = dispatcher.sendMessage(message, httpPost, httpClient, this.context); assertEquals(Result.OK, actual); this.verifyHttpPost(message, httpPost); ArgumentCaptor<ByteArrayEntity> entityCaptor = ArgumentCaptor.forClass(ByteArrayEntity.class); verify(httpPost).setEntity(entityCaptor.capture()); AbstractHttpEntity byteArrayEntity = entityCaptor.getValue(); assertEquals(byteArrayEntity.getContentEncoding().getValue(), "gzip"); byte[] expected = gzip(data); assertArrayEquals(EntityUtils.toByteArray(byteArrayEntity), expected); } @Test public void canSendShouldReturnNOTCONNECTEDIfNoActiveNetwork() { ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); ShadowConnectivityManager shadowConnectivityManager = shadowOf(connectivityManager); shadowConnectivityManager.setActiveNetworkInfo(null); assertEquals(Result.NOTCONNECTED, Dispatcher.canSend(this.context)); } @Test public void canSendShouldReturnOKIfNonCellularAndConnected() { canSendShouldReturnOKIfNonCellularAndConnected(7); // BLUETOOTH canSendShouldReturnOKIfNonCellularAndConnected(ConnectivityManager.TYPE_WIFI); canSendShouldReturnOKIfNonCellularAndConnected(8); // DUMMY canSendShouldReturnOKIfNonCellularAndConnected(9); // ETHERNET } @Test public void canSendShouldReturnOKIfMobileAndHasNoPreferences() { canSendShouldReturnOKIfCellularAndHasNoPreferences(ConnectivityManager.TYPE_MOBILE); canSendShouldReturnOKIfCellularAndHasNoPreferences(ConnectivityManager.TYPE_MOBILE_DUN); canSendShouldReturnOKIfCellularAndHasNoPreferences(ConnectivityManager.TYPE_MOBILE_HIPRI); canSendShouldReturnOKIfCellularAndHasNoPreferences(ConnectivityManager.TYPE_MOBILE_MMS); canSendShouldReturnOKIfCellularAndHasNoPreferences(ConnectivityManager.TYPE_MOBILE_SUPL); canSendShouldReturnOKIfCellularAndHasNoPreferences(ConnectivityManager.TYPE_WIMAX); } @Test public void canSendShouldReturnBlackoutIfMobileAndInBlackout() { canSendShouldReturnBlackoutIfCellularAndInBlackout(ConnectivityManager.TYPE_MOBILE); canSendShouldReturnBlackoutIfCellularAndInBlackout(ConnectivityManager.TYPE_MOBILE_DUN); canSendShouldReturnBlackoutIfCellularAndInBlackout(ConnectivityManager.TYPE_MOBILE_HIPRI); canSendShouldReturnBlackoutIfCellularAndInBlackout(ConnectivityManager.TYPE_MOBILE_MMS); canSendShouldReturnBlackoutIfCellularAndInBlackout(ConnectivityManager.TYPE_MOBILE_SUPL); canSendShouldReturnBlackoutIfCellularAndInBlackout(ConnectivityManager.TYPE_WIMAX); } @Test public void canSendShouldReturnOKIfMobileAndOutsideOfBlackout() { canSendShouldReturnOKIfMobileAndOutsideOfBlackout(ConnectivityManager.TYPE_MOBILE); canSendShouldReturnOKIfMobileAndOutsideOfBlackout(ConnectivityManager.TYPE_MOBILE_DUN); canSendShouldReturnOKIfMobileAndOutsideOfBlackout(ConnectivityManager.TYPE_MOBILE_HIPRI); canSendShouldReturnOKIfMobileAndOutsideOfBlackout(ConnectivityManager.TYPE_MOBILE_MMS); canSendShouldReturnOKIfMobileAndOutsideOfBlackout(ConnectivityManager.TYPE_MOBILE_SUPL); canSendShouldReturnOKIfMobileAndOutsideOfBlackout(ConnectivityManager.TYPE_WIMAX); } @Test public void canSendShouldReturnNoConnectionIfActiveConnectionIsNotConnectedOrConnecting() { ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); ShadowConnectivityManager shadowConnectivityManager = shadowOf(connectivityManager); when(this.networkInfo.isConnectedOrConnecting()).thenReturn(false); shadowConnectivityManager.setActiveNetworkInfo(this.networkInfo); assertEquals(Result.NOTCONNECTED, Dispatcher.canSend(this.context)); } private void canSendShouldReturnOKIfMobileAndOutsideOfBlackout(int type) { when(this.networkInfo.getType()).thenReturn(type); Calendar now = Calendar.getInstance(); int hourOfDay = now.get(Calendar.HOUR_OF_DAY); TimeRange range = new TimeRange(new Time(hourOfDay - 2, 0), new Time(hourOfDay - 1, 0)); new Preferences(this.context).saveCellularDataBlackout(range); assertEquals(Result.OK, Dispatcher.canSend(this.context)); } private void canSendShouldReturnOKIfCellularAndHasNoPreferences(int type) { when(this.networkInfo.getType()).thenReturn(type); SharedPreferences sp = this.context.getSharedPreferences(Preferences.class.getName(), Context.MODE_PRIVATE); SharedPreferences.Editor editor = sp.edit(); editor.clear(); editor.commit(); assertEquals(Result.OK, Dispatcher.canSend(this.context)); } private void canSendShouldReturnBlackoutIfCellularAndInBlackout(int type) { when(this.networkInfo.getType()).thenReturn(type); Calendar now = Calendar.getInstance(); int hourOfDay = now.get(Calendar.HOUR_OF_DAY); TimeRange range = new TimeRange(new Time(hourOfDay - 1, 0), new Time(hourOfDay + 1, 0)); new Preferences(this.context).saveCellularDataBlackout(range); assertEquals(Result.BLACKOUT, Dispatcher.canSend(this.context)); } private void canSendShouldReturnOKIfNonCellularAndConnected(int type) { when(this.networkInfo.getType()).thenReturn(type); Calendar now = Calendar.getInstance(); int hourOfDay = now.get(Calendar.HOUR_OF_DAY); TimeRange range = new TimeRange(new Time(hourOfDay - 1, 0), new Time(hourOfDay + 1, 0)); new Preferences(this.context).saveCellularDataBlackout(range); assertEquals(Result.OK, Dispatcher.canSend(this.context)); } private void verifyHttpPost(Message message, HttpPost httpPost) { ArgumentCaptor<URI> argument = ArgumentCaptor.forClass(URI.class); verify(httpPost).setURI(argument.capture()); assertEquals(message.getUrl(), argument.getValue().toString()); verify(httpPost).setHeader(message.getHeaders()[0].getKey(), message.getHeaders()[0].getValue()); verify(httpPost).setHeader(message.getHeaders()[1].getKey(), message.getHeaders()[1].getValue()); verify(httpPost, times(2)).setHeader(anyString(), anyString()); } private byte[] gzip(byte[] data) throws IOException { ByteArrayOutputStream arr = new ByteArrayOutputStream(); OutputStream zipper = new GZIPOutputStream(arr); zipper.write(data); zipper.close(); return arr.toByteArray(); } @Test // device wlan oncharge // configuration // wlan true public void shouldSendBlackoutTimeScenarioA() { when(this.networkInfo.getType()).thenReturn(ConnectivityManager.TYPE_WIFI); initBatteryChanged(); batteryStatus.putExtra(android.os.BatteryManager.EXTRA_PLUGGED, android.os.BatteryManager.BATTERY_PLUGGED_AC); Preferences preferences = new Preferences(RuntimeEnvironment.application.getApplicationContext()); preferences.saveWlanBlackout("02:00-02:01"); preferences.saveOnChargeBlackout(true); assertEquals(Result.BLACKOUT, Dispatcher.canSend(this.context)); preferences.saveOnChargeBlackout(false); assertEquals(Result.OK, Dispatcher.canSend(this.context)); } @Test // device wlan oncharge // configuration // wlan false public void shouldNotSendBlackoutTimeScenarioB() { when(this.networkInfo.getType()).thenReturn(ConnectivityManager.TYPE_WIFI); initBatteryChanged(); batteryStatus.putExtra(android.os.BatteryManager.EXTRA_PLUGGED, android.os.BatteryManager.BATTERY_PLUGGED_AC); Preferences preferences = new Preferences(RuntimeEnvironment.application.getApplicationContext()); preferences.saveWlanBlackout("00:00-23:59"); preferences.saveOnChargeBlackout(true); assertEquals(Result.BLACKOUT, Dispatcher.canSend(this.context)); preferences.saveOnChargeBlackout(false); assertEquals(Result.BLACKOUT, Dispatcher.canSend(this.context)); } @Test // device wlan offcharge // configuration // wlan true public void blackoutTimeScenarioC() { when(this.networkInfo.getType()).thenReturn(ConnectivityManager.TYPE_WIFI); initBatteryChanged(); Preferences preferences = new Preferences(RuntimeEnvironment.application.getApplicationContext()); preferences.saveWlanBlackout("02:00-02:01"); preferences.saveOffChargeBlackout(true); assertEquals(Result.BLACKOUT, Dispatcher.canSend(this.context)); preferences.saveOffChargeBlackout(false); assertEquals(Result.OK, Dispatcher.canSend(this.context)); } @Test // device wlan offcharge // configuration // wlan false public void blackoutTimeScenarioD() { when(this.networkInfo.getType()).thenReturn(ConnectivityManager.TYPE_WIFI); initBatteryChanged(); Preferences preferences = new Preferences(RuntimeEnvironment.application.getApplicationContext()); preferences.saveWlanBlackout("00:00-23:59"); preferences.saveOffChargeBlackout(true); assertEquals(Result.BLACKOUT, Dispatcher.canSend(this.context)); preferences.saveOffChargeBlackout(false); assertEquals(Result.BLACKOUT, Dispatcher.canSend(this.context)); } private void testBlackoutMobileScenario(int type) { when(this.networkInfo.getType()).thenReturn(type); initBatteryChanged(); batteryStatus.putExtra(android.os.BatteryManager.EXTRA_PLUGGED, android.os.BatteryManager.BATTERY_PLUGGED_AC); Preferences preferences = new Preferences(RuntimeEnvironment.application.getApplicationContext()); preferences.saveWwanBlackout("02:00-02:01"); preferences.saveOnChargeBlackout(true); assertEquals(Result.BLACKOUT, Dispatcher.canSend(this.context)); preferences.saveOnChargeBlackout(false); assertEquals(Result.OK, Dispatcher.canSend(this.context)); } @Test // device wwan oncharge // configuration // wwan true public void blackoutTimeScenarioE() { testBlackoutMobileScenario(ConnectivityManager.TYPE_MOBILE); testBlackoutMobileScenario(ConnectivityManager.TYPE_MOBILE_DUN); testBlackoutMobileScenario(ConnectivityManager.TYPE_MOBILE_HIPRI); testBlackoutMobileScenario(ConnectivityManager.TYPE_MOBILE_MMS); testBlackoutMobileScenario(ConnectivityManager.TYPE_MOBILE_SUPL); testBlackoutMobileScenario(ConnectivityManager.TYPE_WIMAX); } @Test // device wwan oncharge // configuration // wwan false public void blackoutTimeScenarioF() { when(this.networkInfo.getType()).thenReturn(ConnectivityManager.TYPE_MOBILE); initBatteryChanged(); batteryStatus.putExtra(android.os.BatteryManager.EXTRA_PLUGGED, android.os.BatteryManager.BATTERY_PLUGGED_AC); Preferences preferences = new Preferences(RuntimeEnvironment.application.getApplicationContext()); preferences.saveWwanBlackout("00:00-23:59"); preferences.saveOnChargeBlackout(true); assertEquals(Result.BLACKOUT, Dispatcher.canSend(this.context)); preferences.saveOnChargeBlackout(false); assertEquals(Result.BLACKOUT, Dispatcher.canSend(this.context)); } @Test // device wwan offcharge // configuration // wwan true public void blackoutTimeScenarioG() { when(this.networkInfo.getType()).thenReturn(ConnectivityManager.TYPE_MOBILE); initBatteryChanged(); Preferences preferences = new Preferences(RuntimeEnvironment.application.getApplicationContext()); preferences.saveWwanBlackout("02:00-02:01"); preferences.saveOffChargeBlackout(true); assertEquals(Result.BLACKOUT, Dispatcher.canSend(this.context)); preferences.saveOffChargeBlackout(false); assertEquals(Result.OK, Dispatcher.canSend(this.context)); } @Test // device wwan offcharge // configuration // wwan false public void blackoutTimeScenarioH() { when(this.networkInfo.getType()).thenReturn(ConnectivityManager.TYPE_MOBILE); initBatteryChanged(); Preferences preferences = new Preferences(RuntimeEnvironment.application.getApplicationContext()); preferences.saveWwanBlackout("00:00-23:59"); preferences.saveOffChargeBlackout(true); assertEquals(Result.BLACKOUT, Dispatcher.canSend(this.context)); preferences.saveOffChargeBlackout(false); assertEquals(Result.BLACKOUT, Dispatcher.canSend(this.context)); } @SuppressLint("NewApi") @Test // device roaming oncharge // configuration // roaming false public void blackoutTimeScenarioI() { when(this.networkInfo.getType()).thenReturn(ConnectivityManager.TYPE_MOBILE); when(this.networkInfo.isRoaming()).thenReturn(true); initBatteryChanged(); batteryStatus.putExtra(android.os.BatteryManager.EXTRA_PLUGGED, android.os.BatteryManager.BATTERY_PLUGGED_AC); Preferences preferences = new Preferences(RuntimeEnvironment.application.getApplicationContext()); preferences.saveOnChargeBlackout(true); preferences.saveWwanRoamingBlackout(false); assertEquals(Result.BLACKOUT, Dispatcher.canSend(this.context)); preferences.saveOnChargeBlackout(false); assertEquals(Result.OK, Dispatcher.canSend(this.context)); } @SuppressLint("NewApi") @Test // device roaming oncharge // configuration // roaming true public void blackoutTimeScenarioJ() { when(this.networkInfo.getType()).thenReturn(ConnectivityManager.TYPE_MOBILE); when(this.networkInfo.isRoaming()).thenReturn(true); initBatteryChanged(); batteryStatus.putExtra(android.os.BatteryManager.EXTRA_PLUGGED, android.os.BatteryManager.BATTERY_PLUGGED_AC); Preferences preferences = new Preferences(RuntimeEnvironment.application.getApplicationContext()); preferences.saveOnChargeBlackout(true); preferences.saveWwanRoamingBlackout(true); assertEquals(Result.BLACKOUT, Dispatcher.canSend(this.context)); preferences.saveOnChargeBlackout(false); assertEquals(Result.BLACKOUT, Dispatcher.canSend(this.context)); } @SuppressLint("NewApi") @Test // device roaming offcharge // configuration // roaming true public void blackoutTimeScenarioK() { when(this.networkInfo.getType()).thenReturn(ConnectivityManager.TYPE_MOBILE); when(this.networkInfo.isRoaming()).thenReturn(true); initBatteryChanged(); Preferences preferences = new Preferences(RuntimeEnvironment.application.getApplicationContext()); preferences.saveOffChargeBlackout(true); preferences.saveWwanRoamingBlackout(true); assertEquals(Result.BLACKOUT, Dispatcher.canSend(this.context)); preferences.saveOffChargeBlackout(false); assertEquals(Result.BLACKOUT, Dispatcher.canSend(this.context)); } @SuppressLint("NewApi") @Test // device roaming offcharge // configuration // roaming false public void blackoutTimeScenarioL() { when(this.networkInfo.getType()).thenReturn(ConnectivityManager.TYPE_MOBILE); when(this.networkInfo.isRoaming()).thenReturn(true); initBatteryChanged(); Preferences preferences = new Preferences(RuntimeEnvironment.application.getApplicationContext()); preferences.saveOffChargeBlackout(true); preferences.saveWwanRoamingBlackout(false); assertEquals(Result.BLACKOUT, Dispatcher.canSend(this.context)); preferences.saveOffChargeBlackout(false); assertEquals(Result.OK, Dispatcher.canSend(this.context)); } @SuppressLint("NewApi") @Test // device wwan and wlan oncharge // configuration // wwan true public void blackoutTimeScenarioM() { when(this.networkInfo.getType()).thenReturn(ConnectivityManager.TYPE_MOBILE); when(this.networkInfo.isRoaming()).thenReturn(true); initBatteryChanged(); Preferences preferences = new Preferences(RuntimeEnvironment.application.getApplicationContext()); preferences.saveOffChargeBlackout(true); preferences.saveWwanRoamingBlackout(false); assertEquals(Result.BLACKOUT, Dispatcher.canSend(this.context)); preferences.saveOffChargeBlackout(false); assertEquals(Result.OK, Dispatcher.canSend(this.context)); } @Test public void whenCallingIsChargingAndCouldNotGetBatteryStatusShouldReturnFalse() { Intent intent = new Intent(); intent.setAction(Intent.ACTION_AIRPLANE_MODE_CHANGED); RuntimeEnvironment.application.sendStickyBroadcast(intent); assertFalse(Dispatcher.isBatteryCharging(context)); } private void initBatteryChanged() { batteryStatus = new Intent(); batteryStatus.setAction(Intent.ACTION_BATTERY_CHANGED); batteryStatus.putExtra(android.os.BatteryManager.EXTRA_LEVEL, 3); batteryStatus.putExtra(android.os.BatteryManager.EXTRA_SCALE, 7); batteryStatus.putExtra(android.os.BatteryManager.EXTRA_STATUS, 4); RuntimeEnvironment.application.sendStickyBroadcast(batteryStatus); } @Test public void whenCallingIsChargingShouldReturnExpected() { initBatteryChanged(); batteryStatus.putExtra(android.os.BatteryManager.EXTRA_PLUGGED, android.os.BatteryManager.BATTERY_PLUGGED_AC); assertTrue(Dispatcher.isBatteryCharging(context)); } @Test public void whenCallingIsChargingUsbShouldReturnExpected() { initBatteryChanged(); batteryStatus.putExtra(android.os.BatteryManager.EXTRA_PLUGGED, android.os.BatteryManager.BATTERY_PLUGGED_USB); assertTrue(Dispatcher.isBatteryCharging(context)); } @Test public void whenCallingIsChargingWirelessShouldReturnExpected() { initBatteryChanged(); batteryStatus.putExtra(android.os.BatteryManager.EXTRA_PLUGGED, 4); assertTrue(Dispatcher.isBatteryCharging(context)); } @Test public void whenCallingIsChargingUnknownShouldReturnExpected() { initBatteryChanged(); batteryStatus.putExtra(android.os.BatteryManager.EXTRA_PLUGGED, 3); assertTrue(Dispatcher.isBatteryCharging(context)); } @Test public void whenCallingGetBatteryChargingOnAndNotChargingShouldReturnExpected() { initBatteryChanged(); batteryStatus.putExtra(android.os.BatteryManager.EXTRA_PLUGGED, -1); assertFalse(Dispatcher.isBatteryCharging(context)); } @Test public void whenOldAndNewConfigurationPresentPreferNewConfiguration() { when(this.networkInfo.getType()).thenReturn(ConnectivityManager.TYPE_MOBILE); Preferences preferences = new Preferences(RuntimeEnvironment.application.getApplicationContext()); Calendar now = new GregorianCalendar(); Time oldTo = new Time(now.get(Calendar.HOUR_OF_DAY) + 1, now.get(Calendar.MINUTE)); preferences.saveCellularDataBlackout(new TimeRange(new Time(0,0), oldTo)); String newTo = (String.format("%02d", now.get(Calendar.HOUR_OF_DAY) - 1)) + ":" + String.format("%02d", now.get(Calendar.MINUTE)); preferences.saveWwanBlackout("00:00-" + newTo); assertEquals(Result.OK, Dispatcher.canSend(context)); } @Test public void whenOldConfigurationPresentAndNewNotPresentDontUseNewConfDefaultValue() { when(this.networkInfo.getType()).thenReturn(ConnectivityManager.TYPE_MOBILE); Preferences preferences = new Preferences(RuntimeEnvironment.application.getApplicationContext()); Calendar now = new GregorianCalendar(); Time oldTo = new Time(now.get(Calendar.HOUR_OF_DAY) + 1, now.get(Calendar.MINUTE)); preferences.saveCellularDataBlackout(new TimeRange(new Time(0,0), oldTo)); assertEquals(Result.BLACKOUT, Dispatcher.canSend(context)); } @Test public void whenOldConfigurationIsFromZeroAndToZeroAllowSending() { when(this.networkInfo.getType()).thenReturn(ConnectivityManager.TYPE_MOBILE); Preferences preferences = new Preferences(RuntimeEnvironment.application.getApplicationContext()); preferences.saveCellularDataBlackout(new TimeRange(new Time(0, 0), new Time(0, 0))); assertEquals(Result.OK, Dispatcher.canSend(context)); } @Test public void whenCallingCanSendAndCurrentTimeIsBetweenNonRecurringWwanBlackoutStartTimeAndEndTimeShouldBlackout() { when(this.networkInfo.getType()).thenReturn(ConnectivityManager.TYPE_MOBILE); Preferences preferences = new Preferences(RuntimeEnvironment.application.getApplicationContext()); preferences.saveNonRecurringWwanBlackoutStartTime(42L); preferences.saveNonRecurringWwanBlackoutEndTime(84L); GregorianCalendar now = mock(GregorianCalendar.class); when(now.getTimeInMillis()).thenReturn(63L); assertEquals(Result.BLACKOUT, Dispatcher.canSend(context, now)); } @Test public void whenCallingCanSendAndCurrentTimeIsBeforeNonRecurringWwanBlackoutStartTimeAndEndTimeShouldBeOk() { when(this.networkInfo.getType()).thenReturn(ConnectivityManager.TYPE_MOBILE); Preferences preferences = new Preferences(RuntimeEnvironment.application.getApplicationContext()); preferences.saveNonRecurringWwanBlackoutStartTime(70L); preferences.saveNonRecurringWwanBlackoutEndTime(84L); GregorianCalendar now = mock(GregorianCalendar.class); when(now.getTimeInMillis()).thenReturn(63L); assertEquals(Result.OK, Dispatcher.canSend(context, now)); } @Test public void whenCallingCanSendAndCurrentTimeIsAfterNonRecurringWwanBlackoutStartTimeAndEndTimeShouldBeOk() { when(this.networkInfo.getType()).thenReturn(ConnectivityManager.TYPE_MOBILE); Preferences preferences = new Preferences(RuntimeEnvironment.application.getApplicationContext()); preferences.saveNonRecurringWwanBlackoutStartTime(70L); preferences.saveNonRecurringWwanBlackoutEndTime(84L); GregorianCalendar now = mock(GregorianCalendar.class); when(now.getTimeInMillis()).thenReturn(90L); assertEquals(Result.OK, Dispatcher.canSend(context, now)); } @Test public void whenCallingCanSendAndNonRecurringWwanBlackoutStartTimeOrEndTimeIsNotSetShouldBeOk() { when(this.networkInfo.getType()).thenReturn(ConnectivityManager.TYPE_MOBILE); Preferences preferences = new Preferences(RuntimeEnvironment.application.getApplicationContext()); preferences.resetNonRecurringWwanBlackout(); GregorianCalendar now = mock(GregorianCalendar.class); when(now.getTimeInMillis()).thenReturn(90L); assertEquals(Result.OK, Dispatcher.canSend(context, now)); } @Test public void whenCallingSendMessageShouldAddSubmittedTimestamp() throws IOException, URISyntaxException { Message message = RepositoryTest.getMessageWithHeaders(); StatusLine statusLine = mock(StatusLine.class); when(statusLine.getStatusCode()).thenReturn(200); HttpResponse httpResponse = mock(HttpResponse.class); when(httpResponse.getStatusLine()).thenReturn(statusLine); HttpPost httpPost = mock(HttpPost.class); HttpClient httpClient = mock(HttpClient.class); when(httpClient.execute(httpPost)).thenReturn(httpResponse); Clock clock = mock(Clock.class); Dispatcher dispatcher = new Dispatcher(); when(clock.getCurrentTimeMillis()).thenReturn(42L); dispatcher.clock = clock; assertEquals(Result.OK, dispatcher.sendMessage(message, httpPost, httpClient, this.context)); verify(httpPost).addHeader("submitted", "42"); } }