package betterbluetoothle.tests; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import betterbluetoothle.async.AsyncBluetoothLeScan; import betterbluetoothle.async.AsyncBluetoothLeScan.ScanResult; import java.util.ArrayList; import java.util.UUID; import org.jdeferred.ProgressCallback; import org.jdeferred.Promise; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; import static org.fest.assertions.api.Assertions.assertThat; import static org.mockito.Mockito.*; @RunWith(RobolectricTestRunner.class) public class AsyncBluetoothLeScanTest { private ArrayList<ScanResult> found = new ArrayList<ScanResult>(); @Before public void setup() { found.clear(); } @Test public void test_start_no_parameters_detects_all_devices() throws Exception { BluetoothAdapter adapter = mock(BluetoothAdapter.class); AsyncBluetoothLeScan scanner = new AsyncBluetoothLeScan(adapter); when(adapter.startLeScan(scanner)).thenReturn(true); BluetoothDevice d1 = mock(BluetoothDevice.class); BluetoothDevice d2 = mock(BluetoothDevice.class); Promise<Void, Void, ScanResult> promise = scanner.start(); promise.progress(new ProgressCallback<ScanResult>() { @Override public void onProgress(ScanResult result) { found.add(result); } }); scanner.onLeScan(d1, 0, new byte[]{ 0x02, 0x02, 0x01, 0x02 }); scanner.onLeScan(d2, 0, new byte[]{ 0x02, 0x02, 0x03, 0x04 }); assertThat(found.size()).isEqualTo(2); assertThat(found.get(0).device).isEqualTo(d1); assertThat(found.get(1).device).isEqualTo(d2); assertThat(promise.isPending()).isTrue(); assertThat(promise.isRejected()).isFalse(); assertThat(promise.isResolved()).isFalse(); } @Test public void test_start_one_service_uuid_detected() throws Exception { BluetoothAdapter adapter = mock(BluetoothAdapter.class); AsyncBluetoothLeScan scanner = new AsyncBluetoothLeScan(adapter); when(adapter.startLeScan(scanner)).thenReturn(true); BluetoothDevice d1 = mock(BluetoothDevice.class); BluetoothDevice d2 = mock(BluetoothDevice.class); Promise<Void, Void, ScanResult> promise = scanner.start(UUID.fromString("00000201-0000-1000-8000-00805f9b34fb")); promise.progress(new ProgressCallback<ScanResult>() { @Override public void onProgress(ScanResult result) { found.add(result); } }); scanner.onLeScan(d1, 0, new byte[]{ 0x02, 0x02, 0x01, 0x02 }); scanner.onLeScan(d2, 0, new byte[]{ 0x02, 0x02, 0x03, 0x04 }); assertThat(found.size()).isEqualTo(1); assertThat(found.get(0).device).isEqualTo(d1); assertThat(promise.isPending()).isTrue(); assertThat(promise.isRejected()).isFalse(); assertThat(promise.isResolved()).isFalse(); } @Test public void test_start_multiple_service_uuids_detected() throws Exception { BluetoothAdapter adapter = mock(BluetoothAdapter.class); AsyncBluetoothLeScan scanner = new AsyncBluetoothLeScan(adapter); when(adapter.startLeScan(scanner)).thenReturn(true); BluetoothDevice d1 = mock(BluetoothDevice.class); BluetoothDevice d2 = mock(BluetoothDevice.class); BluetoothDevice d3 = mock(BluetoothDevice.class); UUID services[] = new UUID[] { UUID.fromString("00000201-0000-1000-8000-00805f9b34fb"), UUID.fromString("00000403-0000-1000-8000-00805f9b34fb") }; Promise<Void, Void, ScanResult> promise = scanner.start(services); promise.progress(new ProgressCallback<ScanResult>() { @Override public void onProgress(ScanResult result) { found.add(result); } }); scanner.onLeScan(d1, 0, new byte[]{ 0x02, 0x02, 0x01, 0x02 }); scanner.onLeScan(d2, 0, new byte[]{ 0x02, 0x02, 0x03, 0x04 }); scanner.onLeScan(d3, 0, new byte[]{ 0x02, 0x02, 0x05, 0x06 }); assertThat(found.size()).isEqualTo(2); assertThat(found.get(0).device).isEqualTo(d1); assertThat(found.get(1).device).isEqualTo(d2); assertThat(promise.isPending()).isTrue(); assertThat(promise.isRejected()).isFalse(); assertThat(promise.isResolved()).isFalse(); } @Test public void test_startlescan_failure_rejects_promise() throws Exception { BluetoothAdapter adapter = mock(BluetoothAdapter.class); AsyncBluetoothLeScan scanner = new AsyncBluetoothLeScan(adapter); when(adapter.startLeScan(scanner)).thenReturn(false); Promise<Void, Void, ScanResult> promise = scanner.start(); assertThat(promise.isPending()).isFalse(); assertThat(promise.isRejected()).isTrue(); assertThat(promise.isResolved()).isFalse(); } @Test public void test_onlescan_passes_rssi_and_packet_to_progress() throws Exception { BluetoothAdapter adapter = mock(BluetoothAdapter.class); AsyncBluetoothLeScan scanner = new AsyncBluetoothLeScan(adapter); when(adapter.startLeScan(scanner)).thenReturn(true); Promise<Void, Void, ScanResult> promise = scanner.start(); promise.progress(new ProgressCallback<ScanResult>() { @Override public void onProgress(ScanResult result) { found.add(result); } }); byte[] packet = new byte[]{ 0x02, 0x02, 0x01, 0x02 }; scanner.onLeScan(mock(BluetoothDevice.class), 99, packet); assertThat(found.size()).isEqualTo(1); assertThat(found.get(0).rssi).isEqualTo(99); assertThat(found.get(0).bytes).isEqualTo(packet); } @Test public void test_stop_scan_resolves_promise() throws Exception { BluetoothAdapter adapter = mock(BluetoothAdapter.class); AsyncBluetoothLeScan scanner = new AsyncBluetoothLeScan(adapter); when(adapter.startLeScan(scanner)).thenReturn(true); Promise<Void, Void, ScanResult> promise = scanner.start(); scanner.stop(); assertThat(promise.isPending()).isFalse(); assertThat(promise.isRejected()).isFalse(); assertThat(promise.isResolved()).isTrue(); } @Test public void test_start_ends_previous_scan() throws Exception { BluetoothAdapter adapter = mock(BluetoothAdapter.class); AsyncBluetoothLeScan scanner = new AsyncBluetoothLeScan(adapter); when(adapter.startLeScan(scanner)).thenReturn(true); Promise<Void, Void, ScanResult> previous = scanner.start(); Promise<Void, Void, ScanResult> current = scanner.start(); assertThat(previous.isPending()).isFalse(); assertThat(previous.isRejected()).isFalse(); assertThat(previous.isResolved()).isTrue(); assertThat(current.isPending()).isTrue(); assertThat(current.isRejected()).isFalse(); assertThat(current.isResolved()).isFalse(); } }