package com.mopub.nativeads; import android.app.Activity; import android.content.Context; import android.location.Location; import android.location.LocationManager; import android.net.Uri; import android.telephony.TelephonyManager; import android.text.TextUtils; import com.mopub.common.MoPub; import com.mopub.common.test.support.SdkTestRunner; import com.mopub.mobileads.test.support.MoPubShadowTelephonyManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.Robolectric; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowLocationManager; import java.util.*; import static android.Manifest.permission.ACCESS_NETWORK_STATE; import static org.fest.assertions.api.Assertions.assertThat; import static org.robolectric.Robolectric.application; import static org.robolectric.Robolectric.shadowOf; @RunWith(SdkTestRunner.class) @Config(shadows = {MoPubShadowTelephonyManager.class}) public class NativeUrlGeneratorTest { public static final String AD_UNIT_ID = "1234"; private Activity context; private NativeUrlGenerator subject; private MoPubShadowTelephonyManager shadowTelephonyManager; @Before public void setup() { context = new Activity(); shadowOf(context).grantPermissions(ACCESS_NETWORK_STATE); shadowTelephonyManager = (MoPubShadowTelephonyManager) shadowOf((TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE)); } @Test public void generateNativeAdUrl_shouldIncludeDesiredAssetIfSet() throws Exception { EnumSet<RequestParameters.NativeAdAsset> assetsSet = EnumSet.of(RequestParameters.NativeAdAsset.TITLE); RequestParameters requestParameters = new RequestParameters.Builder().desiredAssets(assetsSet).build(); subject = new NativeUrlGenerator(context).withAdUnitId(AD_UNIT_ID).withRequest(requestParameters); String requestString = generateMinimumUrlString(); List<String> desiredAssets = getDesiredAssetsListFromRequestUrlString(requestString); assertThat(desiredAssets.size()).isEqualTo(1); assertThat(desiredAssets).contains("title"); } @Test public void generateNativeAdUrl_shouldIncludeDesiredAssetsIfSet() throws Exception { EnumSet<RequestParameters.NativeAdAsset> assetsSet = EnumSet.of(RequestParameters.NativeAdAsset.TITLE, RequestParameters.NativeAdAsset.TEXT, RequestParameters.NativeAdAsset.ICON_IMAGE); RequestParameters requestParameters = new RequestParameters.Builder().desiredAssets(assetsSet).build(); subject = new NativeUrlGenerator(context).withAdUnitId(AD_UNIT_ID).withRequest(requestParameters); String requestString = generateMinimumUrlString(); List<String> desiredAssets = getDesiredAssetsListFromRequestUrlString(requestString); assertThat(desiredAssets.size()).isEqualTo(3); assertThat(desiredAssets).contains("title", "text", "iconimage"); } @Test public void generateNativeAdUrl_shouldNotIncludeDesiredAssetsIfNotSet() throws Exception { subject = new NativeUrlGenerator(context).withAdUnitId(AD_UNIT_ID); String requestString = generateMinimumUrlString(); List<String> desiredAssets = getDesiredAssetsListFromRequestUrlString(requestString); assertThat(desiredAssets.size()).isEqualTo(0); } @Test public void generateNativeAdUrl_shouldNotIncludeDesiredAssetsIfNoAssetsAreSet() throws Exception { EnumSet<RequestParameters.NativeAdAsset> assetsSet = EnumSet.noneOf(RequestParameters.NativeAdAsset.class); RequestParameters requestParameters = new RequestParameters.Builder().desiredAssets(assetsSet).build(); subject = new NativeUrlGenerator(context).withAdUnitId(AD_UNIT_ID).withRequest(requestParameters); String requestString = generateMinimumUrlString(); List<String> desiredAssets = getDesiredAssetsListFromRequestUrlString(requestString); assertThat(desiredAssets.size()).isEqualTo(0); } @Test public void generateNativeAdUrl_needsButDoesNotHaveReadPhoneState_shouldNotContainOperatorName() { shadowTelephonyManager.setNeedsReadPhoneState(true); shadowTelephonyManager.setReadPhoneStatePermission(false); shadowTelephonyManager.setNetworkOperatorName("TEST_CARRIER"); subject = new NativeUrlGenerator(context).withAdUnitId(AD_UNIT_ID); String requestString = generateMinimumUrlString(); assertThat(getNetworkOperatorNameFromRequestUrl(requestString)).isNullOrEmpty(); } @Test public void generateNativeAdUrl_needsAndHasReadPhoneState_shouldContainOperatorName() { shadowTelephonyManager.setNeedsReadPhoneState(true); shadowTelephonyManager.setReadPhoneStatePermission(true); shadowTelephonyManager.setNetworkOperatorName("TEST_CARRIER"); subject = new NativeUrlGenerator(context).withAdUnitId(AD_UNIT_ID); String requestString = generateMinimumUrlString(); assertThat(getNetworkOperatorNameFromRequestUrl(requestString)).isEqualTo("TEST_CARRIER"); } @Test public void generateNativeAdUrl_doesNotNeedReadPhoneState_shouldContainOperatorName() { shadowTelephonyManager.setNeedsReadPhoneState(false); shadowTelephonyManager.setReadPhoneStatePermission(false); shadowTelephonyManager.setNetworkOperatorName("TEST_CARRIER"); subject = new NativeUrlGenerator(context).withAdUnitId(AD_UNIT_ID); String requestString = generateMinimumUrlString(); assertThat(getNetworkOperatorNameFromRequestUrl(requestString)).isEqualTo("TEST_CARRIER"); } @Test public void generateAdUrl_whenLocationServiceGpsProviderHasMostRecentLocation_shouldUseLocationServiceValue() { Location locationFromDeveloper = new Location(""); locationFromDeveloper.setLatitude(42); locationFromDeveloper.setLongitude(-42); locationFromDeveloper.setAccuracy(3.5f); locationFromDeveloper.setTime(1000); // Mock out the LocationManager's last known location to be more recent than the // developer-supplied location. ShadowLocationManager shadowLocationManager = Robolectric.shadowOf( (LocationManager) application.getSystemService(Context.LOCATION_SERVICE)); Location locationFromSdk = new Location(""); locationFromSdk.setLatitude(37); locationFromSdk.setLongitude(-122); locationFromSdk.setAccuracy(5.0f); locationFromSdk.setTime(2000); shadowLocationManager.setLastKnownLocation(LocationManager.GPS_PROVIDER, locationFromSdk); RequestParameters requestParameters = new RequestParameters.Builder() .location(locationFromDeveloper) .build(); subject = new NativeUrlGenerator(context).withAdUnitId(AD_UNIT_ID); String adUrl = subject.withRequest(requestParameters) .generateUrlString("ads.mopub.com"); assertThat(getParameterFromRequestUrl(adUrl, "ll")).isEqualTo("37.0,-122.0"); assertThat(getParameterFromRequestUrl(adUrl, "lla")).isEqualTo("5"); assertThat(getParameterFromRequestUrl(adUrl, "llsdk")).isEqualTo("1"); } @Test public void generateAdUrl_whenDeveloperSuppliesMoreRecentLocationThanLocationService_shouldUseDeveloperSuppliedLocation() { Location locationFromDeveloper = new Location(""); locationFromDeveloper.setLatitude(42); locationFromDeveloper.setLongitude(-42); locationFromDeveloper.setAccuracy(3.5f); locationFromDeveloper.setTime(1000); ShadowLocationManager shadowLocationManager = Robolectric.shadowOf( (LocationManager) application.getSystemService(Context.LOCATION_SERVICE)); // Mock out the LocationManager's last known location to be older than the // developer-supplied location. Location olderLocation = new Location(""); olderLocation.setLatitude(40); olderLocation.setLongitude(-105); olderLocation.setAccuracy(8.0f); olderLocation.setTime(500); shadowLocationManager.setLastKnownLocation(LocationManager.GPS_PROVIDER, olderLocation); RequestParameters requestParameters = new RequestParameters.Builder() .location(locationFromDeveloper) .build(); subject = new NativeUrlGenerator(context).withAdUnitId(AD_UNIT_ID); String adUrl = subject.withRequest(requestParameters) .generateUrlString("ads.mopub.com"); assertThat(getParameterFromRequestUrl(adUrl, "ll")).isEqualTo("42.0,-42.0"); assertThat(getParameterFromRequestUrl(adUrl, "lla")).isEqualTo("3"); assertThat(getParameterFromRequestUrl(adUrl, "llsdk")).isEmpty(); } @Test public void generateAdUrl_whenLocationServiceNetworkProviderHasMostRecentLocation_shouldUseLocationServiceValue() { Location locationFromDeveloper = new Location(""); locationFromDeveloper.setLatitude(42); locationFromDeveloper.setLongitude(-42); locationFromDeveloper.setAccuracy(3.5f); locationFromDeveloper.setTime(1000); // Mock out the LocationManager's last known location to be more recent than the // developer-supplied location. ShadowLocationManager shadowLocationManager = Robolectric.shadowOf( (LocationManager) application.getSystemService(Context.LOCATION_SERVICE)); Location locationFromSdk = new Location(""); locationFromSdk.setLatitude(38); locationFromSdk.setLongitude(-123); locationFromSdk.setAccuracy(5.0f); locationFromSdk.setTime(2000); shadowLocationManager.setLastKnownLocation(LocationManager.NETWORK_PROVIDER, locationFromSdk); RequestParameters requestParameters = new RequestParameters.Builder() .location(locationFromDeveloper) .build(); subject = new NativeUrlGenerator(context).withAdUnitId(AD_UNIT_ID); String adUrl = subject.withRequest(requestParameters) .generateUrlString("ads.mopub.com"); assertThat(getParameterFromRequestUrl(adUrl, "ll")).isEqualTo("38.0,-123.0"); assertThat(getParameterFromRequestUrl(adUrl, "lla")).isEqualTo("5"); assertThat(getParameterFromRequestUrl(adUrl, "llsdk")).isEqualTo("1"); } @Test public void enableLocation_shouldIncludeLocationInUrl() { MoPub.setLocationAwareness(MoPub.LocationAwareness.NORMAL); subject = new NativeUrlGenerator(context).withAdUnitId(AD_UNIT_ID); String requestString = generateMinimumUrlString(); assertThat(getParameterFromRequestUrl(requestString, "ll")).isNotNull(); } @Test public void disableLocation_shouldNotIncludeLocationInUrl() { MoPub.setLocationAwareness(MoPub.LocationAwareness.DISABLED); subject = new NativeUrlGenerator(context).withAdUnitId(AD_UNIT_ID); String requestString = generateMinimumUrlString(); assertThat(getParameterFromRequestUrl(requestString, "ll")).isNullOrEmpty(); } @Test public void disableLocationCollection_whenLocationServiceHasMostRecentLocation_shouldNotIncludeLocationInUrl() { MoPub.setLocationAwareness(MoPub.LocationAwareness.DISABLED); subject = new NativeUrlGenerator(context); // Mock out the LocationManager's last known location. ShadowLocationManager shadowLocationManager = Robolectric.shadowOf( (LocationManager) application.getSystemService(Context.LOCATION_SERVICE)); Location locationFromSdk = new Location(""); locationFromSdk.setLatitude(37); locationFromSdk.setLongitude(-122); locationFromSdk.setAccuracy(5.0f); locationFromSdk.setTime(2000); shadowLocationManager.setLastKnownLocation(LocationManager.GPS_PROVIDER, locationFromSdk); String requestString = generateMinimumUrlString(); assertThat(getParameterFromRequestUrl(requestString, "ll")).isNullOrEmpty(); } private List<String> getDesiredAssetsListFromRequestUrlString(String requestString) { Uri requestUri = Uri.parse(requestString); String desiredAssetsString = requestUri.getQueryParameter("assets"); return (desiredAssetsString == null) ? new ArrayList<String>() : Arrays.asList(desiredAssetsString.split(",")); } private String getNetworkOperatorNameFromRequestUrl(String requestString) { Uri requestUri = Uri.parse(requestString); String networkOperatorName = requestUri.getQueryParameter("cn"); if (TextUtils.isEmpty(networkOperatorName)) { return ""; } return networkOperatorName; } private String getParameterFromRequestUrl(String requestString, String key) { Uri requestUri = Uri.parse(requestString); String parameter = requestUri.getQueryParameter(key); if (TextUtils.isEmpty(parameter)) { return ""; } return parameter; } private String generateMinimumUrlString() { return subject.generateUrlString("ads.mopub.com"); } }