package org.altbeacon.beacon;
import static android.test.MoreAsserts.assertNotEqual;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
import org.robolectric.RobolectricTestRunner;
import org.junit.runner.RunWith;
import org.junit.Test;
import org.robolectric.annotation.Config;
import java.util.ArrayList;
import java.util.Collections;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@Config(sdk = 18)
@RunWith(RobolectricTestRunner.class)
/*
HOW TO SEE DEBUG LINES FROM YOUR UNIT TESTS:
1. set a line like this at the start of your test:
org.robolectric.shadows.ShadowLog.stream = System.err;
2. run the tests from the command line
3. Look at the test report file in your web browser, e.g.
file:///Users/dyoung/workspace/AndroidProximityLibrary/build/reports/tests/index.html
4. Expand the System.err section
*/
public class RegionTest {
@Test
public void testBeaconMatchesRegionWithSameIdentifiers() {
Beacon beacon = new AltBeacon.Builder().setId1("1").setId2("2").setId3("3").setRssi(4)
.setBeaconTypeCode(5).setTxPower(6).setBluetoothAddress("1:2:3:4:5:6").build();
Region region = new Region("myRegion", Identifier.parse("1"), Identifier.parse("2"), Identifier.parse("3"));
assertTrue("Beacon should match region with all identifiers the same", region.matchesBeacon(beacon));
}
@Test
public void testBeaconMatchesRegionWithSameIdentifier1() {
Beacon beacon = new AltBeacon.Builder().setId1("1").setId2("2").setId3("3").setRssi(4)
.setBeaconTypeCode(5).setTxPower(6).setBluetoothAddress("1:2:3:4:5:6").build();
Region region = new Region("myRegion", Identifier.parse("1"), null, null);
assertTrue("Beacon should match region with first identifier the same", region.matchesBeacon(beacon));
}
@Test
public void testBeaconMatchesRegionWithSameIdentifier1And2() {
Beacon beacon = new AltBeacon.Builder().setId1("1").setId2("2").setId3("3").setRssi(4)
.setBeaconTypeCode(5).setTxPower(6).setBluetoothAddress("1:2:3:4:5:6").build();
Region region = new Region("myRegion", Identifier.parse("1"), Identifier.parse("2"), null);
assertTrue("Beacon should match region with first two identifiers the same", region.matchesBeacon(beacon));
}
@Test
public void testBeaconMatchesRegionWithDifferentIdentifier1() {
Beacon beacon = new AltBeacon.Builder().setId1("1").setId2("2").setId3("3").setRssi(4)
.setBeaconTypeCode(5).setTxPower(6).setBluetoothAddress("1:2:3:4:5:6").build();
Region region = new Region("myRegion", Identifier.parse("22222"), null, null);
assertTrue("Beacon should not match region with first identifier different", !region.matchesBeacon(beacon));
}
@Test
public void testBeaconMatchesRegionWithShorterIdentifierList() {
Beacon beacon = new AltBeacon.Builder().setId1("1").setId2("2").setId3("3").setRssi(4)
.setBeaconTypeCode(5).setTxPower(6).setBluetoothAddress("1:2:3:4:5:6").build();
Region region = new Region("myRegion", Collections.singletonList(Identifier.parse("1")));
assertTrue("Beacon should match region with first identifier equal and shorter Identifier list", region.matchesBeacon(beacon));
}
@Test
public void testBeaconMatchesRegionWithSingleNullIdentifierList() {
Beacon beacon = new AltBeacon.Builder().setId1("1").setId2("2").setId3("3").setRssi(4)
.setBeaconTypeCode(5).setTxPower(6).setBluetoothAddress("1:2:3:4:5:6").build();
ArrayList<Identifier> identifiers=new ArrayList<>();
identifiers.add(null);
Region region=new Region("all-beacons-region",identifiers);
assertTrue("Beacon should match region with first identifier null and shorter Identifier list", region.matchesBeacon(beacon));
}
@Test
public void testBeaconDoesntMatchRegionWithLongerIdentifierList() {
Beacon beacon = new Beacon.Builder().setId1("1").setId2("2").setRssi(4)
.setBeaconTypeCode(5).setTxPower(6).setBluetoothAddress("1:2:3:4:5:6").build();
Region region = new Region("myRegion", Identifier.parse("1"), Identifier.parse("2"), Identifier.parse("3"));
assertFalse("Beacon should not match region with more identifers than the beacon", region.matchesBeacon(beacon));
}
@Test
public void testBeaconDoesMatchRegionWithLongerIdentifierListWithSomeNull() {
Beacon beacon = new Beacon.Builder().setId1("1").setId2("2").setRssi(4)
.setBeaconTypeCode(5).setTxPower(6).setBluetoothAddress("1:2:3:4:5:6").build();
Region region = new Region("myRegion", null, null, null);
assertTrue("Beacon should match region with more identifers than the beacon, if the region identifiers are null", region.matchesBeacon(beacon));
}
@Test
public void testBeaconMatchesRegionWithSameBluetoothMac() {
Beacon beacon = new AltBeacon.Builder().setId1("1").setId2("2").setId3("3").setRssi(4)
.setBeaconTypeCode(5).setTxPower(6).setBluetoothAddress("01:02:03:04:05:06").build();
Region region = new Region("myRegion", "01:02:03:04:05:06");
assertTrue("Beacon should match region with mac the same", region.matchesBeacon(beacon));
}
@Test
public void testBeaconDoesNotMatchRegionWithDiffrentBluetoothMac() {
Beacon beacon = new AltBeacon.Builder().setId1("1").setId2("2").setId3("3").setRssi(4)
.setBeaconTypeCode(5).setTxPower(6).setBluetoothAddress("01:02:03:04:05:06").build();
Region region = new Region("myRegion", "01:02:03:04:05:99");
assertFalse("Beacon should match region with mac the same", region.matchesBeacon(beacon));
}
@Test
public void testBeaconMatchesRegionWithSameBluetoothMacAndIdentifiers() {
Beacon beacon = new AltBeacon.Builder().setId1("1").setId2("2").setId3("3").setRssi(4)
.setBeaconTypeCode(5).setTxPower(6).setBluetoothAddress("01:02:03:04:05:06").build();
ArrayList identifiers = new ArrayList<Identifier>();
identifiers.add(Identifier.parse("1"));
identifiers.add(Identifier.parse("2"));
identifiers.add(Identifier.parse("3"));
Region region = new Region("myRegion", identifiers , "01:02:03:04:05:06");
assertTrue("Beacon should match region with mac the same", region.matchesBeacon(beacon));
}
@Test
public void testCanSerialize() throws Exception {
org.robolectric.shadows.ShadowLog.stream = System.err;
Region region = new Region("myRegion", Identifier.parse("1"), Identifier.parse("2"), null);
byte[] serializedRegion = convertToBytes(region);
Region region2 = (Region) convertFromBytes(serializedRegion);
assertEquals("Right number of identifiers after deserialization", 3, region2.mIdentifiers.size());
assertEquals("uniqueId is same after deserialization", region.getUniqueId(), region2.getUniqueId());
assertEquals("id1 is same after deserialization", region.getIdentifier(0), region2.getIdentifier(0));
assertEquals("id2 is same after deserialization", region.getIdentifier(1), region2.getIdentifier(1));
assertNull("id3 is null before deserialization", region.getIdentifier(2));
assertNull("id3 is null after deserialization", region2.getIdentifier(2));
}
@Test
public void testCanSerializeWithMac() throws Exception {
org.robolectric.shadows.ShadowLog.stream = System.err;
Region region = new Region("myRegion", "1B:2a:03:4C:6E:9F");
byte[] serializedRegion = convertToBytes(region);
Region region2 = (Region) convertFromBytes(serializedRegion);
assertEquals("Right number of identifiers after deserialization", 0, region2.mIdentifiers.size());
assertEquals("ac is same after deserialization", region.getBluetoothAddress(), region2.getBluetoothAddress());
}
@Test
public void rejectsInvalidMac() {
org.robolectric.shadows.ShadowLog.stream = System.err;
try {
Region region = new Region("myRegion", "this string is not a valid mac address!");
assertTrue("IllegalArgumentException should have been thrown", false);
}
catch (IllegalArgumentException e) {
assertEquals("Error message should be as expected",
"Invalid mac address: 'this string is not a valid mac address!' Must be 6 hex bytes separated by colons.",
e.getMessage());
}
}
@Test
public void testToString() {
Region region = new Region("myRegion", Identifier.parse("1"), Identifier.parse("2"), null);
assertEquals("id1: 1 id2: 2 id3: null", region.toString());
}
@Test
public void testConvenienceIdentifierAccessors() {
Region region = new Region("myRegion", Identifier.parse("1"), Identifier.parse("2"), Identifier.parse("3"));
assertEquals("1", region.getId1().toString());
assertEquals("2", region.getId2().toString());
assertEquals("3", region.getId3().toString());
}
// utilty methods for testing serialization
private byte[] convertToBytes(Object object) throws IOException {
try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bos)) {
out.writeObject(object);
return bos.toByteArray();
}
}
private Object convertFromBytes(byte[] bytes) throws IOException, ClassNotFoundException {
try (ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
ObjectInputStream in = new ObjectInputStream(bis)) {
return in.readObject();
}
}
}