package org.physical_web.physicalweb;
import org.physical_web.collection.PhysicalWebCollection;
import org.physical_web.collection.PwPair;
import org.physical_web.collection.PwsClient;
import org.physical_web.collection.PwsResult;
import org.physical_web.collection.UrlDevice;
import android.content.Context;
import android.content.res.Resources;
import org.json.JSONException;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Matchers;
import org.mockito.Mockito;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
/**
* Unit tests for Utils.
*/
public class UtilsTest {
private static final String GOOGLE_PWS_URL = "https://physicalweb.googleapis.com";
private static final int GOOGLE_PWS_VERSION = 2;
private static final String PROD_PWS_URL = "https://url-caster.appspot.com";
private static final int PROD_PWS_VERSION = 1;
public static final String BLE_DEVICE_TYPE = "ble";
private static final String SCAN_TIME_KEY = "scantime";
private static final String PUBLIC_KEY = "public";
private static final String RSSI_KEY = "rssi";
private static final String TYPE_KEY = "type";
private static final String TXPOWER_KEY = "tx";
private static final String PWS_TRIP_TIME_KEY = "pwstriptime";
private static final String GOOGLE_API_KEY_RESOURCE_KEY = "google_api_key";
private static final String GOOGLE_API_KEY_RESOURCE_TYPE = "string";
private static final String SAMPLE_API_KEY = "key";
private static final String SAMPLE_PACKAGE_NAME = "test";
List<String> siteUrls = Arrays.asList((new String[]{"www.google.com", "www.google.com/maps"}));
@Before
public void setUp() throws Exception {
for (String url : siteUrls) {
if (Utils.isFavorite(url)) {
Utils.toggleFavorite(url);
}
}
}
/*
* Tests containsFavorite with empty list.
*
* Prerequisites:
* - Set of favorites is empty
* Procedure:
* 1. Verify list does not contain favorite
*/
@Test
public void testContainsFavoriteEmptyList() throws Exception {
List<PwPair> pairs = new ArrayList<>();
Assert.assertFalse(Utils.containsFavorite(pairs));
}
/*
* Tests containsFavorite with a one element list. Also exercises isFavorite and toggleFavorite.
*
* Prerequisites:
* - Set of favorites is empty
* Procedure:
* 1. Add 1 PwPair to list
* 2. Verify list does not contain favorite
* 3. Add site used for PwPair to favorites
* 4. Verify list contains favorite
*/
@Test
public void testContainsFavoriteOneItem() throws Exception {
String siteUrl = siteUrls.get(0);
List<PwPair> pairs = new ArrayList<>();
pairs.add(new PwPair(null, new PwsResult("", siteUrl)));
Assert.assertFalse(Utils.containsFavorite(pairs));
Utils.toggleFavorite(siteUrl);
Assert.assertTrue(Utils.containsFavorite(pairs));
}
/*
* Tests containsFavorite with a two element list. Also exercises isFavorite and toggleFavorite.
*
* Prerequisites:
* - Set of favorites is empty
* Procedure:
* 1. Add 1 PwPair to list
* 2. Verify list does not contain favorite
* 3. Add site used for PwPair to favorites
* 4. Verify list contains favorite
*/
@Test
public void testContainsFavoriteTwoItems() throws Exception {
String siteUrl = siteUrls.get(0);
List<PwPair> pairs = new ArrayList<>();
pairs.add(new PwPair(null, new PwsResult("", siteUrl)));
pairs.add(new PwPair(null, new PwsResult("", siteUrls.get(1))));
Assert.assertFalse(Utils.containsFavorite(pairs));
Utils.toggleFavorite(siteUrl);
Assert.assertTrue(Utils.containsFavorite(pairs));
}
/*
* Tests formatEndpointForSharedPreferences.
*
* Procedure:
* 1. Verify string with null values and 0
* 2. Verify string with empty values and the minimum integer value
* 3. Verify string with non empty values and the maximum integer value
*/
@Test
public void testFormatEndpointForSharedPreferences() throws Exception {
String url = null;
int version = 0;
String key = null;
Assert.assertArrayEquals("Null values", new String[]{"", Integer.toString(version)},
Utils.formatEndpointForSharedPrefernces(url, version, key).split("\0"));
url = "";
version = Integer.MIN_VALUE;
key = "";
Assert.assertArrayEquals("Empty Strings and min", new String[]{url, Integer.toString(version)},
Utils.formatEndpointForSharedPrefernces(url, version, key).split("\0"));
url = "url";
version = Integer.MAX_VALUE;
key = SAMPLE_API_KEY;
Assert.assertArrayEquals("Non empty strings and max",
new String[]{url, Integer.toString(version), key},
Utils.formatEndpointForSharedPrefernces(url, version, key).split("\0"));
}
/*
* Tests getDefaultPwsEndpointPreferenceString. Also exercises isGoogleApiKeyAvailable and
* formatEndpointForSharedPreferences.
*
* Procedure:
* 1. Configure there to not be an api key
* 2. Verify default is the prod pws
* 3. Configure there to be an api key
* 4. Verify default is the Google pws
*/
@Test
public void testGetDefaultPwsEndpointPreferenceString() throws Exception {
int resId = 1;
String apiKey = SAMPLE_API_KEY;
String packageName = SAMPLE_PACKAGE_NAME;
Resources mockResources = Mockito.mock(Resources.class);
Mockito.when(mockResources.getIdentifier(GOOGLE_API_KEY_RESOURCE_KEY,
GOOGLE_API_KEY_RESOURCE_TYPE, packageName)).thenReturn(0);
Context mockContext = Mockito.mock(Context.class);
Mockito.when(mockContext.getResources()).thenReturn(mockResources);
Mockito.when(mockContext.getPackageName()).thenReturn(packageName);
Assert.assertEquals(PROD_PWS_URL + "\0" + PROD_PWS_VERSION + "\0",
Utils.getDefaultPwsEndpointPreferenceString(mockContext));
Mockito.when(mockResources.getIdentifier(GOOGLE_API_KEY_RESOURCE_KEY,
GOOGLE_API_KEY_RESOURCE_TYPE, packageName)).thenReturn(resId);
Mockito.when(mockContext.getString(resId)).thenReturn(apiKey);
Assert.assertEquals(GOOGLE_PWS_URL + "\0" + GOOGLE_PWS_VERSION + "\0" + apiKey,
Utils.getDefaultPwsEndpointPreferenceString(mockContext));
}
/*
* Tests getDefaultPwsEndpointPreferenceString. Also exercises isGoogleApiKeyAvailable and
* formatEndpointForSharedPreferences.
*
* Procedure:
* 1. Configure there to be an api key
* 2. Verify setEnpoint is called with Google pws
*/
@Test
public void testSetPwsEndPointToGoogle() throws Exception {
int resId = 1;
String apiKey = SAMPLE_API_KEY;
String packageName = SAMPLE_PACKAGE_NAME;
Resources mockResources = Mockito.mock(Resources.class);
Mockito.when(mockResources.getIdentifier(GOOGLE_API_KEY_RESOURCE_KEY,
GOOGLE_API_KEY_RESOURCE_TYPE, packageName)).thenReturn(resId);
Context mockContext = Mockito.mock(Context.class);
Mockito.when(mockContext.getResources()).thenReturn(mockResources);
Mockito.when(mockContext.getString(resId)).thenReturn(apiKey);
Mockito.when(mockContext.getPackageName()).thenReturn(packageName);
PwsClient client = Mockito.mock(PwsClient.class);
Utils.setPwsEndPointToGoogle(mockContext, client);
Mockito.verify(client, Mockito.times(1)).setEndpoint(GOOGLE_PWS_URL, GOOGLE_PWS_VERSION,
apiKey);
}
/*
* Tests isGoogleApiKeyAvailable.
*
* Procedure:
* 1. Configure there to not be an api key
* 2. Verify that there is no api key
* 3. Configure there to be an api key
* 4. Verify that there is an api key
*/
@Test
public void testIsGoogleApiKeyAvailable() throws Exception {
String packageName = "test";
Resources resources = Mockito.mock(Resources.class);
Mockito.when(resources.getIdentifier(GOOGLE_API_KEY_RESOURCE_KEY,
GOOGLE_API_KEY_RESOURCE_TYPE, packageName)).thenReturn(0);
Context context = Mockito.mock(Context.class);
Mockito.when(context.getResources()).thenReturn(resources);
Mockito.when(context.getPackageName()).thenReturn(packageName);
Assert.assertFalse(Utils.isGoogleApiKeyAvailable(context));
Mockito.when(resources.getIdentifier(GOOGLE_API_KEY_RESOURCE_KEY,
GOOGLE_API_KEY_RESOURCE_TYPE, packageName)).thenReturn(1);
Assert.assertTrue(Utils.isGoogleApiKeyAvailable(context));
}
/*
* Tests getGoogleApiKey. Also exercises isGoogleApiKeyAvailable.
*
* Procedure:
* 1. Configure there to be an api key
* 2. Verify api key is equal to apiKey
* 3. Configure there to not be an api key
* 4. Verify api key is empty
*/
@Test
public void testGetGoogleApiKey() throws Exception {
int resId = 1;
String apiKey = SAMPLE_API_KEY;
String packageName = SAMPLE_PACKAGE_NAME;
Resources resources = Mockito.mock(Resources.class);
Mockito.when(resources.getIdentifier(GOOGLE_API_KEY_RESOURCE_KEY, GOOGLE_API_KEY_RESOURCE_TYPE,
packageName)).thenReturn(resId);
Context context = Mockito.mock(Context.class);
Mockito.when(context.getResources()).thenReturn(resources);
Mockito.when(context.getString(resId)).thenReturn(apiKey);
Mockito.when(context.getPackageName()).thenReturn(packageName);
Assert.assertEquals(apiKey, Utils.getGoogleApiKey(context));
resId = 0;
Mockito.when(resources.getIdentifier(GOOGLE_API_KEY_RESOURCE_KEY, GOOGLE_API_KEY_RESOURCE_TYPE,
packageName)).thenReturn(resId);
Mockito.when(context.getString(resId)).thenReturn(apiKey);
Assert.assertEquals("", Utils.getGoogleApiKey(context));
}
/*
* Tests getTopRankedPwPairByGroupId with an empty collection. Also exercises getGroupId.
*
* Procedure:
* 1. Configure there to be an empty list of PwPairs to be sorted
* 2. Verify top ranked PwPair is null
*/
@Test
public void testGetTopRankedPwPairByGroupIdEmptyCollection() throws Exception {
String groupId = "";
PhysicalWebCollection mockCollection = Mockito.mock(PhysicalWebCollection.class);
List<PwPair> pairs = Arrays.asList(new PwPair[]{});
Mockito.when(mockCollection.getGroupedPwPairsSortedByRank(
(Comparator<PwPair>) Matchers.anyObject())).thenReturn(pairs);
Assert.assertNull(Utils.getTopRankedPwPairByGroupId(mockCollection, groupId));
}
/*
* Tests getTopRankedPwPairByGroupId with one item in the collection. Also exercises getGroupId.
*
* Procedure:
* 1. Configure there to be an list of 1 PwPair to be sorted
* 2. Verify top ranked PwPair for groupId that is in list is the expected pair
* 3. Verify top ranked PwPair for groupId that is not in list is null
*/
@Test
public void testGetTopRankedPwPairByGroupIdOneItemCollection() throws Exception {
String groupId = "group";
PwsResult mockResult = Mockito.mock(PwsResult.class);
Mockito.when(mockResult.getGroupId()).thenReturn(groupId);
PwPair mockPair = Mockito.mock(PwPair.class);
Mockito.when(mockPair.getPwsResult()).thenReturn(mockResult);
PhysicalWebCollection mockCollection = Mockito.mock(PhysicalWebCollection.class);
List<PwPair> pairs = Arrays.asList(new PwPair[]{mockPair});
Mockito.when(mockCollection.getGroupedPwPairsSortedByRank(
(Comparator<PwPair>) Matchers.anyObject())).thenReturn(pairs);
Assert.assertEquals(mockPair, Utils.getTopRankedPwPairByGroupId(mockCollection, groupId));
// Check with groupId that is not in the list of pairs.
Assert.assertNull(Utils.getTopRankedPwPairByGroupId(mockCollection, "not in list"));
}
/*
* Tests getTopRankedPwPairByGroupId with two items in the collection. Also exercises getGroupId.
*
* Procedure:
* 1. Configure there to be an list of 2 PwPairs with the same ids to be sorted
* 2. Verify top ranked PwPair for groupId that is in list is the expected pair
* 3. Verify top ranked PwPair for groupId that is not in list is null
*/
@Test
public void testGetTopRankedPwPairByGroupIdTwoItemCollection() throws Exception {
String groupId = "group";
PwsResult mockResult1 = Mockito.mock(PwsResult.class);
Mockito.when(mockResult1.getGroupId()).thenReturn(groupId);
PwsResult mockResult2 = Mockito.mock(PwsResult.class);
Mockito.when(mockResult2.getGroupId()).thenReturn(groupId);
PwPair mockPair1 = Mockito.mock(PwPair.class);
Mockito.when(mockPair1.getPwsResult()).thenReturn(mockResult1);
PwPair mockPair2 = Mockito.mock(PwPair.class);
Mockito.when(mockPair2.getPwsResult()).thenReturn(mockResult2);
PhysicalWebCollection mockCollection = Mockito.mock(PhysicalWebCollection.class);
List<PwPair> pairs = Arrays.asList(new PwPair[]{mockPair1, mockPair2});
Mockito.when(mockCollection.getGroupedPwPairsSortedByRank(
(Comparator<PwPair>) Matchers.anyObject())).thenReturn(pairs);
Assert.assertEquals(mockPair1, Utils.getTopRankedPwPairByGroupId(mockCollection, groupId));
// Check with groupId that is not in the list of pairs.
Assert.assertNull(Utils.getTopRankedPwPairByGroupId(mockCollection, "not in list"));
}
/*
* Tests getBitmapIcon.
*
* Procedure:
* 1. Configure there to be a null icon
* 2. Verify null is returned
*/
@Test
public void testGetBitmapIcon() throws Exception {
String iconUrl = "icon";
PwsResult mockResult = Mockito.mock(PwsResult.class);
Mockito.when(mockResult.getIconUrl()).thenReturn(iconUrl);
PhysicalWebCollection mockCollection = Mockito.mock(PhysicalWebCollection.class);
Mockito.when(mockCollection.getIcon(iconUrl)).thenReturn(null);
Assert.assertNull(Utils.getBitmapIcon(mockCollection, mockResult));
}
/*
* Tests getScanTimeMillis.
*
* Procedure:
* 1. Configure mock device to return scanTime
* 2. Verify scanTime is returned
*/
@Test
public void testGetScanTimeMillis() throws Exception {
long scanTime = 0L;
UrlDevice mockDevice = Mockito.mock(UrlDevice.class);
Mockito.when(mockDevice.getExtraLong(SCAN_TIME_KEY)).thenReturn(scanTime);
Assert.assertEquals(scanTime, Utils.getScanTimeMillis(mockDevice));
}
/*
* Tests getScanTimeMillis.
*
* Procedure:
* 1. Configure mock device to throw JSONException
* 2. Verify RuntimeException is thrown
*/
@Test(expected = RuntimeException.class)
public void testGetScanTimeMillisWithException() throws Exception {
UrlDevice mockDevice = Mockito.mock(UrlDevice.class);
Mockito.when(mockDevice.getExtraLong(SCAN_TIME_KEY)).thenThrow(new JSONException(""));
Utils.getScanTimeMillis(mockDevice);
}
/*
* Tests isPublic.
*
* Procedure:
* 1. Configure mock device to return true
* 2. Verify true is returned
* 3. Configure mock device to return false
* 4. Verify false is returned
*/
@Test
public void testIsPublic() throws Exception {
UrlDevice mockDevice = Mockito.mock(UrlDevice.class);
Mockito.when(mockDevice.optExtraBoolean(PUBLIC_KEY, true)).thenReturn(true);
Assert.assertTrue(Utils.isPublic(mockDevice));
Mockito.when(mockDevice.optExtraBoolean(PUBLIC_KEY, true)).thenReturn(false);
Assert.assertFalse(Utils.isPublic(mockDevice));
}
/*
* Tests isBleUrlDevice.
*
* Procedure:
* 1. Configure mock device return RSSI
* 2. Verify true is returned
* 3. Configure mock device to throw JSONException
* 4. Verify false is returned
*/
@Test
public void testIsBleUrlDevice() throws Exception {
UrlDevice mockDevice = Mockito.mock(UrlDevice.class);
Mockito.when(mockDevice.optExtraString(TYPE_KEY, "")).thenReturn(BLE_DEVICE_TYPE);
Assert.assertTrue(Utils.isBleUrlDevice(mockDevice));
Mockito.when(mockDevice.optExtraString(TYPE_KEY, "")).thenReturn("not ble");
Assert.assertFalse(Utils.isBleUrlDevice(mockDevice));
}
/*
* Tests getRssi.
*
* Procedure:
* 1. Configure mock device to return RSSI
* 2. Verify RSSI is returned
*/
@Test
public void testGetRssi() throws Exception {
int rssi = Integer.MAX_VALUE;
UrlDevice mockDevice = Mockito.mock(UrlDevice.class);
Mockito.when(mockDevice.getExtraInt(RSSI_KEY)).thenReturn(rssi);
Assert.assertEquals(rssi, Utils.getRssi(mockDevice));
}
/*
* Tests getRssi.
*
* Procedure:
* 1. Configure mock device to throw JSONException
* 2. Verify RuntimeException is thrown
*/
@Test(expected = RuntimeException.class)
public void testGetRssiWithException() throws Exception {
UrlDevice mockDevice = Mockito.mock(UrlDevice.class);
Mockito.when(mockDevice.getExtraInt(RSSI_KEY)).thenThrow(new JSONException(""));
Utils.getRssi(mockDevice);
}
/*
* Tests getTxPower.
*
* Procedure:
* 1. Configure mock device to return Tx Power
* 2. Verify Tx Power is returned
*/
@Test
public void testGetTxPower() throws Exception {
int txPower = Integer.MIN_VALUE;
UrlDevice mockDevice = Mockito.mock(UrlDevice.class);
Mockito.when(mockDevice.getExtraInt(TXPOWER_KEY)).thenReturn(txPower);
Assert.assertEquals(txPower, Utils.getTxPower(mockDevice));
}
/*
* Tests getTxPower.
*
* Procedure:
* 1. Configure mock device to throw JSONException
* 2. Verify RuntimeException is thrown
*/
@Test(expected = RuntimeException.class)
public void testGetTxPowerWithException() throws Exception {
UrlDevice mockDevice = Mockito.mock(UrlDevice.class);
Mockito.when(mockDevice.getExtraInt(TXPOWER_KEY)).thenThrow(new JSONException(""));
Utils.getTxPower(mockDevice);
}
/*
* Tests getPwsTripTimeMillis.
*
* Procedure:
* 1. Configure mock result to return trip time
* 2. Verify trip time is returned
*/
@Test
public void testGetPwsTripTimeMillis() throws Exception {
long tripTime = Long.MAX_VALUE;
PwsResult mockResult = Mockito.mock(PwsResult.class);
Mockito.when(mockResult.getExtraLong(PWS_TRIP_TIME_KEY)).thenReturn(tripTime);
Assert.assertEquals(tripTime, Utils.getPwsTripTimeMillis(mockResult));
}
/*
* Tests getPwsTripTimeMillis.
*
* Procedure:
* 1. Configure mock result to throw JSONException
* 2. Verify RuntimeException is thrown
*/
@Test(expected = RuntimeException.class)
public void testGetPwsTripTimeMillisWithException() throws Exception {
PwsResult mockResult = Mockito.mock(PwsResult.class);
Mockito.when(mockResult.getExtraLong(PWS_TRIP_TIME_KEY)).thenThrow(new JSONException(""));
Utils.getPwsTripTimeMillis(mockResult);
}
/*
* Tests getGroupId.
*
* Procedure:
* 1. Configure mock result to return groupId
* 2. Verify groupId is returned
*/
@Test
public void testGetGroupId() throws Exception {
String groupId = "group";
PwsResult mockResult = Mockito.mock(PwsResult.class);
Mockito.when(mockResult.getGroupId()).thenReturn(groupId);
Assert.assertEquals(groupId, Utils.getGroupId(mockResult));
}
/*
* Tests getGroupId.
*
* Procedure:
* 1. Configure mock result to return: {groupId:null, title:non Empty, siteUrl:https://url}
* 2. Verify url + title is returned
* 3. Configure mock result to return: {groupId:empty string, title:non Empty,
* siteUrl:url containing '\'}
* 4. Verify url is returned
*/
@Test
public void testGetGroupIdNotDefined() throws Exception {
String url = siteUrls.get(0);
String title = "Google";
PwsResult mockResult = Mockito.mock(PwsResult.class);
// Test null groupId and use site url that URI can parse
Mockito.when(mockResult.getGroupId()).thenReturn(null);
Mockito.when(mockResult.getSiteUrl()).thenReturn("https://" + url);
Mockito.when(mockResult.getTitle()).thenReturn(title);
Assert.assertEquals(url + title, Utils.getGroupId(mockResult));
// Test empty groupId and use site url that causes URISyntaxException
url = "\\invalid";
Mockito.when(mockResult.getSiteUrl()).thenReturn(url);
Mockito.when(mockResult.getGroupId()).thenReturn("");
Assert.assertEquals(url, Utils.getGroupId(mockResult));
}
}