From ba670bbb50cd04c61947a781ec199b6261c1b3fe Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Sun, 23 Aug 2015 00:54:28 +0200 Subject: [PATCH] More testing work: with a new test for finding the device --- .../service/DeviceCommunicationService.java | 89 +++++++++++++++---- .../service/AbstractServiceTestCase.java | 10 ++- .../DeviceCommunicationServiceTestCase.java | 59 ++++++++++-- .../{test => service}/TestDeviceSupport.java | 6 +- 4 files changed, 135 insertions(+), 29 deletions(-) rename app/src/test/java/nodomain/freeyourgadget/gadgetbridge/{test => service}/TestDeviceSupport.java (92%) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java index 61ecd2136..7fa301c3e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java @@ -13,6 +13,7 @@ import android.net.Uri; import android.os.IBinder; import android.preference.PreferenceManager; import android.provider.ContactsContract; +import android.support.annotation.Nullable; import android.support.v4.content.LocalBroadcastManager; import android.widget.Toast; @@ -27,13 +28,48 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.Alarm; import nodomain.freeyourgadget.gadgetbridge.model.ServiceCommand; import nodomain.freeyourgadget.gadgetbridge.util.GB; -import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.*; + +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_CALLSTATE; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_CONNECT; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_DELETEAPP; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_DISCONNECT; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_FETCH_ACTIVITY_DATA; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_FIND_DEVICE; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_INSTALL; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_NOTIFICATION_EMAIL; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_NOTIFICATION_GENERIC; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_NOTIFICATION_SMS; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_REBOOT; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_REQUEST_APPINFO; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_REQUEST_DEVICEINFO; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_REQUEST_SCREENSHOT; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_SETMUSICINFO; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_SETTIME; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_SET_ALARMS; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_START; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_STARTAPP; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_ALARMS; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_APP_UUID; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CALL_COMMAND; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CALL_PHONENUMBER; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_DEVICE_ADDRESS; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_FIND_START; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_MUSIC_ALBUM; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_MUSIC_ARTIST; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_MUSIC_TRACK; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_BODY; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_SENDER; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_SUBJECT; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_TITLE; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_PERFORM_PAIR; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_URI; public class DeviceCommunicationService extends Service { private static final Logger LOG = LoggerFactory.getLogger(DeviceCommunicationService.class); private boolean mStarted = false; + private DeviceSupportFactory mFactory; private GBDevice mGBDevice = null; private DeviceSupport mDeviceSupport; @@ -60,6 +96,7 @@ public class DeviceCommunicationService extends Service { LOG.debug("DeviceCommunicationService is being created"); super.onCreate(); LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, new IntentFilter(GBDevice.ACTION_DEVICE_CHANGED)); + mFactory = new DeviceSupportFactory(this); } @Override @@ -116,25 +153,20 @@ public class DeviceCommunicationService extends Service { } if (btDeviceAddress != null && !isConnecting() && !isConnected()) { - if (mDeviceSupport != null) { - mDeviceSupport.dispose(); - mDeviceSupport = null; - } + setDeviceSupport(null); try { - DeviceSupportFactory factory = new DeviceSupportFactory(this); - mDeviceSupport = factory.createDeviceSupport(btDeviceAddress); - if (mDeviceSupport != null) { - mGBDevice = mDeviceSupport.getDevice(); + DeviceSupport deviceSupport = mFactory.createDeviceSupport(btDeviceAddress); + if (deviceSupport != null) { + setDeviceSupport(deviceSupport); if (pair) { - mDeviceSupport.pair(); + deviceSupport.pair(); } else { - mDeviceSupport.connect(); + deviceSupport.connect(); } } } catch (Exception e) { GB.toast(this, getString(R.string.cannot_connect, e.getMessage()), Toast.LENGTH_SHORT, GB.ERROR); - mDeviceSupport = null; - mGBDevice = null; + setDeviceSupport(null); } } else if (mGBDevice != null) { // send an update at least @@ -233,6 +265,29 @@ public class DeviceCommunicationService extends Service { return START_STICKY; } + /** + * For testing! + * @param factory + */ + public void setDeviceSupportFactory(DeviceSupportFactory factory) { + mFactory = factory; + } + + /** + * Disposes the current DeviceSupport instance (if any) and sets a new device support instance + * (if not null). + * @param deviceSupport + */ + private void setDeviceSupport(@Nullable DeviceSupport deviceSupport) { + if (deviceSupport != mDeviceSupport && mDeviceSupport != null) { + mDeviceSupport.dispose(); + mDeviceSupport = null; + mGBDevice = null; + } + mDeviceSupport = deviceSupport; + mGBDevice = mDeviceSupport != null ? mDeviceSupport.getDevice() : null; + } + private void start() { if (!mStarted) { startForeground(GB.NOTIFICATION_ID, GB.createNotification(getString(R.string.gadgetbridge_running), this)); @@ -240,6 +295,10 @@ public class DeviceCommunicationService extends Service { } } + public boolean isStarted() { + return mStarted; + } + private boolean isConnected() { return mGBDevice != null && mGBDevice.isConnected(); } @@ -260,9 +319,7 @@ public class DeviceCommunicationService extends Service { LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver); GB.setReceiversEnableState(false, this); // disable BroadcastReceivers - if (mDeviceSupport != null) { - mDeviceSupport.dispose(); - } + setDeviceSupport(null); NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); nm.cancel(GB.NOTIFICATION_ID); // need to do this because the updated notification wont be cancelled when service stops } diff --git a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractServiceTestCase.java b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractServiceTestCase.java index caacc520b..ea82165d3 100644 --- a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractServiceTestCase.java +++ b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/AbstractServiceTestCase.java @@ -37,6 +37,10 @@ public abstract class AbstractServiceTestCase { return mContext; } + public T getServiceInstance() { + return mServiceInstance; + } + @Before public void setUp() throws Exception { mMockHelper = new MockHelper(); @@ -45,6 +49,7 @@ public abstract class AbstractServiceTestCase { mContext = createContext(mApplication); mNotificationManager = mMockHelper.createNotificationManager(mContext); mServiceInstance = createService(mServiceClass, mApplication, mNotificationManager); + mServiceInstance.onCreate(); } @After @@ -55,10 +60,7 @@ public abstract class AbstractServiceTestCase { } public void startService(Intent intent) { - if (!wasStarted) { - wasStarted = true; - mServiceInstance.onCreate(); - } + wasStarted = true; mServiceInstance.onStartCommand(intent, Service.START_FLAG_REDELIVERY, ID); } diff --git a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationServiceTestCase.java b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationServiceTestCase.java index 209fa5161..f32f6f9b6 100644 --- a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationServiceTestCase.java +++ b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationServiceTestCase.java @@ -1,19 +1,42 @@ package nodomain.freeyourgadget.gadgetbridge.service; -import android.test.ServiceTestCase; - -import junit.framework.TestCase; +import android.content.Context; +import org.junit.After; import org.junit.Before; import org.junit.Test; -import org.junit.runner.RunWith; +import org.mockito.InOrder; +import org.mockito.Mock; +import org.mockito.Mockito; -import nodomain.freeyourgadget.gadgetbridge.test.TestDeviceSupport; +import nodomain.freeyourgadget.gadgetbridge.GBException; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; +import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; public class DeviceCommunicationServiceTestCase extends AbstractServiceTestCase { private static final java.lang.String TEST_DEVICE_ADDRESS = TestDeviceSupport.class.getName(); - + + /** + * Factory that always returns the mockSupport instance + */ + private class TestDeviceSupportFactory extends DeviceSupportFactory { + public TestDeviceSupportFactory(Context context) { + super(context); + } + + @Override + public synchronized DeviceSupport createDeviceSupport(String deviceAddress) throws GBException { + return mockSupport; + } + } + private TestDeviceService mDeviceService; + @Mock + private TestDeviceSupport realSupport; + private TestDeviceSupport mockSupport; public DeviceCommunicationServiceTestCase() { super(DeviceCommunicationService.class); @@ -22,16 +45,38 @@ public class DeviceCommunicationServiceTestCase extends AbstractServiceTestCase< @Before public void setUp() throws Exception { super.setUp(); + mockSupport = null; + realSupport = new TestDeviceSupport(); + realSupport.setContext(new GBDevice(TEST_DEVICE_ADDRESS, "Test Device", DeviceType.TEST), null, getContext()); + mockSupport = Mockito.spy(realSupport); + getServiceInstance().setDeviceSupportFactory(new TestDeviceSupportFactory(getContext())); + mDeviceService = new TestDeviceService(this); } @Test public void testStart() { + assertFalse("Service was already", getServiceInstance().isStarted()); mDeviceService.start(); + assertTrue("Service should be started", getServiceInstance().isStarted()); } @Test - public void testConnect() { + public void ensureConnected() { mDeviceService.connect(TEST_DEVICE_ADDRESS); + Mockito.verify(mockSupport, Mockito.times(1)).connect(); + assertTrue(realSupport.getDevice().isInitialized()); + } + + @Test + public void testFindDevice() { + ensureConnected(); + + InOrder inOrder = Mockito.inOrder(mockSupport); + mDeviceService.onFindDevice(true); + mDeviceService.onFindDevice(false); + inOrder.verify(mockSupport, Mockito.times(1)).onFindDevice(true); + inOrder.verify(mockSupport, Mockito.times(1)).onFindDevice(false); + inOrder.verifyNoMoreInteractions(); } } diff --git a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/TestDeviceSupport.java b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/TestDeviceSupport.java similarity index 92% rename from app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/TestDeviceSupport.java rename to app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/TestDeviceSupport.java index 625904184..61de0b47d 100644 --- a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/TestDeviceSupport.java +++ b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/TestDeviceSupport.java @@ -1,4 +1,4 @@ -package nodomain.freeyourgadget.gadgetbridge.test; +package nodomain.freeyourgadget.gadgetbridge.service; import android.bluetooth.BluetoothAdapter; import android.content.Context; @@ -27,7 +27,9 @@ public class TestDeviceSupport extends AbstractDeviceSupport { @Override public boolean connect() { - return false; + gbDevice.setState(GBDevice.State.INITIALIZED); + gbDevice.sendDeviceUpdateIntent(getContext()); + return true; } @Override