From 6bf01bd87efa4fb8e38cdca31fab2159ed4c717f Mon Sep 17 00:00:00 2001 From: Tim Rijckaert Date: Fri, 29 May 2020 16:11:23 +0200 Subject: [PATCH 1/8] Allow the possibility to fetch bids with a PublisherAdRequest$Builder. This allows users to add options after Prebid mutated the Request --- .../mobile/prebidkotlindemo/DemoActivity.kt | 6 ++--- .../src/main/java/org/prebid/mobile/Util.java | 22 +++++++++++++++++-- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/DemoActivity.kt b/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/DemoActivity.kt index a5c0c1a01..bae4e92a3 100644 --- a/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/DemoActivity.kt +++ b/Example/PrebidDemoKotlin/src/main/java/org/prebid/mobile/prebidkotlindemo/DemoActivity.kt @@ -105,15 +105,13 @@ class DemoActivity : AppCompatActivity() { adFrame.addView(dfpAdView) val builder = PublisherAdRequest.Builder() - val request = builder.build() - //region PrebidMobile Mobile API 1.0 usage val millis = intent.getIntExtra(Constants.AUTO_REFRESH_NAME, 0) adUnit!!.setAutoRefreshPeriodMillis(millis) - adUnit!!.fetchDemand(request, object : OnCompleteListener { + adUnit!!.fetchDemand(builder, object : OnCompleteListener { override fun onComplete(resultCode: ResultCode) { this@DemoActivity.resultCode = resultCode - dfpAdView.loadAd(request) + dfpAdView.loadAd(builder.build()) refreshCount++ } }) diff --git a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/Util.java b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/Util.java index 0850d89f0..5cae0e08d 100644 --- a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/Util.java +++ b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/Util.java @@ -24,6 +24,7 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.text.TextUtils; +import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.webkit.ValueCallback; @@ -55,6 +56,7 @@ public class Util { static final String MOPUB_BANNER_VIEW_CLASS = "com.mopub.mobileads.MoPubView"; static final String MOPUB_INTERSTITIAL_CLASS = "com.mopub.mobileads.MoPubInterstitial"; static final String DFP_AD_REQUEST_CLASS = "com.google.android.gms.ads.doubleclick.PublisherAdRequest"; + static final String DFP_AD_REQUEST_BUILDER_CLASS = "com.google.android.gms.ads.doubleclick.PublisherAdRequest$Builder"; private static final Random RANDOM = new Random(); private static final HashSet reservedKeys; private static final int MoPubQueryStringLimit = 4000; @@ -412,7 +414,7 @@ static boolean supportedAdObject(Object adObj) { if (adObj.getClass() == getClassFromString(MOPUB_BANNER_VIEW_CLASS) || adObj.getClass() == getClassFromString(MOPUB_INTERSTITIAL_CLASS) || adObj.getClass() == getClassFromString(DFP_AD_REQUEST_CLASS) - + || adObj.getClass() == getClassFromString(DFP_AD_REQUEST_BUILDER_CLASS) || adObj.getClass() == HashMap.class) return true; return false; @@ -425,7 +427,10 @@ static void apply(HashMap bids, Object adObj) { handleMoPubKeywordsUpdate(bids, adObj); } else if (adObj.getClass() == getClassFromString(DFP_AD_REQUEST_CLASS)) { handleDFPCustomTargetingUpdate(bids, adObj); - } else if (adObj.getClass() == HashMap.class) { + } else if (adObj.getClass() == getClassFromString(DFP_AD_REQUEST_BUILDER_CLASS)) { + handleDFPBuilderCustomTargetingUpdate(bids, adObj); + } + else if (adObj.getClass() == HashMap.class) { if (bids != null && !bids.isEmpty()) { ((HashMap) adObj).putAll(bids); } @@ -468,6 +473,15 @@ private static void handleDFPCustomTargetingUpdate(HashMap bids, } } + private static void handleDFPBuilderCustomTargetingUpdate(HashMap bids, Object adObj) { + removeUsedCustomTargetingForDFPBuilder(adObj); + if (bids != null && !bids.isEmpty()) { + for (String key : bids.keySet()) { + Util.callMethodOnObject(adObj, "addCustomTargeting", key, bids.get(key)); + } + } + } + private static void addReservedKeys(String key) { synchronized (reservedKeys) { reservedKeys.add(key); @@ -507,6 +521,10 @@ private static void removeUsedCustomTargetingForDFP(Object adRequestObj) { } } + private static void removeUsedCustomTargetingForDFPBuilder(Object adRequestObj) { + // TODO: How to remove stuff from the custom targeting map? + } + static void addValue(Map> map, E key, U value) { Set valueSet = map.get(key); From 3014820fec2aa25a43619ed7a0495b57ec07bf29 Mon Sep 17 00:00:00 2001 From: Tim Rijckaert Date: Fri, 29 May 2020 16:13:54 +0200 Subject: [PATCH 2/8] We don't need to remove items from the custom targeting since we will always create a new item anyway --- .../src/main/java/org/prebid/mobile/Util.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/Util.java b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/Util.java index 5cae0e08d..065cb872d 100644 --- a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/Util.java +++ b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/Util.java @@ -474,7 +474,6 @@ private static void handleDFPCustomTargetingUpdate(HashMap bids, } private static void handleDFPBuilderCustomTargetingUpdate(HashMap bids, Object adObj) { - removeUsedCustomTargetingForDFPBuilder(adObj); if (bids != null && !bids.isEmpty()) { for (String key : bids.keySet()) { Util.callMethodOnObject(adObj, "addCustomTargeting", key, bids.get(key)); @@ -521,10 +520,6 @@ private static void removeUsedCustomTargetingForDFP(Object adRequestObj) { } } - private static void removeUsedCustomTargetingForDFPBuilder(Object adRequestObj) { - // TODO: How to remove stuff from the custom targeting map? - } - static void addValue(Map> map, E key, U value) { Set valueSet = map.get(key); From 167b450835bea1ccd406bc104469498a745cb8a9 Mon Sep 17 00:00:00 2001 From: Oleksandr Pavliuchyk Date: Tue, 9 Jun 2020 23:28:09 +0300 Subject: [PATCH 3/8] - `handleDFPBuilderCustomTargetingUpdate()` was upgraded - DemoApp uses `PublisherAdRequest.Builder` - `testPublisherAdRequestBuilder()` test was added --- .../mobile/app/DFPBannerComplexTest.java | 140 +++++++++++++++++- .../org/prebid/mobile/app/DemoActivity.java | 28 ++-- .../src/main/java/org/prebid/mobile/Util.java | 3 +- 3 files changed, 157 insertions(+), 14 deletions(-) diff --git a/Example/PrebidDemoJava/src/androidTest/java/org/prebid/mobile/app/DFPBannerComplexTest.java b/Example/PrebidDemoJava/src/androidTest/java/org/prebid/mobile/app/DFPBannerComplexTest.java index df88e2248..e89f0f628 100644 --- a/Example/PrebidDemoJava/src/androidTest/java/org/prebid/mobile/app/DFPBannerComplexTest.java +++ b/Example/PrebidDemoJava/src/androidTest/java/org/prebid/mobile/app/DFPBannerComplexTest.java @@ -17,6 +17,9 @@ package org.prebid.mobile.app; import android.graphics.Color; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; import android.view.View; import android.widget.FrameLayout; @@ -28,10 +31,13 @@ import com.google.android.gms.ads.doubleclick.PublisherAdRequest; import com.google.android.gms.ads.doubleclick.PublisherAdView; +import org.junit.After; import org.junit.Assert; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import org.prebid.mobile.AdUnit; import org.prebid.mobile.BannerAdUnit; import org.prebid.mobile.Host; import org.prebid.mobile.LogUtil; @@ -40,14 +46,137 @@ import org.prebid.mobile.ResultCode; import org.prebid.mobile.Util; +import java.io.IOException; import java.util.concurrent.CountDownLatch; +import javax.annotation.Nullable; + +import okhttp3.HttpUrl; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; + import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; @RunWith(AndroidJUnit4.class) public class DFPBannerComplexTest { @Rule - public ActivityTestRule m = new ActivityTestRule<>(TestActivity.class); + public ActivityTestRule testActivityRule = new ActivityTestRule<>(TestActivity.class); + + MockWebServer mockServer; + Handler handler; + + @Before + public void setUp() { + handler = new Handler(Looper.getMainLooper()); + mockServer = new MockWebServer(); + + + try { + mockServer.start(); + } catch (IOException e) { + fail("Mock server start failed."); + } + } + + @After + public void tearDown() throws Exception { + mockServer.shutdown(); + mockServer = null; + } + + + @Test + public void testPublisherAdRequestBuilder() throws Exception { + + //given + HttpUrl httpUrl = mockServer.url("/"); + Host.CUSTOM.setHostUrl(httpUrl.toString()); + PrebidMobile.setPrebidServerAccountId("1001"); + + mockServer.enqueue(new MockResponse().setResponseCode(200).setBody("{\n" + + " \"seatbid\": [\n" + + " {\n" + + " \"bid\": [\n" + + " {\n" + + " \"ext\": {\n" + + " \"prebid\": {\n" + + " \"targeting\": {\n" + + " \"hb_env\": \"mobile-app\",\n" + + " \"hb_cache_hostpath\": \"https://prebid-cache-europe.rubiconproject.com/cache\",\n" + + " \"hb_size_rubicon\": \"300x250\",\n" + + " \"hb_cache_id\": \"a2f41588-4727-425c-9ef0-3b382debef1e\",\n" + + " \"hb_cache_path_rubicon\": \"/cache\",\n" + + " \"hb_cache_host_rubicon\": \"prebid-cache-europe.rubiconproject.com\",\n" + + " \"hb_pb\": \"1.20\",\n" + + " \"hb_pb_rubicon\": \"1.20\",\n" + + " \"hb_cache_id_rubicon\": \"a2f41588-4727-425c-9ef0-3b382debef1e\",\n" + + " \"hb_cache_path\": \"/cache\",\n" + + " \"hb_size\": \"300x250\",\n" + + " \"hb_cache_hostpath_rubicon\": \"https://prebid-cache-europe.rubiconproject.com/cache\",\n" + + " \"hb_env_rubicon\": \"mobile-app\",\n" + + " \"hb_bidder\": \"rubicon\",\n" + + " \"hb_bidder_rubicon\": \"rubicon\",\n" + + " \"hb_cache_host\": \"prebid-cache-europe.rubiconproject.com\"\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + " ]\n" + + " }\n" + + " ]\n" + + "}")); + + + + final ReferenceWrapper customTargetingBundleWrapper = new ReferenceWrapper<>(); + + //when + final PublisherAdRequest.Builder builder = new PublisherAdRequest.Builder(); + AdUnit adUnit = new BannerAdUnit("1001-1", 300, 250); + + + adUnit.fetchDemand(builder, new OnCompleteListener() { + @Override + public void onComplete(ResultCode resultCode) { + + + PublisherAdRequest publisherAdRequest = builder.build(); + Bundle customTargetingBundle = publisherAdRequest.getCustomTargeting(); + + customTargetingBundleWrapper.value = customTargetingBundle; + } + }); + + try { + Thread.sleep(1_000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + //then + Bundle customTargetingBundle = customTargetingBundleWrapper.value; + + assertEquals(16, customTargetingBundle.keySet().size()); + + assertEquals("mobile-app", customTargetingBundle.getString("hb_env")); + assertEquals("https://prebid-cache-europe.rubiconproject.com/cache", customTargetingBundle.getString("hb_cache_hostpath")); + assertEquals("300x250", customTargetingBundle.getString("hb_size_rubicon")); + assertEquals("a2f41588-4727-425c-9ef0-3b382debef1e", customTargetingBundle.getString("hb_cache_id")); + assertEquals("/cache", customTargetingBundle.getString("hb_cache_path_rubicon")); + assertEquals("prebid-cache-europe.rubiconproject.com", customTargetingBundle.getString("hb_cache_host_rubicon")); + assertEquals("1.20", customTargetingBundle.getString("hb_pb")); + assertEquals("1.20", customTargetingBundle.getString("hb_pb_rubicon")); + assertEquals("a2f41588-4727-425c-9ef0-3b382debef1e", customTargetingBundle.getString("hb_cache_id_rubicon")); + assertEquals("/cache", customTargetingBundle.getString("hb_cache_path")); + assertEquals("300x250", customTargetingBundle.getString("hb_size")); + assertEquals("https://prebid-cache-europe.rubiconproject.com/cache", customTargetingBundle.getString("hb_cache_hostpath_rubicon")); + assertEquals("mobile-app", customTargetingBundle.getString("hb_env_rubicon")); + assertEquals("rubicon", customTargetingBundle.getString("hb_bidder")); + assertEquals("rubicon", customTargetingBundle.getString("hb_bidder_rubicon")); + assertEquals("prebid-cache-europe.rubiconproject.com", customTargetingBundle.getString("hb_cache_host")); + + } //30x250 -> 728x90 @Test @@ -59,7 +188,7 @@ public void testRubiconDFPBannerResizeSanityAppCheckTest() throws Exception { PrebidMobile.setPrebidServerAccountId(Constants.PBS_ACCOUNT_ID_RUBICON); PrebidMobile.setStoredAuctionResponse(Constants.PBS_STORED_RESPONSE_300x250_RUBICON); - TestActivity activity = m.getActivity(); + TestActivity activity = testActivityRule.getActivity(); final IntegerWrapper firstTransactionCount = new IntegerWrapper(); final IntegerWrapper secondTransactionCount = new IntegerWrapper(); @@ -240,9 +369,16 @@ public void run() { } + private static class ReferenceWrapper { + + @Nullable + T value = null; + } + private static class IntegerWrapper { int value = 0; + //TODO remove getValue() public int getValue() { return value; } diff --git a/Example/PrebidDemoJava/src/main/java/org/prebid/mobile/app/DemoActivity.java b/Example/PrebidDemoJava/src/main/java/org/prebid/mobile/app/DemoActivity.java index dde3bfa5d..12639d882 100644 --- a/Example/PrebidDemoJava/src/main/java/org/prebid/mobile/app/DemoActivity.java +++ b/Example/PrebidDemoJava/src/main/java/org/prebid/mobile/app/DemoActivity.java @@ -83,6 +83,7 @@ public class DemoActivity extends AppCompatActivity implements MoPubRewardedVide AdUnit adUnit; ResultCode resultCode; + //Used by UI tests PublisherAdRequest request; MoPubView adView; @@ -278,7 +279,6 @@ public void onAdLoaded() { nativeAdView.setAdSizes(AdSize.FLUID); adFrame.addView(nativeAdView); final PublisherAdRequest.Builder builder = new PublisherAdRequest.Builder(); - request = builder.build(); NativeAdUnit nativeAdUnit = (NativeAdUnit) adUnit; nativeAdUnit.setContextType(NativeAdUnit.CONTEXT_TYPE.SOCIAL_CENTRIC); nativeAdUnit.setPlacementType(NativeAdUnit.PLACEMENTTYPE.CONTENT_FEED); @@ -324,12 +324,13 @@ public void onAdLoaded() { nativeAdUnit.addAsset(cta); int millis = getIntent().getIntExtra(Constants.AUTO_REFRESH_NAME, 0); nativeAdUnit.setAutoRefreshPeriodMillis(millis); - nativeAdUnit.fetchDemand(request, new OnCompleteListener() { + nativeAdUnit.fetchDemand(builder, new OnCompleteListener() { @Override public void onComplete(ResultCode resultCode) { DemoActivity.this.resultCode = resultCode; + + request = builder.build(); nativeAdView.loadAd(request); - DemoActivity.this.request = request; refreshCount++; } }); @@ -445,14 +446,17 @@ public void failure(@NonNull PbFindSizeError error) { }); final PublisherAdRequest.Builder builder = new PublisherAdRequest.Builder(); - final PublisherAdRequest request = builder.build(); + //region PrebidMobile Mobile API 1.0 usage int millis = getIntent().getIntExtra(Constants.AUTO_REFRESH_NAME, 0); adUnit.setAutoRefreshPeriodMillis(millis); - adUnit.fetchDemand(request, new OnCompleteListener() { + adUnit.fetchDemand(builder, new OnCompleteListener() { @Override public void onComplete(ResultCode resultCode) { + DemoActivity.this.resultCode = resultCode; + + PublisherAdRequest request = builder.build(); amBanner.loadAd(request); refreshCount++; } @@ -622,12 +626,13 @@ public void onInterstitialDismissed(MoPubInterstitial interstitial) { private void loadAMInterstitial() { int millis = getIntent().getIntExtra(Constants.AUTO_REFRESH_NAME, 0); adUnit.setAutoRefreshPeriodMillis(millis); - PublisherAdRequest.Builder builder = new PublisherAdRequest.Builder(); - request = builder.build(); - adUnit.fetchDemand(request, new OnCompleteListener() { + final PublisherAdRequest.Builder builder = new PublisherAdRequest.Builder(); + adUnit.fetchDemand(builder, new OnCompleteListener() { @Override public void onComplete(ResultCode resultCode) { DemoActivity.this.resultCode = resultCode; + + PublisherAdRequest request = builder.build(); amInterstitial.loadAd(request); refreshCount++; } @@ -738,12 +743,13 @@ private void setupMPRubiconRewardedVideo() { //Load private void loadAMRewardedVideo() { - PublisherAdRequest.Builder builder = new PublisherAdRequest.Builder(); - request = builder.build(); - adUnit.fetchDemand(request, new OnCompleteListener() { + final PublisherAdRequest.Builder builder = new PublisherAdRequest.Builder(); + adUnit.fetchDemand(builder, new OnCompleteListener() { @Override public void onComplete(ResultCode resultCode) { DemoActivity.this.resultCode = resultCode; + + PublisherAdRequest request = builder.build(); amRewardedAd.loadAd(request, new RewardedAdLoadCallback() { @Override public void onRewardedAdLoaded() { diff --git a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/Util.java b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/Util.java index 065cb872d..63187db5f 100644 --- a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/Util.java +++ b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/Util.java @@ -24,7 +24,6 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.text.TextUtils; -import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.webkit.ValueCallback; @@ -474,9 +473,11 @@ private static void handleDFPCustomTargetingUpdate(HashMap bids, } private static void handleDFPBuilderCustomTargetingUpdate(HashMap bids, Object adObj) { + removeUsedCustomTargetingForDFP(adObj); if (bids != null && !bids.isEmpty()) { for (String key : bids.keySet()) { Util.callMethodOnObject(adObj, "addCustomTargeting", key, bids.get(key)); + addReservedKeys(key); } } } From e35273f8b3d16bfbe28025230ad99c1721a6516d Mon Sep 17 00:00:00 2001 From: Oleksandr Pavliuchyk Date: Wed, 10 Jun 2020 12:56:21 +0300 Subject: [PATCH 4/8] - fixed auto-refresh with PublisherAdRequest.Builder - `testPublisherAdRequestBuilderWithRefresh()` was added --- .../mobile/app/DFPBannerComplexTest.java | 101 ++++++++++++++++-- .../src/main/java/org/prebid/mobile/Util.java | 4 +- 2 files changed, 98 insertions(+), 7 deletions(-) diff --git a/Example/PrebidDemoJava/src/androidTest/java/org/prebid/mobile/app/DFPBannerComplexTest.java b/Example/PrebidDemoJava/src/androidTest/java/org/prebid/mobile/app/DFPBannerComplexTest.java index e89f0f628..6d56d9487 100644 --- a/Example/PrebidDemoJava/src/androidTest/java/org/prebid/mobile/app/DFPBannerComplexTest.java +++ b/Example/PrebidDemoJava/src/androidTest/java/org/prebid/mobile/app/DFPBannerComplexTest.java @@ -70,8 +70,6 @@ public class DFPBannerComplexTest { public void setUp() { handler = new Handler(Looper.getMainLooper()); mockServer = new MockWebServer(); - - try { mockServer.start(); } catch (IOException e) { @@ -85,7 +83,6 @@ public void tearDown() throws Exception { mockServer = null; } - @Test public void testPublisherAdRequestBuilder() throws Exception { @@ -127,15 +124,12 @@ public void testPublisherAdRequestBuilder() throws Exception { " ]\n" + "}")); - - final ReferenceWrapper customTargetingBundleWrapper = new ReferenceWrapper<>(); //when final PublisherAdRequest.Builder builder = new PublisherAdRequest.Builder(); AdUnit adUnit = new BannerAdUnit("1001-1", 300, 250); - adUnit.fetchDemand(builder, new OnCompleteListener() { @Override public void onComplete(ResultCode resultCode) { @@ -178,6 +172,101 @@ public void onComplete(ResultCode resultCode) { } + @Test + public void testPublisherAdRequestBuilderWithRefresh() throws Exception { + + //given + HttpUrl httpUrl = mockServer.url("/"); + Host.CUSTOM.setHostUrl(httpUrl.toString()); + PrebidMobile.setPrebidServerAccountId("1001"); + + mockServer.enqueue(new MockResponse().setResponseCode(200).setBody("{\n" + + " \"seatbid\": [\n" + + " {\n" + + " \"bid\": [\n" + + " {\n" + + " \"ext\": {\n" + + " \"prebid\": {\n" + + " \"targeting\": {\n" + + " \"hb_cache_id\": \"top_bid_1\",\n" + + " \"key1\": \"value1\"\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + " ]\n" + + " }\n" + + " ]\n" + + "}")); + + mockServer.enqueue(new MockResponse().setResponseCode(200).setBody("{\n" + + " \"seatbid\": [\n" + + " {\n" + + " \"bid\": [\n" + + " {\n" + + " \"ext\": {\n" + + " \"prebid\": {\n" + + " \"targeting\": {\n" + + " \"hb_cache_id\": \"top_bid_2\",\n" + + " \"key5\": \"value5\"\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + " ]\n" + + " }\n" + + " ]\n" + + "}")); + + final ReferenceWrapper customTargetingBundleWrapper1 = new ReferenceWrapper<>(); + final ReferenceWrapper customTargetingBundleWrapper2 = new ReferenceWrapper<>(); + final IntegerWrapper requestCountWrapper = new IntegerWrapper(); + + //when + final PublisherAdRequest.Builder builder = new PublisherAdRequest.Builder(); + AdUnit adUnit = new BannerAdUnit("1001-1", 300, 250); + adUnit.setAutoRefreshPeriodMillis(30_001); + + adUnit.fetchDemand(builder, new OnCompleteListener() { + @Override + public void onComplete(ResultCode resultCode) { + + requestCountWrapper.value++; + + PublisherAdRequest publisherAdRequest = builder.build(); + Bundle customTargetingBundle = publisherAdRequest.getCustomTargeting(); + + if (requestCountWrapper.value == 1) { + customTargetingBundleWrapper1.value = (Bundle)customTargetingBundle.clone(); + } else if (requestCountWrapper.value == 2) { + customTargetingBundleWrapper2.value = (Bundle)customTargetingBundle.clone(); + } + } + }); + + try { + Thread.sleep(31_000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + //then + Bundle customTargetingBundle1 = customTargetingBundleWrapper1.value; + Bundle customTargetingBundle2 = customTargetingBundleWrapper2.value; + + assertEquals(2, requestCountWrapper.value); + + assertEquals(2, customTargetingBundle1.keySet().size()); + assertEquals("top_bid_1", customTargetingBundle1.getString("hb_cache_id")); + assertEquals("value1", customTargetingBundle1.getString("key1")); + + assertEquals(2, customTargetingBundle2.keySet().size()); + assertEquals(null, customTargetingBundle2.getString("key1")); + assertEquals("top_bid_2", customTargetingBundle2.getString("hb_cache_id")); + assertEquals("value5", customTargetingBundle2.getString("key5")); + + } + //30x250 -> 728x90 @Test public void testRubiconDFPBannerResizeSanityAppCheckTest() throws Exception { diff --git a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/Util.java b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/Util.java index 63187db5f..267ba667f 100644 --- a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/Util.java +++ b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/Util.java @@ -473,7 +473,9 @@ private static void handleDFPCustomTargetingUpdate(HashMap bids, } private static void handleDFPBuilderCustomTargetingUpdate(HashMap bids, Object adObj) { - removeUsedCustomTargetingForDFP(adObj); + Object publisherAdRequest = Util.callMethodOnObject(adObj, "build"); + removeUsedCustomTargetingForDFP(publisherAdRequest); + if (bids != null && !bids.isEmpty()) { for (String key : bids.keySet()) { Util.callMethodOnObject(adObj, "addCustomTargeting", key, bids.get(key)); From 5bae5dd7093c972184a1af3610a2342f14bdc4fa Mon Sep 17 00:00:00 2001 From: Oleksandr Pavliuchyk Date: Wed, 10 Jun 2020 13:15:35 +0300 Subject: [PATCH 5/8] - minor refactoring - small tests improvements --- .../src/main/java/org/prebid/mobile/Util.java | 32 +++++++++---------- .../test/java/org/prebid/mobile/UtilTest.java | 17 +++++++--- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/Util.java b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/Util.java index 267ba667f..27e706e8b 100644 --- a/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/Util.java +++ b/PrebidMobile/PrebidMobile-core/src/main/java/org/prebid/mobile/Util.java @@ -54,8 +54,8 @@ public class Util { static final String MOPUB_BANNER_VIEW_CLASS = "com.mopub.mobileads.MoPubView"; static final String MOPUB_INTERSTITIAL_CLASS = "com.mopub.mobileads.MoPubInterstitial"; - static final String DFP_AD_REQUEST_CLASS = "com.google.android.gms.ads.doubleclick.PublisherAdRequest"; - static final String DFP_AD_REQUEST_BUILDER_CLASS = "com.google.android.gms.ads.doubleclick.PublisherAdRequest$Builder"; + static final String AD_MANAGER_REQUEST_CLASS = "com.google.android.gms.ads.doubleclick.PublisherAdRequest"; + static final String AD_MANAGER_REQUEST_BUILDER_CLASS = "com.google.android.gms.ads.doubleclick.PublisherAdRequest$Builder"; private static final Random RANDOM = new Random(); private static final HashSet reservedKeys; private static final int MoPubQueryStringLimit = 4000; @@ -412,8 +412,8 @@ static boolean supportedAdObject(Object adObj) { if (adObj == null) return false; if (adObj.getClass() == getClassFromString(MOPUB_BANNER_VIEW_CLASS) || adObj.getClass() == getClassFromString(MOPUB_INTERSTITIAL_CLASS) - || adObj.getClass() == getClassFromString(DFP_AD_REQUEST_CLASS) - || adObj.getClass() == getClassFromString(DFP_AD_REQUEST_BUILDER_CLASS) + || adObj.getClass() == getClassFromString(AD_MANAGER_REQUEST_CLASS) + || adObj.getClass() == getClassFromString(AD_MANAGER_REQUEST_BUILDER_CLASS) || adObj.getClass() == HashMap.class) return true; return false; @@ -424,10 +424,10 @@ static void apply(HashMap bids, Object adObj) { if (adObj.getClass() == getClassFromString(MOPUB_BANNER_VIEW_CLASS) || adObj.getClass() == getClassFromString(MOPUB_INTERSTITIAL_CLASS)) { handleMoPubKeywordsUpdate(bids, adObj); - } else if (adObj.getClass() == getClassFromString(DFP_AD_REQUEST_CLASS)) { - handleDFPCustomTargetingUpdate(bids, adObj); - } else if (adObj.getClass() == getClassFromString(DFP_AD_REQUEST_BUILDER_CLASS)) { - handleDFPBuilderCustomTargetingUpdate(bids, adObj); + } else if (adObj.getClass() == getClassFromString(AD_MANAGER_REQUEST_CLASS)) { + handleAdManagerCustomTargeting(bids, adObj); + } else if (adObj.getClass() == getClassFromString(AD_MANAGER_REQUEST_BUILDER_CLASS)) { + handleAdManagerBuilderCustomTargeting(bids, adObj); } else if (adObj.getClass() == HashMap.class) { if (bids != null && !bids.isEmpty()) { @@ -458,10 +458,10 @@ private static void handleMoPubKeywordsUpdate(HashMap bids, Obje } } - private static void handleDFPCustomTargetingUpdate(HashMap bids, Object adObj) { - removeUsedCustomTargetingForDFP(adObj); + private static void handleAdManagerCustomTargeting(HashMap bids, Object publisherAdRequest) { + removeUsedCustomTargetingForDFP(publisherAdRequest); if (bids != null && !bids.isEmpty()) { - Bundle bundle = (Bundle) Util.callMethodOnObject(adObj, "getCustomTargeting"); + Bundle bundle = (Bundle) Util.callMethodOnObject(publisherAdRequest, "getCustomTargeting"); if (bundle != null) { // retrieve keywords from mopub adview for (String key : bids.keySet()) { @@ -472,13 +472,13 @@ private static void handleDFPCustomTargetingUpdate(HashMap bids, } } - private static void handleDFPBuilderCustomTargetingUpdate(HashMap bids, Object adObj) { - Object publisherAdRequest = Util.callMethodOnObject(adObj, "build"); + private static void handleAdManagerBuilderCustomTargeting(HashMap bids, Object publisherAdRequestBuilder) { + Object publisherAdRequest = Util.callMethodOnObject(publisherAdRequestBuilder, "build"); removeUsedCustomTargetingForDFP(publisherAdRequest); if (bids != null && !bids.isEmpty()) { for (String key : bids.keySet()) { - Util.callMethodOnObject(adObj, "addCustomTargeting", key, bids.get(key)); + Util.callMethodOnObject(publisherAdRequestBuilder, "addCustomTargeting", key, bids.get(key)); addReservedKeys(key); } } @@ -514,8 +514,8 @@ private static void removeUsedKeywordsForMoPub(Object adViewObj) { } } - private static void removeUsedCustomTargetingForDFP(Object adRequestObj) { - Bundle bundle = (Bundle) Util.callMethodOnObject(adRequestObj, "getCustomTargeting"); + private static void removeUsedCustomTargetingForDFP(Object publisherAdRequest) { + Bundle bundle = (Bundle) Util.callMethodOnObject(publisherAdRequest, "getCustomTargeting"); if (bundle != null && reservedKeys != null) { for (String key : reservedKeys) { bundle.remove(key); diff --git a/PrebidMobile/src/test/java/org/prebid/mobile/UtilTest.java b/PrebidMobile/src/test/java/org/prebid/mobile/UtilTest.java index 70f8488d9..24c27bb6b 100644 --- a/PrebidMobile/src/test/java/org/prebid/mobile/UtilTest.java +++ b/PrebidMobile/src/test/java/org/prebid/mobile/UtilTest.java @@ -63,7 +63,8 @@ public void testCallMethodOnObject() throws Exception { public void testGetClassFromString() throws Exception { assertEquals(MoPubView.class, Util.getClassFromString(Util.MOPUB_BANNER_VIEW_CLASS)); assertEquals(MoPubInterstitial.class, Util.getClassFromString(Util.MOPUB_INTERSTITIAL_CLASS)); - assertEquals(PublisherAdRequest.class, Util.getClassFromString(Util.DFP_AD_REQUEST_CLASS)); + assertEquals(PublisherAdRequest.class, Util.getClassFromString(Util.AD_MANAGER_REQUEST_CLASS)); + assertEquals(PublisherAdRequest.Builder.class, Util.getClassFromString(Util.AD_MANAGER_REQUEST_BUILDER_CLASS)); } @Test @@ -93,18 +94,22 @@ public void testApplyBidsToDFOAdObject() throws Exception { HashMap bids = new HashMap<>(); bids.put("hb_pb", "0.50"); bids.put("hb_cache_id", "123456"); + + Util.apply(bids, builder); PublisherAdRequest request = builder.build(); + assertEquals(3, request.getCustomTargeting().size()); + assertEquals("Value", request.getCustomTargeting().get("Key")); + assertEquals("0.50", request.getCustomTargeting().get("hb_pb")); + assertEquals("123456", request.getCustomTargeting().get("hb_cache_id")); + Util.apply(bids, request); assertEquals(3, request.getCustomTargeting().size()); - assertTrue(request.getCustomTargeting().containsKey("Key")); assertEquals("Value", request.getCustomTargeting().get("Key")); - assertTrue(request.getCustomTargeting().containsKey("hb_pb")); assertEquals("0.50", request.getCustomTargeting().get("hb_pb")); - assertTrue(request.getCustomTargeting().containsKey("hb_cache_id")); assertEquals("123456", request.getCustomTargeting().get("hb_cache_id")); + Util.apply(null, request); assertEquals(1, request.getCustomTargeting().size()); - assertTrue(request.getCustomTargeting().containsKey("Key")); assertEquals("Value", request.getCustomTargeting().get("Key")); } @@ -117,6 +122,8 @@ public void testSupportedAdObject() throws Exception { assertTrue(Util.supportedAdObject(interstitial)); PublisherAdRequest request = new PublisherAdRequest.Builder().build(); assertTrue(Util.supportedAdObject(request)); + PublisherAdRequest.Builder requestBuilder = new PublisherAdRequest.Builder(); + assertTrue(Util.supportedAdObject(requestBuilder)); Object object = new Object(); assertFalse(Util.supportedAdObject(object)); } From 7af3c86b4293363ed4cc33919f568379c3c23f88 Mon Sep 17 00:00:00 2001 From: Oleksandr Pavliuchyk Date: Wed, 10 Jun 2020 14:53:50 +0300 Subject: [PATCH 6/8] tests were fixed --- ...lexTest.java => AdManagerComplexTest.java} | 67 +++++++++---------- 1 file changed, 30 insertions(+), 37 deletions(-) rename Example/PrebidDemoJava/src/androidTest/java/org/prebid/mobile/app/{DFPBannerComplexTest.java => AdManagerComplexTest.java} (91%) diff --git a/Example/PrebidDemoJava/src/androidTest/java/org/prebid/mobile/app/DFPBannerComplexTest.java b/Example/PrebidDemoJava/src/androidTest/java/org/prebid/mobile/app/AdManagerComplexTest.java similarity index 91% rename from Example/PrebidDemoJava/src/androidTest/java/org/prebid/mobile/app/DFPBannerComplexTest.java rename to Example/PrebidDemoJava/src/androidTest/java/org/prebid/mobile/app/AdManagerComplexTest.java index 6d56d9487..5e915d3c8 100644 --- a/Example/PrebidDemoJava/src/androidTest/java/org/prebid/mobile/app/DFPBannerComplexTest.java +++ b/Example/PrebidDemoJava/src/androidTest/java/org/prebid/mobile/app/AdManagerComplexTest.java @@ -18,8 +18,6 @@ import android.graphics.Color; import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; import android.view.View; import android.widget.FrameLayout; @@ -32,7 +30,6 @@ import com.google.android.gms.ads.doubleclick.PublisherAdView; import org.junit.After; -import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -59,16 +56,14 @@ import static org.junit.Assert.fail; @RunWith(AndroidJUnit4.class) -public class DFPBannerComplexTest { +public class AdManagerComplexTest { @Rule public ActivityTestRule testActivityRule = new ActivityTestRule<>(TestActivity.class); MockWebServer mockServer; - Handler handler; @Before public void setUp() { - handler = new Handler(Looper.getMainLooper()); mockServer = new MockWebServer(); try { mockServer.start(); @@ -87,10 +82,6 @@ public void tearDown() throws Exception { public void testPublisherAdRequestBuilder() throws Exception { //given - HttpUrl httpUrl = mockServer.url("/"); - Host.CUSTOM.setHostUrl(httpUrl.toString()); - PrebidMobile.setPrebidServerAccountId("1001"); - mockServer.enqueue(new MockResponse().setResponseCode(200).setBody("{\n" + " \"seatbid\": [\n" + " {\n" + @@ -124,6 +115,13 @@ public void testPublisherAdRequestBuilder() throws Exception { " ]\n" + "}")); + //important line + PrebidMobile.setPrebidServerHost(Host.CUSTOM); + + HttpUrl httpUrl = mockServer.url("/testPublisherAdRequestBuilder"); + Host.CUSTOM.setHostUrl(httpUrl.toString()); + PrebidMobile.setPrebidServerAccountId("1001"); + final ReferenceWrapper customTargetingBundleWrapper = new ReferenceWrapper<>(); //when @@ -174,11 +172,7 @@ public void onComplete(ResultCode resultCode) { @Test public void testPublisherAdRequestBuilderWithRefresh() throws Exception { - //given - HttpUrl httpUrl = mockServer.url("/"); - Host.CUSTOM.setHostUrl(httpUrl.toString()); - PrebidMobile.setPrebidServerAccountId("1001"); mockServer.enqueue(new MockResponse().setResponseCode(200).setBody("{\n" + " \"seatbid\": [\n" + @@ -218,6 +212,14 @@ public void testPublisherAdRequestBuilderWithRefresh() throws Exception { " ]\n" + "}")); + + //important line + PrebidMobile.setPrebidServerHost(Host.CUSTOM); + + HttpUrl httpUrl = mockServer.url("/testPublisherAdRequestBuilderWithRefresh"); + Host.CUSTOM.setHostUrl(httpUrl.toString()); + PrebidMobile.setPrebidServerAccountId("1001"); + final ReferenceWrapper customTargetingBundleWrapper1 = new ReferenceWrapper<>(); final ReferenceWrapper customTargetingBundleWrapper2 = new ReferenceWrapper<>(); final IntegerWrapper requestCountWrapper = new IntegerWrapper(); @@ -264,7 +266,6 @@ public void onComplete(ResultCode resultCode) { assertEquals(null, customTargetingBundle2.getString("key1")); assertEquals("top_bid_2", customTargetingBundle2.getString("hb_cache_id")); assertEquals("value5", customTargetingBundle2.getString("key5")); - } //30x250 -> 728x90 @@ -275,7 +276,7 @@ public void testRubiconDFPBannerResizeSanityAppCheckTest() throws Exception { PrebidMobile.setPrebidServerHost(Host.RUBICON); PrebidMobile.setPrebidServerAccountId(Constants.PBS_ACCOUNT_ID_RUBICON); - PrebidMobile.setStoredAuctionResponse(Constants.PBS_STORED_RESPONSE_300x250_RUBICON); + PrebidMobile.setStoredAuctionResponse("1001-rubicon-300x250"); TestActivity activity = testActivityRule.getActivity(); @@ -324,14 +325,13 @@ private void notifyResult() { private void update(boolean isSuccess) { if (isSuccess) { - if (firstTransactionCount.getValue() != -1) { + if (firstTransactionCount.value != -1) { firstTransactionCount.value = -1; - //TODO make a call - //TODO PrebidMobile.setStoredAuctionResponse(728x90); -// bannerAdUnit.addAdditionalSize(728, 90); + PrebidMobile.setStoredAuctionResponse("1001-rubicon-300x50"); + bannerAdUnit.fetchDemand(request, completeListener); - } else if (secondTransactionCount.getValue() != -1) { + } else if (secondTransactionCount.value != -1) { secondTransactionCount.value = -1; notifyResult(); @@ -344,24 +344,24 @@ private void update(boolean isSuccess) { e.printStackTrace(); } - if (firstTransactionCount.getValue() != -1) { - if (firstTransactionCount.getValue() > transactionFailRepeatCount -2) { - Assert.fail("first Transaction Count == " + transactionFailRepeatCount); + if (firstTransactionCount.value != -1) { + if (firstTransactionCount.value > transactionFailRepeatCount -2) { + fail("first Transaction Count == " + transactionFailRepeatCount); } else { //repeat firstTransactionCount.value++; bannerAdUnit.fetchDemand(request, completeListener); } - } else if (secondTransactionCount.getValue() != -1) { - if (secondTransactionCount.getValue() > transactionFailRepeatCount -2) { - Assert.fail("second Transaction Count == " + transactionFailRepeatCount); + } else if (secondTransactionCount.value != -1) { + if (secondTransactionCount.value > transactionFailRepeatCount -2) { + fail("second Transaction Count == " + transactionFailRepeatCount); } else { //repeat secondTransactionCount.value++; bannerAdUnit.fetchDemand(request, completeListener); } } else { - Assert.fail("Unexpected"); + fail("Unexpected"); } } @@ -452,25 +452,18 @@ public void run() { e.printStackTrace(); } - assertEquals(-1, firstTransactionCount.getValue()); - assertEquals(-1, secondTransactionCount.getValue()); - + assertEquals(-1, firstTransactionCount.value); + assertEquals(-1, secondTransactionCount.value); } private static class ReferenceWrapper { - @Nullable T value = null; } private static class IntegerWrapper { int value = 0; - - //TODO remove getValue() - public int getValue() { - return value; - } } } From 22c21b246504a66acea01012509054209a025216 Mon Sep 17 00:00:00 2001 From: Oleksandr Pavliuchyk Date: Wed, 10 Jun 2020 15:19:25 +0300 Subject: [PATCH 7/8] `testPublisherAdRequestBuilderUseCase()` was added --- .../mobile/app/AdManagerComplexTest.java | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/Example/PrebidDemoJava/src/androidTest/java/org/prebid/mobile/app/AdManagerComplexTest.java b/Example/PrebidDemoJava/src/androidTest/java/org/prebid/mobile/app/AdManagerComplexTest.java index 5e915d3c8..6689c317d 100644 --- a/Example/PrebidDemoJava/src/androidTest/java/org/prebid/mobile/app/AdManagerComplexTest.java +++ b/Example/PrebidDemoJava/src/androidTest/java/org/prebid/mobile/app/AdManagerComplexTest.java @@ -268,6 +268,72 @@ public void onComplete(ResultCode resultCode) { assertEquals("value5", customTargetingBundle2.getString("key5")); } + @Test + public void testPublisherAdRequestBuilderUseCase() throws Exception { + //given + + mockServer.enqueue(new MockResponse().setResponseCode(200).setBody("{\n" + + " \"seatbid\": [\n" + + " {\n" + + " \"bid\": [\n" + + " {\n" + + " \"ext\": {\n" + + " \"prebid\": {\n" + + " \"targeting\": {\n" + + " \"hb_cache_id\": \"top_bid_1\",\n" + + " \"key1\": \"value1\"\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + " ]\n" + + " }\n" + + " ]\n" + + "}")); + + + //important line + PrebidMobile.setPrebidServerHost(Host.CUSTOM); + + HttpUrl httpUrl = mockServer.url("/testPublisherAdRequestBuilderUseCase"); + Host.CUSTOM.setHostUrl(httpUrl.toString()); + PrebidMobile.setPrebidServerAccountId("1001"); + + final ReferenceWrapper customTargetingBundleWrapper1 = new ReferenceWrapper<>(); + + //when + final PublisherAdRequest.Builder builder = new PublisherAdRequest.Builder(); + AdUnit adUnit = new BannerAdUnit("1001-1", 300, 250); + + adUnit.fetchDemand(builder, new OnCompleteListener() { + @Override + public void onComplete(ResultCode resultCode) { + + builder.addCustomTargeting("key2", "value2"); + PublisherAdRequest publisherAdRequest = builder.build(); + Bundle customTargetingBundle = publisherAdRequest.getCustomTargeting(); + + customTargetingBundleWrapper1.value = (Bundle)customTargetingBundle.clone(); + + } + }); + + try { + Thread.sleep(1_000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + //then + Bundle customTargetingBundle = customTargetingBundleWrapper1.value; + + assertEquals(3, customTargetingBundle.keySet().size()); + assertEquals("top_bid_1", customTargetingBundle.getString("hb_cache_id")); + assertEquals("value1", customTargetingBundle.getString("key1")); + assertEquals("value2", customTargetingBundle.getString("key2")); + + } + //30x250 -> 728x90 @Test public void testRubiconDFPBannerResizeSanityAppCheckTest() throws Exception { From 71339d65e7a8d1e3e0275a0a37149f1faa27c6a6 Mon Sep 17 00:00:00 2001 From: Oleksandr Pavliuchyk Date: Wed, 10 Jun 2020 16:21:52 +0300 Subject: [PATCH 8/8] `testPublisherAdRequest()` was added --- .../mobile/app/AdManagerComplexTest.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/Example/PrebidDemoJava/src/androidTest/java/org/prebid/mobile/app/AdManagerComplexTest.java b/Example/PrebidDemoJava/src/androidTest/java/org/prebid/mobile/app/AdManagerComplexTest.java index 6689c317d..014668e60 100644 --- a/Example/PrebidDemoJava/src/androidTest/java/org/prebid/mobile/app/AdManagerComplexTest.java +++ b/Example/PrebidDemoJava/src/androidTest/java/org/prebid/mobile/app/AdManagerComplexTest.java @@ -268,6 +268,30 @@ public void onComplete(ResultCode resultCode) { assertEquals("value5", customTargetingBundle2.getString("key5")); } + @Test + public void testPublisherAdRequest() throws Exception { + PublisherAdRequest.Builder builder = new PublisherAdRequest.Builder(); + builder.addCustomTargeting("key1", "value1"); + builder.addCustomTargeting("key2", "value2"); + + PublisherAdRequest publisherAdRequest1 = builder.build(); + Bundle bundle1 = publisherAdRequest1.getCustomTargeting(); + + assertEquals(2, bundle1.keySet().size()); + assertEquals("value1", bundle1.getString("key1")); + assertEquals("value2", bundle1.getString("key2")); + + bundle1.remove("key2"); + assertEquals(1, bundle1.keySet().size()); + assertEquals("value1", bundle1.getString("key1")); + + PublisherAdRequest publisherAdRequest2 = builder.build(); + Bundle bundle2 = publisherAdRequest2.getCustomTargeting(); + assertEquals(1, bundle2.keySet().size()); + assertEquals("value1", bundle2.getString("key1")); + + } + @Test public void testPublisherAdRequestBuilderUseCase() throws Exception { //given