diff --git a/src/main/java/org/prebid/server/bidder/gumgum/GumgumBidder.java b/src/main/java/org/prebid/server/bidder/gumgum/GumgumBidder.java index cecb9e3c473..344004a575f 100644 --- a/src/main/java/org/prebid/server/bidder/gumgum/GumgumBidder.java +++ b/src/main/java/org/prebid/server/bidder/gumgum/GumgumBidder.java @@ -26,6 +26,7 @@ import org.prebid.server.json.DecodeException; import org.prebid.server.json.JacksonMapper; import org.prebid.server.proto.openrtb.ext.ExtPrebid; +import org.prebid.server.proto.openrtb.ext.request.ExtImpPrebid; import org.prebid.server.proto.openrtb.ext.request.gumgum.ExtImpGumgum; import org.prebid.server.proto.openrtb.ext.request.gumgum.ExtImpGumgumBanner; import org.prebid.server.proto.openrtb.ext.request.gumgum.ExtImpGumgumVideo; @@ -42,12 +43,13 @@ import java.util.Comparator; import java.util.List; import java.util.Objects; +import java.util.Optional; public class GumgumBidder implements Bidder { private static final String REQUEST_EXT_PRODUCT = "product"; - private static final TypeReference> GUMGUM_EXT_TYPE_REFERENCE = + private static final TypeReference> GUMGUM_EXT_TYPE_REFERENCE = new TypeReference<>() { }; @@ -82,17 +84,24 @@ private BidRequest createBidRequest(BidRequest bidRequest, List err for (Imp imp : bidRequest.getImp()) { try { - final ExtImpGumgum extImp = parseImpExt(imp); - modifiedImps.add(modifyImp(imp, extImp)); + final ExtPrebid extImp = parseImpExt(imp); + final ExtImpGumgum extImpGumgum = extImp.getBidder(); + final String adUnitCode = Optional.ofNullable(extImp.getPrebid()) + .map(ExtImpPrebid::getAdUnitCode) + .orElse(null); - final String extZone = extImp.getZone(); + modifiedImps.add(modifyImp(imp, extImpGumgum, adUnitCode)); + + final String extZone = extImpGumgum.getZone(); if (StringUtils.isNotEmpty(extZone)) { zone = extZone; } - final BigInteger extPubId = extImp.getPubId(); + + final BigInteger extPubId = extImpGumgum.getPubId(); if (extPubId != null && !extPubId.equals(BigInteger.ZERO)) { pubId = extPubId; } + } catch (PreBidException e) { errors.add(BidderError.badInput(e.getMessage())); } @@ -108,15 +117,15 @@ private BidRequest createBidRequest(BidRequest bidRequest, List err .build(); } - private ExtImpGumgum parseImpExt(Imp imp) { + private ExtPrebid parseImpExt(Imp imp) { try { - return mapper.mapper().convertValue(imp.getExt(), GUMGUM_EXT_TYPE_REFERENCE).getBidder(); + return mapper.mapper().convertValue(imp.getExt(), GUMGUM_EXT_TYPE_REFERENCE); } catch (IllegalArgumentException e) { throw new PreBidException(e.getMessage()); } } - private Imp modifyImp(Imp imp, ExtImpGumgum extImp) { + private Imp modifyImp(Imp imp, ExtImpGumgum extImp, String adUnitCode) { final Imp.ImpBuilder impBuilder = imp.toBuilder(); final String product = extImp.getProduct(); @@ -125,6 +134,10 @@ private Imp modifyImp(Imp imp, ExtImpGumgum extImp) { impBuilder.ext(productExt); } + if (StringUtils.isNotEmpty(adUnitCode)) { + impBuilder.tagid(adUnitCode); + } + final Banner banner = imp.getBanner(); if (banner != null) { final Banner resolvedBanner = resolveBanner(banner, extImp); @@ -141,6 +154,7 @@ private Imp modifyImp(Imp imp, ExtImpGumgum extImp) { impBuilder.video(resolvedVideo); } } + return impBuilder.build(); } diff --git a/src/test/java/org/prebid/server/bidder/gumgum/GumgumBidderTest.java b/src/test/java/org/prebid/server/bidder/gumgum/GumgumBidderTest.java index 2595b6d903a..2b00840ed26 100644 --- a/src/test/java/org/prebid/server/bidder/gumgum/GumgumBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/gumgum/GumgumBidderTest.java @@ -21,12 +21,15 @@ import org.prebid.server.bidder.model.HttpResponse; import org.prebid.server.bidder.model.Result; import org.prebid.server.proto.openrtb.ext.ExtPrebid; +import org.prebid.server.proto.openrtb.ext.request.ExtImpPrebid; import org.prebid.server.proto.openrtb.ext.request.gumgum.ExtImpGumgum; import org.prebid.server.proto.openrtb.ext.request.gumgum.ExtImpGumgumBanner; import org.prebid.server.proto.openrtb.ext.request.gumgum.ExtImpGumgumVideo; +import java.io.IOException; import java.math.BigDecimal; import java.math.BigInteger; +import java.util.Collections; import java.util.List; import java.util.function.Function; @@ -36,6 +39,10 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; import static org.assertj.core.api.Assertions.tuple; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.prebid.server.proto.openrtb.ext.response.BidType.banner; import static org.prebid.server.proto.openrtb.ext.response.BidType.video; @@ -45,6 +52,124 @@ public class GumgumBidderTest extends VertxTest { private final GumgumBidder target = new GumgumBidder(ENDPOINT_URL, jacksonMapper); + @Test + public void makeHttpRequestsShouldReturnErrorIfImpExtCouldNotBeParsed() { + // given + final BidRequest bidRequest = givenBidRequest(impBuilder -> + impBuilder.ext(mapper.valueToTree(ExtPrebid.of(null, mapper.createArrayNode())))); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + assertThat(result.getErrors()).hasSize(2) + .anySatisfy(error -> { + assertThat(error.getType()).isEqualTo(BidderError.Type.bad_input); + assertThat(error.getMessage()).startsWith("Cannot deserialize value"); + }); + } + + @Test + public void makeHttpRequestsShouldModifyImpressionsWhenValidInput() { + // given + final ObjectNode extImp = mapper.valueToTree(ExtPrebid.of( + ExtImpPrebid.builder().adUnitCode("adUnit123").build(), + ExtImpGumgum.of("zone", BigInteger.TEN, "irisId", null, "product"))); + + final BidRequest bidRequest = givenBidRequest(impBuilder -> + impBuilder.ext(extImp)); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + assertThat(result.getValue()) + .extracting(HttpRequest::getPayload) + .flatExtracting(BidRequest::getImp) + .extracting(Imp::getTagid) + .containsExactly("adUnit123"); + } + + @Test + public void testMakeHttpRequestsShouldNotSetTagIdFromZoneWhenAdUnitIdIsMissing() throws IOException { + // given + final ObjectNode extImp = mapper.valueToTree(ExtPrebid.of(null, + ExtImpGumgum.of("zone123", BigInteger.TEN, "productA", null, "zone123"))); + + final Imp imp = Imp.builder() + .id("imp1") + .banner(Banner.builder().w(300).h(250).build()) + .ext(extImp) + .build(); + + final BidRequest bidRequest = BidRequest.builder() + .id("test-bid-request") + .imp(Collections.singletonList(imp)) + .site(Site.builder().id("test-site").build()) + .build(); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + assertNotNull(result); + assertFalse(result.getValue().isEmpty()); + + final byte[] requestBody = result.getValue().get(0).getBody(); + final BidRequest modifiedRequest = mapper.readValue(requestBody, BidRequest.class); + + assertFalse(modifiedRequest.getImp().isEmpty()); + + final Imp modifiedImp = modifiedRequest.getImp().get(0); + + assertNull(modifiedImp.getTagid()); + assertEquals("test-site", modifiedRequest.getSite().getId(), "zone123"); + } + + @Test + public void makeHttpRequestsShouldReturnModifiedBidRequestWhenValidInput() { + // given + final ObjectNode extImp = mapper.valueToTree(ExtPrebid.of( + ExtImpPrebid.builder().adUnitCode("adUnit123").build(), + ExtImpGumgum.of("zone", BigInteger.TEN, "irisId", null, "product"))); + + final BidRequest bidRequest = givenBidRequest(impBuilder -> impBuilder.ext(extImp)); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + assertThat(result.getErrors()).isEmpty(); + + assertThat(result.getValue()) + .extracting(HttpRequest::getPayload) + .flatExtracting(BidRequest::getImp) + .extracting(Imp::getTagid) + .containsExactly("adUnit123"); + } + + @Test + public void makeHttpRequestsShouldExtractAdUnitIdWhenPresent() { + // given + final ObjectNode extImp = mapper.valueToTree(ExtPrebid.of( + ExtImpPrebid.builder().adUnitCode("adUnit123").build(), + ExtImpGumgum.of("zone", BigInteger.TEN, "irisId", null, "product"))); + + final BidRequest bidRequest = givenBidRequest(impBuilder -> impBuilder.ext(extImp)); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + assertThat(result.getErrors()).isEmpty(); + + assertThat(result.getValue()) + .extracting(HttpRequest::getPayload) + .flatExtracting(BidRequest::getImp) + .extracting(Imp::getTagid) + .containsExactly("adUnit123"); + } + @Test public void creationShouldFailOnInvalidEndpointUrl() { assertThatIllegalArgumentException().isThrownBy(() -> new GumgumBidder("invalid_url", jacksonMapper)); @@ -422,4 +547,5 @@ private static BidderCall givenHttpCall(BidRequest bidRequest, Strin HttpResponse.of(200, null, body), null); } + }