More testing work: with a new test for finding the device

This commit is contained in:
cpfeiffer 2015-08-23 00:54:28 +02:00
parent ba6bdad057
commit ba670bbb50
4 changed files with 135 additions and 29 deletions

View File

@ -13,6 +13,7 @@ import android.net.Uri;
import android.os.IBinder; import android.os.IBinder;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.provider.ContactsContract; import android.provider.ContactsContract;
import android.support.annotation.Nullable;
import android.support.v4.content.LocalBroadcastManager; import android.support.v4.content.LocalBroadcastManager;
import android.widget.Toast; 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.Alarm;
import nodomain.freeyourgadget.gadgetbridge.model.ServiceCommand; import nodomain.freeyourgadget.gadgetbridge.model.ServiceCommand;
import nodomain.freeyourgadget.gadgetbridge.util.GB; 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 { public class DeviceCommunicationService extends Service {
private static final Logger LOG = LoggerFactory.getLogger(DeviceCommunicationService.class); private static final Logger LOG = LoggerFactory.getLogger(DeviceCommunicationService.class);
private boolean mStarted = false; private boolean mStarted = false;
private DeviceSupportFactory mFactory;
private GBDevice mGBDevice = null; private GBDevice mGBDevice = null;
private DeviceSupport mDeviceSupport; private DeviceSupport mDeviceSupport;
@ -60,6 +96,7 @@ public class DeviceCommunicationService extends Service {
LOG.debug("DeviceCommunicationService is being created"); LOG.debug("DeviceCommunicationService is being created");
super.onCreate(); super.onCreate();
LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, new IntentFilter(GBDevice.ACTION_DEVICE_CHANGED)); LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, new IntentFilter(GBDevice.ACTION_DEVICE_CHANGED));
mFactory = new DeviceSupportFactory(this);
} }
@Override @Override
@ -116,25 +153,20 @@ public class DeviceCommunicationService extends Service {
} }
if (btDeviceAddress != null && !isConnecting() && !isConnected()) { if (btDeviceAddress != null && !isConnecting() && !isConnected()) {
if (mDeviceSupport != null) { setDeviceSupport(null);
mDeviceSupport.dispose();
mDeviceSupport = null;
}
try { try {
DeviceSupportFactory factory = new DeviceSupportFactory(this); DeviceSupport deviceSupport = mFactory.createDeviceSupport(btDeviceAddress);
mDeviceSupport = factory.createDeviceSupport(btDeviceAddress); if (deviceSupport != null) {
if (mDeviceSupport != null) { setDeviceSupport(deviceSupport);
mGBDevice = mDeviceSupport.getDevice();
if (pair) { if (pair) {
mDeviceSupport.pair(); deviceSupport.pair();
} else { } else {
mDeviceSupport.connect(); deviceSupport.connect();
} }
} }
} catch (Exception e) { } catch (Exception e) {
GB.toast(this, getString(R.string.cannot_connect, e.getMessage()), Toast.LENGTH_SHORT, GB.ERROR); GB.toast(this, getString(R.string.cannot_connect, e.getMessage()), Toast.LENGTH_SHORT, GB.ERROR);
mDeviceSupport = null; setDeviceSupport(null);
mGBDevice = null;
} }
} else if (mGBDevice != null) { } else if (mGBDevice != null) {
// send an update at least // send an update at least
@ -233,6 +265,29 @@ public class DeviceCommunicationService extends Service {
return START_STICKY; 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() { private void start() {
if (!mStarted) { if (!mStarted) {
startForeground(GB.NOTIFICATION_ID, GB.createNotification(getString(R.string.gadgetbridge_running), this)); 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() { private boolean isConnected() {
return mGBDevice != null && mGBDevice.isConnected(); return mGBDevice != null && mGBDevice.isConnected();
} }
@ -260,9 +319,7 @@ public class DeviceCommunicationService extends Service {
LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver); LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver);
GB.setReceiversEnableState(false, this); // disable BroadcastReceivers GB.setReceiversEnableState(false, this); // disable BroadcastReceivers
if (mDeviceSupport != null) { setDeviceSupport(null);
mDeviceSupport.dispose();
}
NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 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 nm.cancel(GB.NOTIFICATION_ID); // need to do this because the updated notification wont be cancelled when service stops
} }

View File

@ -37,6 +37,10 @@ public abstract class AbstractServiceTestCase<T extends Service> {
return mContext; return mContext;
} }
public T getServiceInstance() {
return mServiceInstance;
}
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
mMockHelper = new MockHelper(); mMockHelper = new MockHelper();
@ -45,6 +49,7 @@ public abstract class AbstractServiceTestCase<T extends Service> {
mContext = createContext(mApplication); mContext = createContext(mApplication);
mNotificationManager = mMockHelper.createNotificationManager(mContext); mNotificationManager = mMockHelper.createNotificationManager(mContext);
mServiceInstance = createService(mServiceClass, mApplication, mNotificationManager); mServiceInstance = createService(mServiceClass, mApplication, mNotificationManager);
mServiceInstance.onCreate();
} }
@After @After
@ -55,10 +60,7 @@ public abstract class AbstractServiceTestCase<T extends Service> {
} }
public void startService(Intent intent) { public void startService(Intent intent) {
if (!wasStarted) {
wasStarted = true; wasStarted = true;
mServiceInstance.onCreate();
}
mServiceInstance.onStartCommand(intent, Service.START_FLAG_REDELIVERY, ID); mServiceInstance.onStartCommand(intent, Service.START_FLAG_REDELIVERY, ID);
} }

View File

@ -1,19 +1,42 @@
package nodomain.freeyourgadget.gadgetbridge.service; package nodomain.freeyourgadget.gadgetbridge.service;
import android.test.ServiceTestCase; import android.content.Context;
import junit.framework.TestCase;
import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; 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<DeviceCommunicationService> { public class DeviceCommunicationServiceTestCase extends AbstractServiceTestCase<DeviceCommunicationService> {
private static final java.lang.String TEST_DEVICE_ADDRESS = TestDeviceSupport.class.getName(); 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; private TestDeviceService mDeviceService;
@Mock
private TestDeviceSupport realSupport;
private TestDeviceSupport mockSupport;
public DeviceCommunicationServiceTestCase() { public DeviceCommunicationServiceTestCase() {
super(DeviceCommunicationService.class); super(DeviceCommunicationService.class);
@ -22,16 +45,38 @@ public class DeviceCommunicationServiceTestCase extends AbstractServiceTestCase<
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
super.setUp(); 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); mDeviceService = new TestDeviceService(this);
} }
@Test @Test
public void testStart() { public void testStart() {
assertFalse("Service was already", getServiceInstance().isStarted());
mDeviceService.start(); mDeviceService.start();
assertTrue("Service should be started", getServiceInstance().isStarted());
} }
@Test @Test
public void testConnect() { public void ensureConnected() {
mDeviceService.connect(TEST_DEVICE_ADDRESS); 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();
} }
} }

View File

@ -1,4 +1,4 @@
package nodomain.freeyourgadget.gadgetbridge.test; package nodomain.freeyourgadget.gadgetbridge.service;
import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothAdapter;
import android.content.Context; import android.content.Context;
@ -27,7 +27,9 @@ public class TestDeviceSupport extends AbstractDeviceSupport {
@Override @Override
public boolean connect() { public boolean connect() {
return false; gbDevice.setState(GBDevice.State.INITIALIZED);
gbDevice.sendDeviceUpdateIntent(getContext());
return true;
} }
@Override @Override