From 15dd5c158a6f76bf539d3c5c689fad1e34705b6c Mon Sep 17 00:00:00 2001 From: antonbabak Date: Mon, 19 May 2025 12:35:08 +0200 Subject: [PATCH 1/3] Adnuntius Adapter: Add multi-format and native support --- .../bidder/adnuntius/AdnuntiusBidder.java | 181 ++-- .../model/request/AdnuntiusNativeRequest.java | 11 + .../model/request/AdnuntiusRequest.java | 2 +- ...dUnit.java => AdnuntiusRequestAdUnit.java} | 8 +- ...ntiusAdsUnit.java => AdnuntiusAdUnit.java} | 9 +- .../model/response/AdnuntiusResponse.java | 2 +- .../bidder/AdnuntiusBidderConfiguration.java | 33 +- .../resources/bidder-config/adnuntius.yaml | 2 + .../bidder/adnuntius/AdnuntiusBidderTest.java | 783 +++++++++++++++--- .../adnuntius/test-adnuntius-bid-request.json | 2 +- .../test-adnuntius-bid-response.json | 3 +- .../test-auction-adnuntius-response.json | 1 + 12 files changed, 860 insertions(+), 177 deletions(-) create mode 100644 src/main/java/org/prebid/server/bidder/adnuntius/model/request/AdnuntiusNativeRequest.java rename src/main/java/org/prebid/server/bidder/adnuntius/model/request/{AdnuntiusAdUnit.java => AdnuntiusRequestAdUnit.java} (71%) rename src/main/java/org/prebid/server/bidder/adnuntius/model/response/{AdnuntiusAdsUnit.java => AdnuntiusAdUnit.java} (63%) diff --git a/src/main/java/org/prebid/server/bidder/adnuntius/AdnuntiusBidder.java b/src/main/java/org/prebid/server/bidder/adnuntius/AdnuntiusBidder.java index 52ec2b3992a..e499c18b61f 100644 --- a/src/main/java/org/prebid/server/bidder/adnuntius/AdnuntiusBidder.java +++ b/src/main/java/org/prebid/server/bidder/adnuntius/AdnuntiusBidder.java @@ -1,5 +1,6 @@ package org.prebid.server.bidder.adnuntius; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; @@ -23,11 +24,12 @@ import org.apache.commons.lang3.StringUtils; import org.apache.http.client.utils.URIBuilder; import org.prebid.server.bidder.Bidder; -import org.prebid.server.bidder.adnuntius.model.request.AdnuntiusAdUnit; import org.prebid.server.bidder.adnuntius.model.request.AdnuntiusMetaData; +import org.prebid.server.bidder.adnuntius.model.request.AdnuntiusNativeRequest; import org.prebid.server.bidder.adnuntius.model.request.AdnuntiusRequest; +import org.prebid.server.bidder.adnuntius.model.request.AdnuntiusRequestAdUnit; import org.prebid.server.bidder.adnuntius.model.response.AdnuntiusAd; -import org.prebid.server.bidder.adnuntius.model.response.AdnuntiusAdsUnit; +import org.prebid.server.bidder.adnuntius.model.response.AdnuntiusAdUnit; import org.prebid.server.bidder.adnuntius.model.response.AdnuntiusAdvertiser; import org.prebid.server.bidder.adnuntius.model.response.AdnuntiusBid; import org.prebid.server.bidder.adnuntius.model.response.AdnuntiusBidExt; @@ -41,6 +43,7 @@ import org.prebid.server.bidder.model.Result; import org.prebid.server.exception.PreBidException; import org.prebid.server.json.DecodeException; +import org.prebid.server.json.EncodeException; import org.prebid.server.json.JacksonMapper; import org.prebid.server.proto.openrtb.ext.ExtPrebid; import org.prebid.server.proto.openrtb.ext.FlexibleExtension; @@ -51,6 +54,7 @@ import org.prebid.server.proto.openrtb.ext.request.adnuntius.ExtImpAdnuntius; import org.prebid.server.proto.openrtb.ext.response.BidType; import org.prebid.server.proto.openrtb.ext.response.ExtBidDsa; +import org.prebid.server.util.BidderUtil; import org.prebid.server.util.HttpUtil; import org.prebid.server.util.ObjectUtil; @@ -74,48 +78,68 @@ public class AdnuntiusBidder implements Bidder { new TypeReference<>() { }; private static final int SECONDS_IN_MINUTE = 60; - private static final String TARGET_ID_DELIMITER = "-"; private static final String DEFAULT_PAGE = "unknown"; private static final String DEFAULT_NETWORK = "default"; private static final BigDecimal PRICE_MULTIPLIER = BigDecimal.valueOf(1000); + private static final int BANNER_MTYPE = 1; + private static final int NATIVE_MTYPE = 4; private final String endpointUrl; + private final String alternativeEndpointUrl; private final Clock clock; private final JacksonMapper mapper; - public AdnuntiusBidder(String endpointUrl, Clock clock, JacksonMapper mapper) { + public AdnuntiusBidder(String endpointUrl, + String alternativeEndpointUrl, + Clock clock, + JacksonMapper mapper) { + this.endpointUrl = HttpUtil.validateUrl(Objects.requireNonNull(endpointUrl)); + this.alternativeEndpointUrl = alternativeEndpointUrl; this.clock = Objects.requireNonNull(clock); this.mapper = Objects.requireNonNull(mapper); } @Override public Result>> makeHttpRequests(BidRequest request) { - final Map> networkToAdUnits = new HashMap<>(); + final Map> networkToAdUnits = new HashMap<>(); boolean noCookies = false; for (Imp imp : request.getImp()) { - final ExtImpAdnuntius extImpAdnuntius; try { validateImp(imp); - extImpAdnuntius = parseImpExt(imp); + final ExtImpAdnuntius extImpAdnuntius = parseImpExt(imp); + noCookies = noCookies || resolveIsNoCookies(extImpAdnuntius); + final String network = resolveNetwork(extImpAdnuntius); + + final List adUnits = networkToAdUnits.computeIfAbsent( + network, + ignored -> new ArrayList<>()); + + if (imp.getBanner() != null) { + adUnits.add(makeBannerAdUnit(imp, extImpAdnuntius)); + } + + if (imp.getXNative() != null) { + adUnits.add(makeNativeAdUnit(imp, extImpAdnuntius)); + } + } catch (PreBidException e) { return Result.withError(BidderError.badInput(e.getMessage())); } - - noCookies = noCookies || resolveIsNoCookies(extImpAdnuntius); - final String network = resolveNetwork(extImpAdnuntius); - - networkToAdUnits.computeIfAbsent(network, ignored -> new ArrayList<>()) - .add(makeAdUnit(imp, extImpAdnuntius)); } - return Result.withValues(createHttpRequests(networkToAdUnits, request, noCookies)); + try { + return Result.withValues(createHttpRequests(networkToAdUnits, request, noCookies)); + } catch (PreBidException e) { + return Result.withError(BidderError.badInput(e.getMessage())); + } } private static void validateImp(Imp imp) { - if (imp.getBanner() == null) { - throw new PreBidException("Fail on Imp.Id=%s: Adnuntius supports only Banner".formatted(imp.getId())); + if (imp.getBanner() == null && imp.getXNative() == null) { + throw new PreBidException("ignoring imp id=%s: Adnuntius supports only native and banner" + .formatted(imp.getId())); } } @@ -141,18 +165,22 @@ private static String resolveNetwork(ExtImpAdnuntius extImpAdnuntius) { .orElse(DEFAULT_NETWORK); } - private static AdnuntiusAdUnit makeAdUnit(Imp imp, ExtImpAdnuntius extImpAdnuntius) { + private static AdnuntiusRequestAdUnit makeBannerAdUnit(Imp imp, ExtImpAdnuntius extImpAdnuntius) { final String auId = extImpAdnuntius.getAuId(); - return AdnuntiusAdUnit.builder() + return AdnuntiusRequestAdUnit.builder() .auId(auId) - .targetId(targetId(auId, imp.getId())) + .targetId(targetId(auId, imp.getId(), "banner")) .dimensions(createDimensions(imp.getBanner())) .maxDeals(resolveMaxDeals(extImpAdnuntius)) .build(); } + private static String targetId(String auId, String impId, String bidType) { + return "%s-%s:%s".formatted(auId, impId, bidType); + } + private static String targetId(String auId, String impId) { - return auId + TARGET_ID_DELIMITER + impId; + return "%s-%s".formatted(auId, impId); } private static List> createDimensions(Banner banner) { @@ -166,6 +194,7 @@ private static List> createDimensions(Banner banner) { formats.add(List.of(w, h)); } } + if (!formats.isEmpty()) { return formats; } @@ -179,44 +208,68 @@ private static List> createDimensions(Banner banner) { return formats.isEmpty() ? null : formats; } + private AdnuntiusRequestAdUnit makeNativeAdUnit(Imp imp, ExtImpAdnuntius extImpAdnuntius) { + final String auId = extImpAdnuntius.getAuId(); + return AdnuntiusRequestAdUnit.builder() + .auId(auId) + .adType("NATIVE") + .targetId(targetId(auId, imp.getId(), "native")) + .maxDeals(resolveMaxDeals(extImpAdnuntius)) + .nativeRequest(AdnuntiusNativeRequest.of(parseNativeRequest(imp))) + .build(); + } + + private ObjectNode parseNativeRequest(Imp imp) { + try { + return mapper.mapper().readValue(imp.getXNative().getRequest(), ObjectNode.class); + } catch (IllegalArgumentException | JsonProcessingException e) { + throw new PreBidException("Unmarshalling Native error " + e.getMessage()); + } + } + private static Integer resolveMaxDeals(ExtImpAdnuntius extImpAdnuntius) { final Integer maxDeals = extImpAdnuntius.getMaxDeals(); return maxDeals != null && maxDeals > 0 ? maxDeals : null; } - private List> createHttpRequests(Map> networkToAdUnits, - BidRequest request, - boolean noCookies) { + private List> createHttpRequests( + Map> networkToAdUnits, + BidRequest request, + boolean noCookies) { final Site site = request.getSite(); - final String uri = createUri(request, noCookies); + final String uri = makeEndpoint(request, noCookies); final String page = extractPage(site); final ObjectNode data = extractData(site); final AdnuntiusMetaData metaData = createMetaData(request.getUser()); final List> adnuntiusRequests = new ArrayList<>(); - for (List adUnits : networkToAdUnits.values()) { + for (List adUnits : networkToAdUnits.values()) { final AdnuntiusRequest adnuntiusRequest = AdnuntiusRequest.builder() .adUnits(adUnits) .context(page) .keyValue(data) .metaData(metaData) .build(); - adnuntiusRequests.add(createHttpRequest(adnuntiusRequest, uri, request.getDevice())); + adnuntiusRequests.add(createHttpRequest(request, adnuntiusRequest, uri, request.getDevice())); } return adnuntiusRequests; } - private String createUri(BidRequest bidRequest, Boolean noCookies) { + private String makeEndpoint(BidRequest bidRequest, Boolean noCookies) { try { - final URIBuilder uriBuilder = new URIBuilder(endpointUrl) + final String gdpr = extractGdpr(bidRequest.getRegs()); + final String url = StringUtils.isNotEmpty(gdpr) && alternativeEndpointUrl != null + ? HttpUtil.validateUrl(alternativeEndpointUrl) + : endpointUrl; + + final URIBuilder uriBuilder = new URIBuilder(url) .addParameter("format", "prebidServer") .addParameter("tzo", getTimeZoneOffset()); - final String gdpr = extractGdpr(bidRequest.getRegs()); if (StringUtils.isNotEmpty(gdpr)) { uriBuilder.addParameter("gdpr", gdpr); } @@ -231,7 +284,7 @@ private String createUri(BidRequest bidRequest, Boolean noCookies) { } return uriBuilder.build().toString(); - } catch (URISyntaxException e) { + } catch (URISyntaxException | IllegalArgumentException e) { throw new PreBidException(e.getMessage()); } } @@ -297,7 +350,8 @@ private static AdnuntiusMetaData createMetaData(User user) { .orElse(null); } - private HttpRequest createHttpRequest(AdnuntiusRequest adnuntiusRequest, + private HttpRequest createHttpRequest(BidRequest request, + AdnuntiusRequest adnuntiusRequest, String uri, Device device) { @@ -307,6 +361,7 @@ private HttpRequest createHttpRequest(AdnuntiusRequest adnunti .uri(uri) .body(mapper.encodeToBytes(adnuntiusRequest)) .payload(adnuntiusRequest) + .impIds(BidderUtil.impIds(request)) .build(); } @@ -327,22 +382,22 @@ public Result> makeBids(BidderCall httpCall, B final String body = httpCall.getResponse().getBody(); final AdnuntiusResponse adnuntiusResponse = mapper.decodeValue(body, AdnuntiusResponse.class); return Result.withValues(extractBids(bidRequest, adnuntiusResponse)); - } catch (DecodeException | PreBidException e) { + } catch (EncodeException | DecodeException | PreBidException e) { return Result.withError(BidderError.badServerResponse(e.getMessage())); } } private List extractBids(BidRequest bidRequest, AdnuntiusResponse adnuntiusResponse) { - if (adnuntiusResponse == null || CollectionUtils.isEmpty(adnuntiusResponse.getAdsUnits())) { + if (adnuntiusResponse == null || CollectionUtils.isEmpty(adnuntiusResponse.getAdUnits())) { return Collections.emptyList(); } - final Map targetIdToAdsUnit = adnuntiusResponse.getAdsUnits().stream() - .filter(AdnuntiusBidder::validateAdsUnit) + final Map targetIdToAdsUnit = adnuntiusResponse.getAdUnits().stream() + .filter(AdnuntiusBidder::isValid) .collect(Collectors.toMap( - AdnuntiusAdsUnit::getTargetId, + adUnit -> extractTargetId(adUnit.getTargetId()), Function.identity(), - (first, second) -> second)); + (first, second) -> getBidAmount(first).compareTo(getBidAmount(second)) >= 0 ? first : second)); String currency = null; final List bids = new ArrayList<>(); @@ -351,35 +406,64 @@ private List extractBids(BidRequest bidRequest, AdnuntiusResponse adn final ExtImpAdnuntius extImpAdnuntius = parseImpExt(imp); final String targetId = targetId(extImpAdnuntius.getAuId(), imp.getId()); - final AdnuntiusAdsUnit adsUnit = targetIdToAdsUnit.get(targetId); - if (adsUnit == null) { + final AdnuntiusAdUnit adUnit = targetIdToAdsUnit.get(targetId); + if (adUnit == null) { continue; } - final AdnuntiusAd ad = adsUnit.getAds().getFirst(); + final AdnuntiusAd ad = adUnit.getAds().getFirst(); final String impId = imp.getId(); final String bidType = extImpAdnuntius.getBidType(); + currency = ObjectUtil.getIfNotNull(ad.getBid(), AdnuntiusBid::getCurrency); + final JsonNode nativeRequest = Optional.ofNullable(adUnit.getNativeJson()) + .map(AdnuntiusNativeRequest::getOrtb) + .orElse(null); + final int mType = nativeRequest == null ? BANNER_MTYPE : NATIVE_MTYPE; + final String html = nativeRequest == null ? adUnit.getHtml() : mapper.encodeToString(nativeRequest); - bids.add(createBid(ad, bidRequest, adsUnit.getHtml(), impId, bidType)); + bids.add(createBid(ad, bidRequest, html, impId, bidType, mType)); - for (AdnuntiusAd deal : ListUtils.emptyIfNull(adsUnit.getDeals())) { - bids.add(createBid(deal, bidRequest, deal.getHtml(), impId, bidType)); + for (AdnuntiusAd deal : ListUtils.emptyIfNull(adUnit.getDeals())) { + bids.add(createBid(deal, bidRequest, deal.getHtml(), impId, bidType, BANNER_MTYPE)); } } final String lastCurrency = currency; return bids.stream() - .map(bid -> BidderBid.of(bid, BidType.banner, lastCurrency)) + .map(bid -> BidderBid.of( + bid, + bid.getMtype() == BANNER_MTYPE ? BidType.banner : BidType.xNative, + lastCurrency)) .toList(); } - private static boolean validateAdsUnit(AdnuntiusAdsUnit adsUnit) { - final List ads = adsUnit != null ? adsUnit.getAds() : null; - return CollectionUtils.isNotEmpty(ads) && ads.getFirst() != null; + private static BigDecimal getBidAmount(AdnuntiusAdUnit adUnit) { + return adUnit.getAds().getFirst().getBid().getAmount(); + } + + private static boolean isValid(AdnuntiusAdUnit adsUnit) { + if (adsUnit == null) { + return false; + } + + final String targetId = extractTargetId(adsUnit.getTargetId()); + final int matchedCount = ObjectUtils.defaultIfNull(adsUnit.getMatchedAdCount(), 0); + final List ads = adsUnit.getAds(); + final BigDecimal bidAmount = CollectionUtils.emptyIfNull(ads).stream() + .findFirst() + .map(AdnuntiusAd::getBid) + .map(AdnuntiusBid::getAmount) + .orElse(null); + + return targetId != null && matchedCount > 0 && bidAmount != null; + } + + private static String extractTargetId(String targetId) { + return targetId == null ? null : targetId.split(":")[0]; } - private Bid createBid(AdnuntiusAd ad, BidRequest bidRequest, String adm, String impId, String bidType) { + private Bid createBid(AdnuntiusAd ad, BidRequest bidRequest, String adm, String impId, String bidType, int mtype) { final String adId = ad.getAdId(); final AdnuntiusBidExt bidExt = prepareBidExt(ad, bidRequest); @@ -395,6 +479,7 @@ private Bid createBid(AdnuntiusAd ad, BidRequest bidRequest, String adm, String .price(resolvePrice(ad, bidType)) .adm(adm) .adomain(ad.getAdvertiserDomains()) + .mtype(mtype) .ext(bidExt == null ? null : mapper.mapper().valueToTree(bidExt)) .build(); } diff --git a/src/main/java/org/prebid/server/bidder/adnuntius/model/request/AdnuntiusNativeRequest.java b/src/main/java/org/prebid/server/bidder/adnuntius/model/request/AdnuntiusNativeRequest.java new file mode 100644 index 00000000000..b76f5394b4d --- /dev/null +++ b/src/main/java/org/prebid/server/bidder/adnuntius/model/request/AdnuntiusNativeRequest.java @@ -0,0 +1,11 @@ +package org.prebid.server.bidder.adnuntius.model.request; + +import com.fasterxml.jackson.databind.node.ObjectNode; +import lombok.Value; + +@Value(staticConstructor = "of") +public class AdnuntiusNativeRequest { + + ObjectNode ortb; + +} diff --git a/src/main/java/org/prebid/server/bidder/adnuntius/model/request/AdnuntiusRequest.java b/src/main/java/org/prebid/server/bidder/adnuntius/model/request/AdnuntiusRequest.java index eafd24facbf..2fde60d0044 100644 --- a/src/main/java/org/prebid/server/bidder/adnuntius/model/request/AdnuntiusRequest.java +++ b/src/main/java/org/prebid/server/bidder/adnuntius/model/request/AdnuntiusRequest.java @@ -13,7 +13,7 @@ public class AdnuntiusRequest { @JsonProperty("adUnits") - List adUnits; + List adUnits; @JsonProperty("metaData") @JsonInclude(JsonInclude.Include.NON_EMPTY) diff --git a/src/main/java/org/prebid/server/bidder/adnuntius/model/request/AdnuntiusAdUnit.java b/src/main/java/org/prebid/server/bidder/adnuntius/model/request/AdnuntiusRequestAdUnit.java similarity index 71% rename from src/main/java/org/prebid/server/bidder/adnuntius/model/request/AdnuntiusAdUnit.java rename to src/main/java/org/prebid/server/bidder/adnuntius/model/request/AdnuntiusRequestAdUnit.java index f092822f909..03e9b586c72 100644 --- a/src/main/java/org/prebid/server/bidder/adnuntius/model/request/AdnuntiusAdUnit.java +++ b/src/main/java/org/prebid/server/bidder/adnuntius/model/request/AdnuntiusRequestAdUnit.java @@ -8,7 +8,7 @@ @Builder(toBuilder = true) @Value -public class AdnuntiusAdUnit { +public class AdnuntiusRequestAdUnit { @JsonProperty("auId") String auId; @@ -20,4 +20,10 @@ public class AdnuntiusAdUnit { @JsonProperty("maxDeals") Integer maxDeals; + + @JsonProperty("nativeRequest") + AdnuntiusNativeRequest nativeRequest; + + @JsonProperty("adType") + String adType; } diff --git a/src/main/java/org/prebid/server/bidder/adnuntius/model/response/AdnuntiusAdsUnit.java b/src/main/java/org/prebid/server/bidder/adnuntius/model/response/AdnuntiusAdUnit.java similarity index 63% rename from src/main/java/org/prebid/server/bidder/adnuntius/model/response/AdnuntiusAdsUnit.java rename to src/main/java/org/prebid/server/bidder/adnuntius/model/response/AdnuntiusAdUnit.java index 8fb0c0c7c70..7dbd6478335 100644 --- a/src/main/java/org/prebid/server/bidder/adnuntius/model/response/AdnuntiusAdsUnit.java +++ b/src/main/java/org/prebid/server/bidder/adnuntius/model/response/AdnuntiusAdUnit.java @@ -3,12 +3,13 @@ import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Builder; import lombok.Value; +import org.prebid.server.bidder.adnuntius.model.request.AdnuntiusNativeRequest; import java.util.List; @Builder @Value -public class AdnuntiusAdsUnit { +public class AdnuntiusAdUnit { @JsonProperty("auId") String auId; @@ -18,9 +19,15 @@ public class AdnuntiusAdsUnit { String html; + @JsonProperty("matchedAdCount") + Integer matchedAdCount; + @JsonProperty("responseId") String responseId; + @JsonProperty("nativeJson") + AdnuntiusNativeRequest nativeJson; + List ads; List deals; diff --git a/src/main/java/org/prebid/server/bidder/adnuntius/model/response/AdnuntiusResponse.java b/src/main/java/org/prebid/server/bidder/adnuntius/model/response/AdnuntiusResponse.java index 6ce62d9afdb..ca4a6d5fe5f 100644 --- a/src/main/java/org/prebid/server/bidder/adnuntius/model/response/AdnuntiusResponse.java +++ b/src/main/java/org/prebid/server/bidder/adnuntius/model/response/AdnuntiusResponse.java @@ -9,5 +9,5 @@ public class AdnuntiusResponse { @JsonProperty("adUnits") - List adsUnits; + List adUnits; } diff --git a/src/main/java/org/prebid/server/spring/config/bidder/AdnuntiusBidderConfiguration.java b/src/main/java/org/prebid/server/spring/config/bidder/AdnuntiusBidderConfiguration.java index 687c2897b8f..edfe18165c2 100644 --- a/src/main/java/org/prebid/server/spring/config/bidder/AdnuntiusBidderConfiguration.java +++ b/src/main/java/org/prebid/server/spring/config/bidder/AdnuntiusBidderConfiguration.java @@ -1,5 +1,8 @@ package org.prebid.server.spring.config.bidder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; import org.prebid.server.bidder.BidderDeps; import org.prebid.server.bidder.adnuntius.AdnuntiusBidder; import org.prebid.server.json.JacksonMapper; @@ -7,6 +10,7 @@ import org.prebid.server.spring.config.bidder.util.BidderDepsAssembler; import org.prebid.server.spring.config.bidder.util.UsersyncerCreator; import org.prebid.server.spring.env.YamlPropertySourceFactory; +import org.prebid.server.util.ObjectUtil; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; @@ -24,20 +28,39 @@ public class AdnuntiusBidderConfiguration { @Bean("adnuntiusConfigurationProperties") @ConfigurationProperties("adapters.adnuntius") - BidderConfigurationProperties configurationProperties() { - return new BidderConfigurationProperties(); + AdnuntiusConfigurationProperties configurationProperties() { + return new AdnuntiusConfigurationProperties(); } @Bean - BidderDeps adnuntiusBidderDeps(BidderConfigurationProperties adnuntiusConfigurationProperties, + BidderDeps adnuntiusBidderDeps(AdnuntiusConfigurationProperties adnuntiusConfigurationProperties, @NotBlank @Value("${external-url}") String externalUrl, Clock clock, JacksonMapper mapper) { - return BidderDepsAssembler.forBidder(BIDDER_NAME) + return BidderDepsAssembler.forBidder(BIDDER_NAME) .withConfig(adnuntiusConfigurationProperties) .usersyncerCreator(UsersyncerCreator.create(externalUrl)) - .bidderCreator(config -> new AdnuntiusBidder(config.getEndpoint(), clock, mapper)) + .bidderCreator(config -> new AdnuntiusBidder( + config.getEndpoint(), + ObjectUtil.getIfNotNull(config.getExtraInfo(), ExtraInfo::getUrl), + clock, + mapper)) .assemble(); } + + @Data + @EqualsAndHashCode(callSuper = true) + @NoArgsConstructor + private static class AdnuntiusConfigurationProperties extends BidderConfigurationProperties { + + private ExtraInfo extraInfo = new ExtraInfo(); + } + + @Data + @NoArgsConstructor + private static class ExtraInfo { + + String url; + } } diff --git a/src/main/resources/bidder-config/adnuntius.yaml b/src/main/resources/bidder-config/adnuntius.yaml index b90b743f81d..5fd1d63edaa 100644 --- a/src/main/resources/bidder-config/adnuntius.yaml +++ b/src/main/resources/bidder-config/adnuntius.yaml @@ -5,7 +5,9 @@ adapters: maintainer-email: hello@adnuntius.com app-media-types: - banner + - native site-media-types: - banner + - native supported-vendors: vendor-id: 855 diff --git a/src/test/java/org/prebid/server/bidder/adnuntius/AdnuntiusBidderTest.java b/src/test/java/org/prebid/server/bidder/adnuntius/AdnuntiusBidderTest.java index afcc617ebfa..084de7478c4 100644 --- a/src/test/java/org/prebid/server/bidder/adnuntius/AdnuntiusBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/adnuntius/AdnuntiusBidderTest.java @@ -10,6 +10,7 @@ import com.iab.openrtb.request.Eid; import com.iab.openrtb.request.Format; import com.iab.openrtb.request.Imp; +import com.iab.openrtb.request.Native; import com.iab.openrtb.request.Regs; import com.iab.openrtb.request.Site; import com.iab.openrtb.request.Uid; @@ -20,11 +21,12 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.prebid.server.VertxTest; -import org.prebid.server.bidder.adnuntius.model.request.AdnuntiusAdUnit; +import org.prebid.server.bidder.adnuntius.model.request.AdnuntiusNativeRequest; +import org.prebid.server.bidder.adnuntius.model.request.AdnuntiusRequestAdUnit; import org.prebid.server.bidder.adnuntius.model.request.AdnuntiusMetaData; import org.prebid.server.bidder.adnuntius.model.request.AdnuntiusRequest; import org.prebid.server.bidder.adnuntius.model.response.AdnuntiusAd; -import org.prebid.server.bidder.adnuntius.model.response.AdnuntiusAdsUnit; +import org.prebid.server.bidder.adnuntius.model.response.AdnuntiusAdUnit; import org.prebid.server.bidder.adnuntius.model.response.AdnuntiusAdvertiser; import org.prebid.server.bidder.adnuntius.model.response.AdnuntiusBid; import org.prebid.server.bidder.adnuntius.model.response.AdnuntiusGrossBid; @@ -51,6 +53,7 @@ import java.time.ZoneId; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.function.UnaryOperator; import static java.util.Arrays.asList; @@ -61,24 +64,37 @@ public class AdnuntiusBidderTest extends VertxTest { + private static final String ENDPOINT_URL = "https://test.domain.dm/uri"; + private static final String ALTERNATIVE_URL = "https://alternative.domain.dm/uri"; + private AdnuntiusBidder target; @BeforeEach public void setUp() { final Clock clock = Clock.system(ZoneId.of("UTC+05:00")); - target = new AdnuntiusBidder("https://test.domain.dm/uri", clock, jacksonMapper); + target = new AdnuntiusBidder( + ENDPOINT_URL, + null, + clock, + jacksonMapper); } @Test public void creationShouldFailOnInvalidEndpointUrl() { - assertThatIllegalArgumentException().isThrownBy(() -> - new AdnuntiusBidder("invalid_url", Clock.systemDefaultZone(), jacksonMapper)); + assertThatIllegalArgumentException().isThrownBy(() -> new AdnuntiusBidder( + "invalid_url", + null, + Clock.systemDefaultZone(), + jacksonMapper)); } @Test - public void makeHttpRequestsShouldReturnErrorWhenSomeImpBannerIsAbsent() { + public void makeHttpRequestsShouldReturnErrorWhenSomeImpBannerAndNativeIsAbsent() { // given - final BidRequest bidRequest = givenBidRequest(givenImp(identity()), givenImp(imp -> imp.banner(null))); + final BidRequest bidRequest = givenBidRequest( + givenBannerImp(identity()), + givenNativeImp(identity()), + givenBannerImp(imp -> imp.banner(null).xNative(null))); // when final Result>> result = target.makeHttpRequests(bidRequest); @@ -86,14 +102,14 @@ public void makeHttpRequestsShouldReturnErrorWhenSomeImpBannerIsAbsent() { // then assertThat(result.getValue()).isEmpty(); assertThat(result.getErrors()).extracting(BidderError::getMessage) - .containsExactly("Fail on Imp.Id=impId: Adnuntius supports only Banner"); + .containsExactly("ignoring imp id=impId: Adnuntius supports only native and banner"); } @Test public void makeHttpRequestsShouldReturnErrorWhenSomeImpExtCouldNotBeParsed() { // given - final BidRequest bidRequest = givenBidRequest(givenImp(identity()), - givenImp(imp -> imp.ext(mapper.valueToTree(ExtPrebid.of(null, mapper.createArrayNode()))))); + final BidRequest bidRequest = givenBidRequest(givenBannerImp(identity()), + givenBannerImp(imp -> imp.ext(mapper.valueToTree(ExtPrebid.of(null, mapper.createArrayNode()))))); // when final Result>> result = target.makeHttpRequests(bidRequest); @@ -108,7 +124,8 @@ public void makeHttpRequestsShouldReturnErrorWhenSomeImpExtCouldNotBeParsed() { public void makeHttpRequestsShouldReturnRequestsWithMaxDealsIfMaxDealsIsBiggestThatZero() { // given final BidRequest bidRequest = givenBidRequest( - givenImp(ExtImpAdnuntius.builder().maxDeals(10).build(), identity())); + givenBannerImp(ExtImpAdnuntius.builder().maxDeals(10).build(), identity()), + givenNativeImp(ExtImpAdnuntius.builder().maxDeals(5).build(), identity())); // when final Result>> result = target.makeHttpRequests(bidRequest); @@ -118,15 +135,16 @@ public void makeHttpRequestsShouldReturnRequestsWithMaxDealsIfMaxDealsIsBiggestT assertThat(result.getValue()) .extracting(HttpRequest::getPayload) .flatExtracting(AdnuntiusRequest::getAdUnits) - .extracting(AdnuntiusAdUnit::getMaxDeals) - .containsExactly(10); + .extracting(AdnuntiusRequestAdUnit::getMaxDeals) + .containsExactly(10, 5); } @Test public void makeHttpRequestsShouldNotReturnRequestsWithMaxDealsIfMaxDealsIsLowestThatZero() { // given final BidRequest bidRequest = givenBidRequest( - givenImp(ExtImpAdnuntius.builder().maxDeals(-10).build(), identity())); + givenBannerImp(ExtImpAdnuntius.builder().maxDeals(-10).build(), identity()), + givenNativeImp(ExtImpAdnuntius.builder().maxDeals(-10).build(), identity())); // when final Result>> result = target.makeHttpRequests(bidRequest); @@ -136,7 +154,41 @@ public void makeHttpRequestsShouldNotReturnRequestsWithMaxDealsIfMaxDealsIsLowes assertThat(result.getValue()) .extracting(HttpRequest::getPayload) .flatExtracting(AdnuntiusRequest::getAdUnits) - .extracting(AdnuntiusAdUnit::getMaxDeals) + .extracting(AdnuntiusRequestAdUnit::getMaxDeals) + .containsOnlyNulls(); + } + + @Test + public void makeHttpRequestsShouldReturnAdTypeForNativeImp() { + // given + final BidRequest bidRequest = givenBidRequest(givenNativeImp(identity())); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + assertThat(result.getErrors()).isEmpty(); + assertThat(result.getValue()) + .extracting(HttpRequest::getPayload) + .flatExtracting(AdnuntiusRequest::getAdUnits) + .extracting(AdnuntiusRequestAdUnit::getAdType) + .containsOnly("NATIVE"); + } + + @Test + public void makeHttpRequestsShouldNotReturnAdTypeForBannerImp() { + // given + final BidRequest bidRequest = givenBidRequest(givenBannerImp(identity())); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + assertThat(result.getErrors()).isEmpty(); + assertThat(result.getValue()) + .extracting(HttpRequest::getPayload) + .flatExtracting(AdnuntiusRequest::getAdUnits) + .extracting(AdnuntiusRequestAdUnit::getAdType) .containsNull(); } @@ -144,7 +196,7 @@ public void makeHttpRequestsShouldNotReturnRequestsWithMaxDealsIfMaxDealsIsLowes public void makeHttpRequestsShouldReturnRequestsWithDimensionsIfBannerHighAndWidthArePresent() { // given final BidRequest bidRequest = givenBidRequest( - givenImp(imp -> imp.banner(Banner.builder().w(150).h(200).build()))); + givenBannerImp(imp -> imp.banner(Banner.builder().w(150).h(200).build()))); // when final Result>> result = target.makeHttpRequests(bidRequest); @@ -154,7 +206,7 @@ public void makeHttpRequestsShouldReturnRequestsWithDimensionsIfBannerHighAndWid assertThat(result.getValue()) .extracting(HttpRequest::getPayload) .flatExtracting(AdnuntiusRequest::getAdUnits) - .extracting(AdnuntiusAdUnit::getDimensions) + .extracting(AdnuntiusRequestAdUnit::getDimensions) .containsExactly(List.of(List.of(150, 200))); } @@ -162,7 +214,7 @@ public void makeHttpRequestsShouldReturnRequestsWithDimensionsIfBannerHighAndWid public void makeHttpRequestsShouldReturnRequestsWithDimensionsIfBannerFormatHighAndWidthArePresent() { // given final BidRequest bidRequest = givenBidRequest( - givenImp(imp -> imp.banner(Banner.builder() + givenBannerImp(imp -> imp.banner(Banner.builder() .format(List.of( Format.builder().w(150).h(200).build(), Format.builder().w(100).h(300).build())) @@ -178,14 +230,14 @@ public void makeHttpRequestsShouldReturnRequestsWithDimensionsIfBannerFormatHigh assertThat(result.getValue()) .extracting(HttpRequest::getPayload) .flatExtracting(AdnuntiusRequest::getAdUnits) - .extracting(AdnuntiusAdUnit::getDimensions) + .extracting(AdnuntiusRequestAdUnit::getDimensions) .containsExactly(List.of(List.of(150, 200), List.of(100, 300))); } @Test public void makeHttpRequestsShouldReturnRequestsWithoutDimensionsIfBannerFormatHighAndWidthAreAbsent() { // given - final BidRequest bidRequest = givenBidRequest(givenImp(identity())); + final BidRequest bidRequest = givenBidRequest(givenBannerImp(identity())); // when final Result>> result = target.makeHttpRequests(bidRequest); @@ -195,18 +247,37 @@ public void makeHttpRequestsShouldReturnRequestsWithoutDimensionsIfBannerFormatH assertThat(result.getValue()) .extracting(HttpRequest::getPayload) .flatExtracting(AdnuntiusRequest::getAdUnits) - .extracting(AdnuntiusAdUnit::getDimensions) + .extracting(AdnuntiusRequestAdUnit::getDimensions) .containsOnlyNulls(); } @Test - public void makeHttpRequestsShouldReturnRequestsWithAdUnitsSeparatedByImpExtNetwork() { + public void makeHttpRequestsShouldReturnNativeRequestAdUnitForNativeImp() { + // given + final BidRequest bidRequest = givenBidRequest(givenNativeImp(imp -> + imp.xNative(Native.builder().request("{\"field\":\"value\"}").build()))); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + assertThat(result.getErrors()).isEmpty(); + assertThat(result.getValue()) + .extracting(HttpRequest::getPayload) + .flatExtracting(AdnuntiusRequest::getAdUnits) + .extracting(AdnuntiusRequestAdUnit::getNativeRequest) + .extracting(AdnuntiusNativeRequest::getOrtb) + .allSatisfy(ortb -> assertThat(ortb).isEqualTo(mapper.createObjectNode().put("field", "value"))); + } + + @Test + public void makeHttpRequestsShouldReturnRequestsWithAdUnitsSeparatedByBannerImpExtNetwork() { // given final BidRequest bidRequest = givenBidRequest( - givenImp(ExtImpAdnuntius.builder().auId("auId1").build(), identity()), - givenImp(ExtImpAdnuntius.builder().auId("auId2").build(), identity()), - givenImp(ExtImpAdnuntius.builder().auId("auId1").network("network").build(), identity()), - givenImp(ExtImpAdnuntius.builder().auId("auId2").network("network").build(), identity())); + givenBannerImp(ExtImpAdnuntius.builder().auId("auId1").build(), identity()), + givenBannerImp(ExtImpAdnuntius.builder().auId("auId2").build(), identity()), + givenBannerImp(ExtImpAdnuntius.builder().auId("auId1").network("network").build(), identity()), + givenBannerImp(ExtImpAdnuntius.builder().auId("auId2").network("network").build(), identity())); // when final Result>> result = target.makeHttpRequests(bidRequest); @@ -216,7 +287,29 @@ public void makeHttpRequestsShouldReturnRequestsWithAdUnitsSeparatedByImpExtNetw .extracting(HttpRequest::getPayload) .extracting(AdnuntiusRequest::getAdUnits) .allSatisfy(adUnits -> assertThat(adUnits) - .extracting(AdnuntiusAdUnit::getAuId) + .extracting(AdnuntiusRequestAdUnit::getAuId) + .containsExactly("auId1", "auId2")); + assertThat(result.getErrors()).isEmpty(); + } + + @Test + public void makeHttpRequestsShouldReturnRequestsWithAdUnitsSeparatedByNativeImpExtNetwork() { + // given + final BidRequest bidRequest = givenBidRequest( + givenNativeImp(ExtImpAdnuntius.builder().auId("auId1").build(), identity()), + givenNativeImp(ExtImpAdnuntius.builder().auId("auId2").build(), identity()), + givenNativeImp(ExtImpAdnuntius.builder().auId("auId1").network("network").build(), identity()), + givenNativeImp(ExtImpAdnuntius.builder().auId("auId2").network("network").build(), identity())); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + assertThat(result.getValue()).hasSize(2) + .extracting(HttpRequest::getPayload) + .extracting(AdnuntiusRequest::getAdUnits) + .allSatisfy(adUnits -> assertThat(adUnits) + .extracting(AdnuntiusRequestAdUnit::getAuId) .containsExactly("auId1", "auId2")); assertThat(result.getErrors()).isEmpty(); } @@ -225,9 +318,9 @@ public void makeHttpRequestsShouldReturnRequestsWithAdUnitsSeparatedByImpExtNetw public void makeHttpRequestsShouldReturnRequestsWithCorrectAdUnits() { // given final BidRequest bidRequest = givenBidRequest( - givenImp(imp -> imp.id(null)), - givenImp(ExtImpAdnuntius.builder().auId("auId").build(), imp -> imp.id(null)), - givenImp(ExtImpAdnuntius.builder().auId("auId").build(), imp -> imp.id("impId"))); + givenBannerAndNativeImp(ExtImpAdnuntius.builder().build(), imp -> imp.id(null)), + givenBannerAndNativeImp(ExtImpAdnuntius.builder().auId("auId").build(), imp -> imp.id(null)), + givenBannerAndNativeImp(ExtImpAdnuntius.builder().auId("auId").build(), imp -> imp.id("impId"))); // when final Result>> result = target.makeHttpRequests(bidRequest); @@ -236,8 +329,35 @@ public void makeHttpRequestsShouldReturnRequestsWithCorrectAdUnits() { assertThat(result.getValue()).hasSize(1) .extracting(HttpRequest::getPayload) .flatExtracting(AdnuntiusRequest::getAdUnits) - .extracting(AdnuntiusAdUnit::getAuId, AdnuntiusAdUnit::getTargetId) - .containsExactly(tuple(null, "null-null"), tuple("auId", "auId-null"), tuple("auId", "auId-impId")); + .extracting(AdnuntiusRequestAdUnit::getAuId, AdnuntiusRequestAdUnit::getTargetId) + .containsExactly( + tuple(null, "null-null:banner"), + tuple(null, "null-null:native"), + tuple("auId", "auId-null:banner"), + tuple("auId", "auId-null:native"), + tuple("auId", "auId-impId:banner"), + tuple("auId", "auId-impId:native")); + assertThat(result.getErrors()).isEmpty(); + } + + @Test + public void makeHttpRequestsShouldReturnRequestsWithTheWholeListOfImpIds() { + // given + final BidRequest bidRequest = givenBidRequest( + givenBannerAndNativeImp( + ExtImpAdnuntius.builder().auId("auId").build(), imp -> imp.id("impId1")), + givenNativeImp( + ExtImpAdnuntius.builder().auId("auId").build(), imp -> imp.id("impId2")), + givenBannerImp( + ExtImpAdnuntius.builder().auId("auId").network("network").build(), imp -> imp.id("impId3"))); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + assertThat(result.getValue()).hasSize(2) + .extracting(HttpRequest::getImpIds) + .containsExactlyInAnyOrder(Set.of("impId1", "impId2", "impId3"), Set.of("impId1", "impId2", "impId3")); assertThat(result.getErrors()).isEmpty(); } @@ -246,8 +366,8 @@ public void makeHttpRequestsShouldReturnRequestsWithMetaDataIfUserIdIsPresent() // given final BidRequest bidRequest = givenBidRequest( request -> request.user(User.builder().id("userId").build()), - givenImp(ExtImpAdnuntius.builder().network("network").build(), identity()), - givenImp(identity())); + givenBannerImp(ExtImpAdnuntius.builder().network("network").build(), identity()), + givenBannerImp(identity())); // when final Result>> result = target.makeHttpRequests(bidRequest); @@ -271,8 +391,8 @@ public void makeHttpRequestsShouldPopulateMetaDataUsiFromUserIdWhenBothUidIdAndU .eids(List.of(Eid.builder().uids(List.of(Uid.builder().id("eidsId").build())).build())) .build()) .build()), - givenImp(ExtImpAdnuntius.builder().network("network").build(), identity()), - givenImp(identity())); + givenBannerImp(ExtImpAdnuntius.builder().network("network").build(), identity()), + givenBannerImp(identity())); // when final Result>> result = target.makeHttpRequests(bidRequest); @@ -296,8 +416,8 @@ public void makeHttpRequestsShouldPopulateMetaDataUsiWhenUserExtEidsUidIdPresent .eids(List.of(Eid.builder().uids(List.of(Uid.builder().id("eidsId").build())).build())) .build()) .build()), - givenImp(ExtImpAdnuntius.builder().network("network").build(), identity()), - givenImp(identity())); + givenBannerImp(ExtImpAdnuntius.builder().network("network").build(), identity()), + givenBannerImp(identity())); // when final Result>> result = target.makeHttpRequests(bidRequest); @@ -318,8 +438,8 @@ public void makeHttpRequestsShouldPopulateHttpRequestKeyValueFieldFromSiteExtDat request -> request.site(Site.builder() .ext(ExtSite.of(null, mapper.createObjectNode().put("ANY", "ANY"))) .build()), - givenImp(ExtImpAdnuntius.builder().network("network").build(), identity()), - givenImp(identity())); + givenBannerImp(ExtImpAdnuntius.builder().network("network").build(), identity()), + givenBannerImp(identity())); // when final Result>> result = target.makeHttpRequests(bidRequest); @@ -339,7 +459,7 @@ public void makeHttpRequestsShouldReturnRequestsWithHeadersIfDeviceIsPresent() { // given final BidRequest bidRequest = givenBidRequest( request -> request.device(Device.builder().ip("ip").ua("ua").build()), - givenImp(identity())); + givenBannerImp(identity())); // when final Result>> result = target.makeHttpRequests(bidRequest); @@ -362,8 +482,8 @@ public void makeHttpRequestsShouldReturnRequestsWithContextIfSitePageIsPresent() // given final BidRequest bidRequest = givenBidRequest( request -> request.site(Site.builder().page("page").build()), - givenImp(ExtImpAdnuntius.builder().network("network").build(), identity()), - givenImp(identity())); + givenBannerImp(ExtImpAdnuntius.builder().network("network").build(), identity()), + givenBannerImp(identity())); // when final Result>> result = target.makeHttpRequests(bidRequest); @@ -382,14 +502,14 @@ public void makeHttpRequestsShouldReturnRequestsWithCorrectUriIfGdprAndConsentAr request -> request .regs(Regs.builder().ext(ExtRegs.of(null, null, null, null)).build()) .user(User.builder().ext(ExtUser.builder().consent(null).build()).build()), - givenImp(identity()), - givenImp(ExtImpAdnuntius.builder().network("network").build(), identity())); + givenBannerImp(identity()), + givenBannerImp(ExtImpAdnuntius.builder().network("network").build(), identity())); // when final Result>> result = target.makeHttpRequests(bidRequest); // then - final String expectedUrl = givenExpectedUrl(null, null); + final String expectedUrl = buildExpectedUrl(ENDPOINT_URL, null, null, null); assertThat(result.getValue()) .extracting(HttpRequest::getUri) @@ -404,14 +524,14 @@ public void makeHttpRequestsShouldReturnRequestsWithCorrectUriIfGdprIsAbsent() { request -> request .regs(Regs.builder().ext(ExtRegs.of(null, null, null, null)).build()) .user(User.builder().ext(ExtUser.builder().consent("consent").build()).build()), - givenImp(identity()), - givenImp(ExtImpAdnuntius.builder().network("network").build(), identity())); + givenBannerImp(identity()), + givenBannerImp(ExtImpAdnuntius.builder().network("network").build(), identity())); // when final Result>> result = target.makeHttpRequests(bidRequest); // then - final String expectedUrl = givenExpectedUrl(null, "consent"); + final String expectedUrl = givenExpectedUrl(ENDPOINT_URL, null, "consent"); assertThat(result.getValue()) .extracting(HttpRequest::getUri) @@ -423,17 +543,15 @@ public void makeHttpRequestsShouldReturnRequestsWithCorrectUriIfGdprIsAbsent() { public void makeHttpRequestsShouldReturnRequestsWithCorrectUriIfConsentIsAbsent() { // given final BidRequest bidRequest = givenBidRequest( - request -> request - .regs(Regs.builder().ext(ExtRegs.of(1, null, null, null)).build()) - .user(User.builder().ext(ExtUser.builder().consent(null).build()).build()), - givenImp(identity()), - givenImp(ExtImpAdnuntius.builder().network("network").build(), identity())); + request -> request.user(User.builder().ext(ExtUser.builder().consent(null).build()).build()), + givenBannerImp(identity()), + givenBannerImp(ExtImpAdnuntius.builder().network("network").build(), identity())); // when final Result>> result = target.makeHttpRequests(bidRequest); // then - final String expectedUrl = givenExpectedUrl(1, null); + final String expectedUrl = givenExpectedUrl(ENDPOINT_URL, null); assertThat(result.getValue()) .extracting(HttpRequest::getUri) @@ -450,14 +568,14 @@ public void makeHttpRequestsShouldReturnRequestsWithCorrectUri() { request -> request .regs(Regs.builder().ext(ExtRegs.of(gdpr, null, null, null)).build()) .user(User.builder().ext(ExtUser.builder().consent(consent).build()).build()), - givenImp(identity()), - givenImp(ExtImpAdnuntius.builder().network("network").build(), identity())); + givenBannerImp(identity()), + givenBannerImp(ExtImpAdnuntius.builder().network("network").build(), identity())); // when final Result>> result = target.makeHttpRequests(bidRequest); // then - final String expectedUrl = givenExpectedUrl(gdpr, consent); + final String expectedUrl = givenExpectedUrl(ENDPOINT_URL, gdpr, consent); assertThat(result.getValue()) .extracting(HttpRequest::getUri) @@ -469,14 +587,14 @@ public void makeHttpRequestsShouldReturnRequestsWithCorrectUri() { public void makeHttpRequestsShouldReturnRequestsWithCorrectUriIfExtImpNoCookiesIsNull() { // given final BidRequest bidRequest = givenBidRequest(identity(), - givenImp(ExtImpAdnuntius.builder().network("network").build(), identity()), - givenImp(identity())); + givenBannerImp(ExtImpAdnuntius.builder().network("network").build(), identity()), + givenBannerImp(identity())); // when final Result>> result = target.makeHttpRequests(bidRequest); // then - final String expectedUrl = givenExpectedUrl(null); + final String expectedUrl = givenExpectedUrl(ENDPOINT_URL, null); assertThat(result.getValue()) .extracting(HttpRequest::getUri) @@ -490,14 +608,14 @@ public void makeHttpRequestsShouldReturnRequestsWithCorrectUriIfExtImpNoCookiesI final Boolean noCookies = false; final BidRequest bidRequest = givenBidRequest( identity(), - givenImp(ExtImpAdnuntius.builder().network("network").noCookies(noCookies).build(), identity()), - givenImp(identity())); + givenBannerImp(ExtImpAdnuntius.builder().network("network").noCookies(noCookies).build(), identity()), + givenBannerImp(identity())); // when final Result>> result = target.makeHttpRequests(bidRequest); // then - final String expectedUrl = givenExpectedUrl(noCookies); + final String expectedUrl = givenExpectedUrl(ENDPOINT_URL, noCookies); assertThat(result.getValue()) .extracting(HttpRequest::getUri) @@ -511,14 +629,14 @@ public void makeHttpRequestsShouldReturnRequestsWithCorrectUriIfExtImpNoCookiesI final Boolean noCookies = true; final BidRequest bidRequest = givenBidRequest( identity(), - givenImp(ExtImpAdnuntius.builder().network("network").noCookies(noCookies).build(), identity()), - givenImp(ExtImpAdnuntius.builder().noCookies(!noCookies).build(), identity())); + givenBannerImp(ExtImpAdnuntius.builder().network("network").noCookies(noCookies).build(), identity()), + givenBannerImp(ExtImpAdnuntius.builder().noCookies(!noCookies).build(), identity())); // when final Result>> result = target.makeHttpRequests(bidRequest); // then - final String expectedUrl = givenExpectedUrl(noCookies); + final String expectedUrl = givenExpectedUrl(ENDPOINT_URL, noCookies); assertThat(result.getValue()) .extracting(HttpRequest::getUri) @@ -531,14 +649,14 @@ public void makeHttpRequestsShouldReturnRequestsWithCorrectUriAndPopulateExtDevi // given final BidRequest bidRequest = givenBidRequest( request -> request.device(Device.builder().ext(givenExtDeviceNoCookies(null)).build()), - givenImp(identity()), - givenImp(ExtImpAdnuntius.builder().network("network").build(), identity())); + givenBannerImp(identity()), + givenBannerImp(ExtImpAdnuntius.builder().network("network").build(), identity())); // when final Result>> result = target.makeHttpRequests(bidRequest); // then - final String expectedUrl = givenExpectedUrl(null); + final String expectedUrl = givenExpectedUrl(ENDPOINT_URL, null); assertThat(result.getValue()) .extracting(HttpRequest::getUri) @@ -552,14 +670,14 @@ public void makeHttpRequestsShouldReturnRequestsWithCorrectUriIfExtDeviceImpNoCo final Boolean noCookies = false; final BidRequest bidRequest = givenBidRequest( request -> request.device(Device.builder().ext(givenExtDeviceNoCookies(noCookies)).build()), - givenImp(identity()), - givenImp(ExtImpAdnuntius.builder().network("network").build(), identity())); + givenBannerImp(identity()), + givenBannerImp(ExtImpAdnuntius.builder().network("network").build(), identity())); // when final Result>> result = target.makeHttpRequests(bidRequest); // then - final String expectedUrl = givenExpectedUrl(noCookies); + final String expectedUrl = givenExpectedUrl(ENDPOINT_URL, noCookies); assertThat(result.getValue()) .extracting(HttpRequest::getUri) @@ -573,14 +691,318 @@ public void makeHttpRequestsShouldReturnRequestsWithCorrectUriIfExtDeviceImpNoCo final Boolean noCookies = true; final BidRequest bidRequest = givenBidRequest( request -> request.device(Device.builder().ext(givenExtDeviceNoCookies(noCookies)).build()), - givenImp(identity()), - givenImp(ExtImpAdnuntius.builder().network("network").build(), identity())); + givenBannerImp(identity()), + givenBannerImp(ExtImpAdnuntius.builder().network("network").build(), identity())); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + final String expectedUrl = givenExpectedUrl(ENDPOINT_URL, noCookies); + + assertThat(result.getValue()) + .extracting(HttpRequest::getUri) + .containsExactly(expectedUrl, expectedUrl); + assertThat(result.getErrors()).isEmpty(); + } + + @Test + public void makeHttpRequestsShouldReturnRequestsWithBasicUriIfGdprAndConsentAreAbsentWhenAlternativeUriProvided() { + // given + target = new AdnuntiusBidder( + ENDPOINT_URL, + ALTERNATIVE_URL, + Clock.system(ZoneId.of("UTC+05:00")), + jacksonMapper); + + final BidRequest bidRequest = givenBidRequest( + request -> request + .regs(Regs.builder().ext(ExtRegs.of(null, null, null, null)).build()) + .user(User.builder().ext(ExtUser.builder().consent(null).build()).build()), + givenBannerImp(identity()), + givenBannerImp(ExtImpAdnuntius.builder().network("network").build(), identity())); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + final String expectedUrl = buildExpectedUrl(ENDPOINT_URL, null, null, null); + + assertThat(result.getValue()) + .extracting(HttpRequest::getUri) + .containsExactly(expectedUrl, expectedUrl); + assertThat(result.getErrors()).isEmpty(); + } + + @Test + public void makeHttpRequestsShouldReturnRequestsWithBasicUriIfGdprIsAbsentWhenAlternativeUriProvided() { + // given + target = new AdnuntiusBidder( + ENDPOINT_URL, + ALTERNATIVE_URL, + Clock.system(ZoneId.of("UTC+05:00")), + jacksonMapper); + + final BidRequest bidRequest = givenBidRequest( + request -> request + .regs(Regs.builder().ext(ExtRegs.of(null, null, null, null)).build()) + .user(User.builder().ext(ExtUser.builder().consent("consent").build()).build()), + givenBannerImp(identity()), + givenBannerImp(ExtImpAdnuntius.builder().network("network").build(), identity())); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + final String expectedUrl = givenExpectedUrl(ENDPOINT_URL, null, "consent"); + + assertThat(result.getValue()) + .extracting(HttpRequest::getUri) + .containsExactly(expectedUrl, expectedUrl); + assertThat(result.getErrors()).isEmpty(); + } + + @Test + public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfConsentIsAbsentAndGdprIsPresent() { + // given + target = new AdnuntiusBidder( + ENDPOINT_URL, + ALTERNATIVE_URL, + Clock.system(ZoneId.of("UTC+05:00")), + jacksonMapper); + + final BidRequest bidRequest = givenBidRequest( + request -> request + .regs(Regs.builder().ext(ExtRegs.of(1, null, null, null)).build()) + .user(User.builder().ext(ExtUser.builder().consent(null).build()).build()), + givenBannerImp(identity()), + givenBannerImp(ExtImpAdnuntius.builder().network("network").build(), identity())); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + final String expectedUrl = buildExpectedUrl(ALTERNATIVE_URL, 1, null, null); + + assertThat(result.getValue()) + .extracting(HttpRequest::getUri) + .containsExactly(expectedUrl, expectedUrl); + assertThat(result.getErrors()).isEmpty(); + } + + @Test + public void makeHttpRequestsShouldFailWhenGdprIsPresentAndAlternativeUriIsInvalid() { + // given + target = new AdnuntiusBidder( + ENDPOINT_URL, + "invalid_url", + Clock.system(ZoneId.of("UTC+05:00")), + jacksonMapper); + + final BidRequest bidRequest = givenBidRequest( + request -> request + .regs(Regs.builder().ext(ExtRegs.of(1, null, null, null)).build()) + .user(User.builder().ext(ExtUser.builder().consent(null).build()).build()), + givenBannerImp(identity()), + givenBannerImp(ExtImpAdnuntius.builder().network("network").build(), identity())); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + assertThat(result.getErrors()).containsExactly(BidderError.badInput("URL supplied is not valid: invalid_url")); + assertThat(result.getValue()).isEmpty(); + } + + @Test + public void makeHttpRequestsShouldReturnRequestsWithAlternativeUri() { + // given + target = new AdnuntiusBidder( + ENDPOINT_URL, + ALTERNATIVE_URL, + Clock.system(ZoneId.of("UTC+05:00")), + jacksonMapper); + + final Integer gdpr = 1; + final String consent = "con sent"; + final BidRequest bidRequest = givenBidRequest( + request -> request + .regs(Regs.builder().ext(ExtRegs.of(gdpr, null, null, null)).build()) + .user(User.builder().ext(ExtUser.builder().consent(consent).build()).build()), + givenBannerImp(identity()), + givenBannerImp(ExtImpAdnuntius.builder().network("network").build(), identity())); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + final String expectedUrl = givenExpectedUrl(ALTERNATIVE_URL, gdpr, consent); + + assertThat(result.getValue()) + .extracting(HttpRequest::getUri) + .containsExactly(expectedUrl, expectedUrl); + assertThat(result.getErrors()).isEmpty(); + } + + @Test + public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfExtImpNoCookiesIsNull() { + // given + target = new AdnuntiusBidder( + ENDPOINT_URL, + ALTERNATIVE_URL, + Clock.system(ZoneId.of("UTC+05:00")), + jacksonMapper); + + final BidRequest bidRequest = givenBidRequest( + request -> request.regs(Regs.builder().ext(ExtRegs.of(1, null, null, null)).build()), + givenBannerImp(ExtImpAdnuntius.builder().network("network").build(), identity()), + givenBannerImp(identity())); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + final String expectedUrl = buildExpectedUrl(ALTERNATIVE_URL, 1, null, null); + + assertThat(result.getValue()) + .extracting(HttpRequest::getUri) + .containsExactly(expectedUrl, expectedUrl); + assertThat(result.getErrors()).isEmpty(); + } + + @Test + public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfExtImpNoCookiesIsFalse() { + // given + target = new AdnuntiusBidder( + ENDPOINT_URL, + ALTERNATIVE_URL, + Clock.system(ZoneId.of("UTC+05:00")), + jacksonMapper); + + final Boolean noCookies = false; + final BidRequest bidRequest = givenBidRequest( + request -> request.regs(Regs.builder().ext(ExtRegs.of(1, null, null, null)).build()), + givenBannerImp(ExtImpAdnuntius.builder().network("network").noCookies(noCookies).build(), identity()), + givenBannerImp(identity())); // when final Result>> result = target.makeHttpRequests(bidRequest); // then - final String expectedUrl = givenExpectedUrl(noCookies); + final String expectedUrl = givenExpectedUrl(ALTERNATIVE_URL, 1, noCookies); + + assertThat(result.getValue()) + .extracting(HttpRequest::getUri) + .containsExactly(expectedUrl, expectedUrl); + assertThat(result.getErrors()).isEmpty(); + } + + @Test + public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfExtImpNoCookiesIsTrue() { + // given + target = new AdnuntiusBidder( + ENDPOINT_URL, + ALTERNATIVE_URL, + Clock.system(ZoneId.of("UTC+05:00")), + jacksonMapper); + + final Boolean noCookies = true; + final BidRequest bidRequest = givenBidRequest( + request -> request.regs(Regs.builder().ext(ExtRegs.of(1, null, null, null)).build()), + givenBannerImp(ExtImpAdnuntius.builder().network("network").noCookies(noCookies).build(), identity()), + givenBannerImp(ExtImpAdnuntius.builder().noCookies(!noCookies).build(), identity())); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + final String expectedUrl = givenExpectedUrl(ALTERNATIVE_URL, 1, noCookies); + + assertThat(result.getValue()) + .extracting(HttpRequest::getUri) + .containsExactly(expectedUrl, expectedUrl); + assertThat(result.getErrors()).isEmpty(); + } + + @Test + public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriAndPopulateExtDeviceWithNoCookies() { + // given + target = new AdnuntiusBidder( + ENDPOINT_URL, + ALTERNATIVE_URL, + Clock.system(ZoneId.of("UTC+05:00")), + jacksonMapper); + + final BidRequest bidRequest = givenBidRequest( + request -> request + .regs(Regs.builder().ext(ExtRegs.of(1, null, null, null)).build()) + .device(Device.builder().ext(givenExtDeviceNoCookies(null)).build()), + givenBannerImp(identity()), + givenBannerImp(ExtImpAdnuntius.builder().network("network").build(), identity())); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + final String expectedUrl = buildExpectedUrl(ALTERNATIVE_URL, 1, null, null); + + assertThat(result.getValue()) + .extracting(HttpRequest::getUri) + .containsExactly(expectedUrl, expectedUrl); + assertThat(result.getErrors()).isEmpty(); + } + + @Test + public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfExtDeviceImpNoCookiesIsFalse() { + // given + target = new AdnuntiusBidder( + ENDPOINT_URL, + ALTERNATIVE_URL, + Clock.system(ZoneId.of("UTC+05:00")), + jacksonMapper); + + final Boolean noCookies = false; + final BidRequest bidRequest = givenBidRequest( + request -> request + .regs(Regs.builder().ext(ExtRegs.of(1, null, null, null)).build()) + .device(Device.builder().ext(givenExtDeviceNoCookies(noCookies)).build()), + givenBannerImp(identity()), + givenBannerImp(ExtImpAdnuntius.builder().network("network").build(), identity())); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + final String expectedUrl = givenExpectedUrl(ALTERNATIVE_URL, 1, noCookies); + + assertThat(result.getValue()) + .extracting(HttpRequest::getUri) + .containsExactly(expectedUrl, expectedUrl); + assertThat(result.getErrors()).isEmpty(); + } + + @Test + public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfExtDeviceImpNoCookiesIsTrue() { + // given + target = new AdnuntiusBidder( + ENDPOINT_URL, + ALTERNATIVE_URL, + Clock.system(ZoneId.of("UTC+05:00")), + jacksonMapper); + + final Boolean noCookies = true; + final BidRequest bidRequest = givenBidRequest( + request -> request + .regs(Regs.builder().ext(ExtRegs.of(1, null, null, null)).build()) + .device(Device.builder().ext(givenExtDeviceNoCookies(noCookies)).build()), + givenBannerImp(identity()), + givenBannerImp(ExtImpAdnuntius.builder().network("network").build(), identity())); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + final String expectedUrl = givenExpectedUrl(ALTERNATIVE_URL, 1, noCookies); assertThat(result.getValue()) .extracting(HttpRequest::getUri) @@ -648,7 +1070,7 @@ public void makeBidsShouldReturnEmptyListIfResponseAdsUnitsIsEmpty() throws Json public void makeBidsShouldSkipInvalidAdsUnits() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall(givenAdsUnitWithAds("auId")); - final BidRequest bidRequest = givenBidRequest(givenImp(identity())); + final BidRequest bidRequest = givenBidRequest(givenBannerImp(identity())); // when final Result> result = target.makeBids(httpCall, bidRequest); @@ -664,16 +1086,16 @@ public void makeBidsShouldUseCurrencyOfFirstBidOfLastRelatedImp() throws JsonPro final BidderCall httpCall = givenHttpCall( givenAdsUnitWithAds( "au1", - givenAd(ad -> ad.bid(AdnuntiusBid.of(null, "1.1"))), - givenAd(ad -> ad.bid(AdnuntiusBid.of(null, "1.2")))), + givenAd(ad -> ad.bid(AdnuntiusBid.of(BigDecimal.ONE, "1.1"))), + givenAd(ad -> ad.bid(AdnuntiusBid.of(BigDecimal.ONE, "1.2")))), givenAdsUnitWithAds( "au2", - givenAd(ad -> ad.bid(AdnuntiusBid.of(null, "2.1"))), - givenAd(ad -> ad.bid(AdnuntiusBid.of(null, "2.2"))))); + givenAd(ad -> ad.bid(AdnuntiusBid.of(BigDecimal.ONE, "2.1"))), + givenAd(ad -> ad.bid(AdnuntiusBid.of(BigDecimal.ONE, "2.2"))))); final BidRequest bidRequest = givenBidRequest( - givenImp(ExtImpAdnuntius.builder().auId("au2").build(), identity()), - givenImp(ExtImpAdnuntius.builder().auId("au1").build(), identity())); + givenBannerImp(ExtImpAdnuntius.builder().auId("au2").build(), identity()), + givenBannerImp(ExtImpAdnuntius.builder().auId("au1").build(), identity())); // when final Result> result = target.makeBids(httpCall, bidRequest); @@ -689,9 +1111,11 @@ public void makeBidsShouldUseCurrencyOfFirstBidOfLastRelatedImp() throws JsonPro public void makeBidsShouldPopulateGrossBidPriceWhenGrossBidSpecified() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( - givenAdsUnitWithAds("auId", givenAd(ad -> ad.grossBid(AdnuntiusGrossBid.of(BigDecimal.ONE))))); + givenAdsUnitWithAds("auId", givenAd(ad -> ad + .bid(AdnuntiusBid.of(BigDecimal.TWO, "USD")) + .grossBid(AdnuntiusGrossBid.of(BigDecimal.ONE))))); final BidRequest bidRequest = givenBidRequest( - givenImp(ExtImpAdnuntius.builder().auId("auId").bidType("gross").build(), identity())); + givenBannerImp(ExtImpAdnuntius.builder().auId("auId").bidType("gross").build(), identity())); // when final Result> result = target.makeBids(httpCall, bidRequest); @@ -708,9 +1132,11 @@ public void makeBidsShouldPopulateGrossBidPriceWhenGrossBidSpecified() throws Js public void makeBidsShouldPopulateNetBidPriceWhenGrossBidSpecified() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( - givenAdsUnitWithAds("auId", givenAd(ad -> ad.netBid(AdnuntiusNetBid.of(BigDecimal.ONE))))); + givenAdsUnitWithAds("auId", givenAd(ad -> ad + .bid(AdnuntiusBid.of(BigDecimal.TWO, "USD")) + .netBid(AdnuntiusNetBid.of(BigDecimal.ONE))))); final BidRequest bidRequest = givenBidRequest( - givenImp(ExtImpAdnuntius.builder().auId("auId").bidType("net").build(), identity())); + givenBannerImp(ExtImpAdnuntius.builder().auId("auId").bidType("net").build(), identity())); // when final Result> result = target.makeBids(httpCall, bidRequest); @@ -729,7 +1155,7 @@ public void makeBidsShouldNotReturnBidFromDealsWhenAdsIsAbsentAndDealsIsSpecifie final BidderCall httpCall = givenHttpCall(givenAdsUnitWithDeals("auId", givenAd(identity()))); final BidRequest bidRequest = givenBidRequest( - givenImp(ExtImpAdnuntius.builder().auId("auId").build(), identity())); + givenBannerImp(ExtImpAdnuntius.builder().auId("auId").build(), identity())); // when final Result> result = target.makeBids(httpCall, bidRequest); @@ -742,7 +1168,7 @@ public void makeBidsShouldNotReturnBidFromDealsWhenAdsIsAbsentAndDealsIsSpecifie @Test public void makeBidsShouldReturnTwoBidFromDealsAndAdsWhenAdsAndDealsIsSpecified() throws JsonProcessingException { // given - final BidderCall httpCall = givenHttpCall(givenAdsUnitWithDealsAndAds( + final BidderCall httpCall = givenHttpCall(givenBannerAdsUnitWithDealsAndAds( "auId", List.of(givenAd(ad -> ad .bid(AdnuntiusBid.of(BigDecimal.ONE, "USD")) @@ -762,7 +1188,7 @@ public void makeBidsShouldReturnTwoBidFromDealsAndAdsWhenAdsAndDealsIsSpecified( .advertiser(AdnuntiusAdvertiser.of("legalName", "name")) .advertiserDomains(List.of("domain1.com", "domain2.dt")))))); - final BidRequest bidRequest = givenBidRequest(givenImp( + final BidRequest bidRequest = givenBidRequest(givenBannerImp( ExtImpAdnuntius.builder().auId("auId").build(), identity())); // when @@ -780,7 +1206,87 @@ public void makeBidsShouldReturnTwoBidFromDealsAndAdsWhenAdsAndDealsIsSpecified( assertThat(bid).extracting(Bid::getCid).isEqualTo("lineItemId"); assertThat(bid).extracting(Bid::getDealid).isEqualTo("dealId"); assertThat(bid).extracting(Bid::getCrid).isEqualTo("creativeId"); + assertThat(bid).extracting(Bid::getMtype).isEqualTo(1); + assertThat(bid).extracting(Bid::getPrice).isEqualTo(BigDecimal.valueOf(1000)); + assertThat(bid).extracting(Bid::getAdomain).asList() + .containsExactlyInAnyOrder("domain1.com", "domain2.dt"); + assertThat(bid).extracting(Bid::getExt).isNull(); + }); + assertThat(bidderBid).extracting(BidderBid::getType).isEqualTo(BidType.banner); + assertThat(bidderBid).extracting(BidderBid::getBidCurrency).isEqualTo("USD"); + }); + assertThat(result.getErrors()).isEmpty(); + } + + @Test + public void makeBidsShouldReturnTwoBidFromDealsAndAdsWhenNativeAdsAndDealsIsSpecified() + throws JsonProcessingException { + + // given + final BidderCall httpCall = givenHttpCall(givenNativeAdsUnitWithDealsAndAds( + "auId", + List.of(givenAd(ad -> ad + .bid(AdnuntiusBid.of(BigDecimal.ONE, "USD")) + .adId("adId") + .creativeId("creativeId") + .lineItemId("lineItemId") + .dealId("dealId") + .advertiser(AdnuntiusAdvertiser.of(null, "name")) + .advertiserDomains(List.of("domain1.com", "domain2.dt")))), + List.of(givenAd(ad -> ad + .bid(AdnuntiusBid.of(BigDecimal.ONE, "USD")) + .adId("adId") + .creativeId("creativeId") + .lineItemId("lineItemId") + .dealId("dealId") + .html("dealHtml") + .advertiser(AdnuntiusAdvertiser.of("legalName", "name")) + .advertiserDomains(List.of("domain1.com", "domain2.dt")))), + "{\"ortb\":{\"property\":\"value\"}}")); + + final BidRequest bidRequest = givenBidRequest(givenBannerImp( + ExtImpAdnuntius.builder().auId("auId").build(), identity())); + + // when + final Result> result = target.makeBids(httpCall, bidRequest); + + // then + assertThat(result.getValue()).hasSize(2); + + assertThat(result.getValue().getFirst()).satisfies(bidderBid -> { + assertThat(bidderBid).extracting(BidderBid::getBid).satisfies(bid -> { + assertThat(bid).extracting(Bid::getId).isEqualTo("adId"); + assertThat(bid).extracting(Bid::getImpid).isEqualTo("impId"); + assertThat(bid).extracting(Bid::getW).isEqualTo(21); + assertThat(bid).extracting(Bid::getH).isEqualTo(9); + assertThat(bid).extracting(Bid::getAdid).isEqualTo("adId"); + assertThat(bid).extracting(Bid::getAdm).isEqualTo("{\"property\":\"value\"}"); + assertThat(bid).extracting(Bid::getCid).isEqualTo("lineItemId"); + assertThat(bid).extracting(Bid::getDealid).isEqualTo("dealId"); + assertThat(bid).extracting(Bid::getCrid).isEqualTo("creativeId"); + assertThat(bid).extracting(Bid::getPrice).isEqualTo(BigDecimal.valueOf(1000)); + assertThat(bid).extracting(Bid::getMtype).isEqualTo(4); + assertThat(bid).extracting(Bid::getAdomain).asList() + .containsExactlyInAnyOrder("domain1.com", "domain2.dt"); + assertThat(bid).extracting(Bid::getExt).isNull(); + }); + assertThat(bidderBid).extracting(BidderBid::getType).isEqualTo(BidType.xNative); + assertThat(bidderBid).extracting(BidderBid::getBidCurrency).isEqualTo("USD"); + }); + + assertThat(result.getValue().getLast()).satisfies(bidderBid -> { + assertThat(bidderBid).extracting(BidderBid::getBid).satisfies(bid -> { + assertThat(bid).extracting(Bid::getId).isEqualTo("adId"); + assertThat(bid).extracting(Bid::getImpid).isEqualTo("impId"); + assertThat(bid).extracting(Bid::getW).isEqualTo(21); + assertThat(bid).extracting(Bid::getH).isEqualTo(9); + assertThat(bid).extracting(Bid::getAdid).isEqualTo("adId"); + assertThat(bid).extracting(Bid::getAdm).isEqualTo("dealHtml"); + assertThat(bid).extracting(Bid::getCid).isEqualTo("lineItemId"); + assertThat(bid).extracting(Bid::getDealid).isEqualTo("dealId"); + assertThat(bid).extracting(Bid::getCrid).isEqualTo("creativeId"); assertThat(bid).extracting(Bid::getPrice).isEqualTo(BigDecimal.valueOf(1000)); + assertThat(bid).extracting(Bid::getMtype).isEqualTo(1); assertThat(bid).extracting(Bid::getAdomain).asList() .containsExactlyInAnyOrder("domain1.com", "domain2.dt"); assertThat(bid).extracting(Bid::getExt).isNull(); @@ -796,7 +1302,7 @@ public void makeBidsShouldReturnTwoBidWithDsaFromDealsAndAdsWhenAdsAndDealsIsSpe throws JsonProcessingException { // given - final BidderCall httpCall = givenHttpCall(givenAdsUnitWithDealsAndAds( + final BidderCall httpCall = givenHttpCall(givenBannerAdsUnitWithDealsAndAds( "auId", List.of(givenAd(ad -> ad .bid(AdnuntiusBid.of(BigDecimal.ONE, "USD")) @@ -823,7 +1329,7 @@ public void makeBidsShouldReturnTwoBidWithDsaFromDealsAndAdsWhenAdsAndDealsIsSpe final ExtRegsDsa dsa = ExtRegsDsa.of(1, 0, 2, null); final BidRequest bidRequest = givenBidRequest( request -> request.regs(Regs.builder().ext(ExtRegs.of(null, null, null, dsa)).build()), - givenImp(ExtImpAdnuntius.builder().auId("auId").build(), identity())); + givenBannerImp(ExtImpAdnuntius.builder().auId("auId").build(), identity())); // when final Result> result = target.makeBids(httpCall, bidRequest); @@ -849,12 +1355,12 @@ public void makeBidsShouldReturnTwoBidWithDsaFromDealsAndAdsWhenAdsAndDealsIsSpe public void makeBidsShouldReturnErrorIfCreativeHeightOfSomeAdIsAbsent() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( - givenAdsUnitWithAds("au1", givenAd(ad -> ad.bid(AdnuntiusBid.of(null, "CUR")))), + givenAdsUnitWithAds("au1", givenAd(ad -> ad.bid(AdnuntiusBid.of(BigDecimal.TWO, "CUR")))), givenAdsUnitWithAds("au2", givenAd(ad -> ad.creativeHeight(null)))); final BidRequest bidRequest = givenBidRequest( - givenImp(ExtImpAdnuntius.builder().auId("au1").build(), identity()), - givenImp(ExtImpAdnuntius.builder().auId("au2").build(), identity())); + givenBannerImp(ExtImpAdnuntius.builder().auId("au1").build(), identity()), + givenBannerImp(ExtImpAdnuntius.builder().auId("au2").build(), identity())); // when final Result> result = target.makeBids(httpCall, bidRequest); @@ -869,12 +1375,12 @@ public void makeBidsShouldReturnErrorIfCreativeHeightOfSomeAdIsAbsent() throws J public void makeBidsShouldReturnErrorIfCreativeWidthtOfSomeAdIsAbsent() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( - givenAdsUnitWithAds("au1", givenAd(ad -> ad.bid(AdnuntiusBid.of(null, "CUR")))), + givenAdsUnitWithAds("au1", givenAd(ad -> ad.bid(AdnuntiusBid.of(BigDecimal.TWO, "CUR")))), givenAdsUnitWithAds("au2", givenAd(ad -> ad.creativeWidth(null)))); final BidRequest bidRequest = givenBidRequest( - givenImp(ExtImpAdnuntius.builder().auId("au1").build(), identity()), - givenImp(ExtImpAdnuntius.builder().auId("au2").build(), identity())); + givenBannerImp(ExtImpAdnuntius.builder().auId("au1").build(), identity()), + givenBannerImp(ExtImpAdnuntius.builder().auId("au2").build(), identity())); // when final Result> result = target.makeBids(httpCall, bidRequest); @@ -899,7 +1405,7 @@ public void makeBidsShouldReturnCorrectSeatBids() throws JsonProcessingException .advertiserDomains(List.of("domain1.com", "domain2.dt"))))); final BidRequest bidRequest = givenBidRequest( - givenImp(ExtImpAdnuntius.builder().auId("auId").build(), identity())); + givenBannerImp(ExtImpAdnuntius.builder().auId("auId").build(), identity())); // when final Result> result = target.makeBids(httpCall, bidRequest); @@ -934,14 +1440,31 @@ private BidRequest givenBidRequest(Imp... imps) { return givenBidRequest(identity(), imps); } - private Imp givenImp(ExtImpAdnuntius extImpAdnuntius, UnaryOperator impCustomizer) { + private Imp givenBannerAndNativeImp(ExtImpAdnuntius extImpAdnuntius, UnaryOperator impCustomizer) { + final Banner banner = Banner.builder().build(); + final Native xNative = Native.builder().request("{}").build(); + final ObjectNode ext = mapper.valueToTree(ExtPrebid.of(null, extImpAdnuntius)); + return impCustomizer.apply(Imp.builder().id("impId").banner(banner).xNative(xNative).ext(ext)).build(); + } + + private Imp givenBannerImp(ExtImpAdnuntius extImpAdnuntius, UnaryOperator impCustomizer) { final Banner banner = Banner.builder().build(); final ObjectNode ext = mapper.valueToTree(ExtPrebid.of(null, extImpAdnuntius)); return impCustomizer.apply(Imp.builder().id("impId").banner(banner).ext(ext)).build(); } - private Imp givenImp(UnaryOperator impCustomizer) { - return givenImp(ExtImpAdnuntius.builder().build(), impCustomizer); + private Imp givenBannerImp(UnaryOperator impCustomizer) { + return givenBannerImp(ExtImpAdnuntius.builder().build(), impCustomizer); + } + + private Imp givenNativeImp(ExtImpAdnuntius extImpAdnuntius, UnaryOperator impCustomizer) { + final Native xNative = Native.builder().request("{}").build(); + final ObjectNode ext = mapper.valueToTree(ExtPrebid.of(null, extImpAdnuntius)); + return impCustomizer.apply(Imp.builder().id("impId").xNative(xNative).ext(ext)).build(); + } + + private Imp givenNativeImp(UnaryOperator impCustomizer) { + return givenNativeImp(ExtImpAdnuntius.builder().build(), impCustomizer); } private BidderCall givenHttpCall(String body) { @@ -950,35 +1473,55 @@ private BidderCall givenHttpCall(String body) { return BidderCall.succeededHttp(request, response, null); } - private BidderCall givenHttpCall(AdnuntiusAdsUnit... adsUnits) + private BidderCall givenHttpCall(AdnuntiusAdUnit... adsUnits) throws JsonProcessingException { return givenHttpCall(mapper.writeValueAsString(AdnuntiusResponse.of(List.of(adsUnits)))); } - private AdnuntiusAdsUnit givenAdsUnitWithAds(String auId, AdnuntiusAd... ads) { - return givenAdsUnit(auId, List.of(ads), null); + private AdnuntiusAdUnit givenAdsUnitWithAds(String auId, AdnuntiusAd... ads) { + return givenAdsUnit(auId, List.of(ads), null, null); } - private AdnuntiusAdsUnit givenAdsUnitWithDeals(String auId, AdnuntiusAd... deals) { - return givenAdsUnit(auId, null, List.of(deals)); + private AdnuntiusAdUnit givenAdsUnitWithDeals(String auId, AdnuntiusAd... deals) { + return givenAdsUnit(auId, null, List.of(deals), null); } - private AdnuntiusAdsUnit givenAdsUnitWithDealsAndAds(String auId, List ads, List deals) { - return givenAdsUnit(auId, ads, deals); + private AdnuntiusAdUnit givenBannerAdsUnitWithDealsAndAds(String auId, + List ads, + List deals) { + return givenAdsUnit(auId, ads, deals, null); } - private AdnuntiusAdsUnit givenAdsUnit(String auId, List ads, List deals) { - return AdnuntiusAdsUnit.builder() + private AdnuntiusAdUnit givenNativeAdsUnitWithDealsAndAds(String auId, + List ads, + List deals, + String nativeJson) { + return givenAdsUnit(auId, ads, deals, nativeJson); + } + + private AdnuntiusAdUnit givenAdsUnit(String auId, + List ads, + List deals, + String nativeJson) { + + return AdnuntiusAdUnit.builder() .auId(auId) .targetId(auId + "-impId") .html("html") .ads(ads) .deals(deals) + .matchedAdCount(1) + .nativeJson(nativeJson != null + ? jacksonMapper.decodeValue(nativeJson, AdnuntiusNativeRequest.class) + : null) .build(); } private AdnuntiusAd givenAd(UnaryOperator customizer) { - return customizer.apply(AdnuntiusAd.builder().creativeWidth("21").creativeHeight("9")).build(); + return customizer.apply(AdnuntiusAd.builder() + .bid(AdnuntiusBid.of(BigDecimal.ONE, "USD")) + .creativeWidth("21") + .creativeHeight("9")).build(); } private static ExtDevice givenExtDeviceNoCookies(Boolean noCookies) { @@ -989,16 +1532,20 @@ private static ExtDevice givenExtDeviceNoCookies(Boolean noCookies) { return extDevice; } - private static String givenExpectedUrl(Integer gdpr, String consent) { - return buildExpectedUrl(gdpr, consent, false); + private static String givenExpectedUrl(String url, Integer gdpr, String consent) { + return buildExpectedUrl(url, gdpr, consent, false); + } + + private static String givenExpectedUrl(String url, Integer gdpr, Boolean noCookies) { + return buildExpectedUrl(url, gdpr, null, noCookies); } - private static String givenExpectedUrl(Boolean noCookies) { - return buildExpectedUrl(null, null, noCookies); + private static String givenExpectedUrl(String url, Boolean noCookies) { + return buildExpectedUrl(url, null, null, noCookies); } - private static String buildExpectedUrl(Integer gdpr, String consent, Boolean noCookies) { - final StringBuilder expectedUri = new StringBuilder("https://test.domain.dm/uri?format=prebidServer&tzo=-300"); + private static String buildExpectedUrl(String url, Integer gdpr, String consent, Boolean noCookies) { + final StringBuilder expectedUri = new StringBuilder(url + "?format=prebidServer&tzo=-300"); if (gdpr != null) { expectedUri.append("&gdpr=").append(HttpUtil.encodeUrl(gdpr.toString())); } diff --git a/src/test/resources/org/prebid/server/it/openrtb2/adnuntius/test-adnuntius-bid-request.json b/src/test/resources/org/prebid/server/it/openrtb2/adnuntius/test-adnuntius-bid-request.json index c0707bf2a61..7d075275a7b 100644 --- a/src/test/resources/org/prebid/server/it/openrtb2/adnuntius/test-adnuntius-bid-request.json +++ b/src/test/resources/org/prebid/server/it/openrtb2/adnuntius/test-adnuntius-bid-request.json @@ -2,7 +2,7 @@ "adUnits": [ { "auId": "some_au_id", - "targetId": "some_au_id-imp_id", + "targetId": "some_au_id-imp_id:banner", "dimensions": [ [ 300, diff --git a/src/test/resources/org/prebid/server/it/openrtb2/adnuntius/test-adnuntius-bid-response.json b/src/test/resources/org/prebid/server/it/openrtb2/adnuntius/test-adnuntius-bid-response.json index 4020376e20f..3f74ebaa9f0 100644 --- a/src/test/resources/org/prebid/server/it/openrtb2/adnuntius/test-adnuntius-bid-response.json +++ b/src/test/resources/org/prebid/server/it/openrtb2/adnuntius/test-adnuntius-bid-response.json @@ -2,7 +2,8 @@ "adUnits": [ { "auId": "some_au_id", - "targetId": "some_au_id-imp_id", + "targetId": "some_au_id-imp_id:banner", + "matchedAdCount": 1, "html": "some_html", "ads": [ { diff --git a/src/test/resources/org/prebid/server/it/openrtb2/adnuntius/test-auction-adnuntius-response.json b/src/test/resources/org/prebid/server/it/openrtb2/adnuntius/test-auction-adnuntius-response.json index 6d033a9c208..648eef6866a 100644 --- a/src/test/resources/org/prebid/server/it/openrtb2/adnuntius/test-auction-adnuntius-response.json +++ b/src/test/resources/org/prebid/server/it/openrtb2/adnuntius/test-auction-adnuntius-response.json @@ -17,6 +17,7 @@ "crid": "some_creative_id", "dealid": "some_deal_id", "w": 140, + "mtype": 1, "h": 90, "ext": { "prebid": { From 4d1124cf75a69fec707c6af38ee815d62db0f6d8 Mon Sep 17 00:00:00 2001 From: antonbabak Date: Thu, 29 May 2025 15:13:49 +0200 Subject: [PATCH 2/3] Fix comments --- .../bidder/adnuntius/AdnuntiusBidder.java | 108 ++++++++-------- .../bidder/AdnuntiusBidderConfiguration.java | 12 +- .../resources/bidder-config/adnuntius.yaml | 1 + .../bidder/adnuntius/AdnuntiusBidderTest.java | 119 ++++-------------- .../org/prebid/server/it/AdnuntiusTest.java | 2 +- .../server/it/test-application.properties | 1 + 6 files changed, 81 insertions(+), 162 deletions(-) diff --git a/src/main/java/org/prebid/server/bidder/adnuntius/AdnuntiusBidder.java b/src/main/java/org/prebid/server/bidder/adnuntius/AdnuntiusBidder.java index e499c18b61f..95e5986b58d 100644 --- a/src/main/java/org/prebid/server/bidder/adnuntius/AdnuntiusBidder.java +++ b/src/main/java/org/prebid/server/bidder/adnuntius/AdnuntiusBidder.java @@ -69,8 +69,6 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; -import java.util.function.Function; -import java.util.stream.Collectors; public class AdnuntiusBidder implements Bidder { @@ -85,28 +83,27 @@ public class AdnuntiusBidder implements Bidder { private static final int NATIVE_MTYPE = 4; private final String endpointUrl; - private final String alternativeEndpointUrl; + private final String euEndpoint; private final Clock clock; private final JacksonMapper mapper; public AdnuntiusBidder(String endpointUrl, - String alternativeEndpointUrl, + String euEndpoint, Clock clock, JacksonMapper mapper) { this.endpointUrl = HttpUtil.validateUrl(Objects.requireNonNull(endpointUrl)); - this.alternativeEndpointUrl = alternativeEndpointUrl; + this.euEndpoint = HttpUtil.validateUrl(Objects.requireNonNull(euEndpoint)); this.clock = Objects.requireNonNull(clock); this.mapper = Objects.requireNonNull(mapper); } @Override public Result>> makeHttpRequests(BidRequest request) { - final Map> networkToAdUnits = new HashMap<>(); - boolean noCookies = false; - - for (Imp imp : request.getImp()) { - try { + try { + final Map> networkToAdUnits = new HashMap<>(); + boolean noCookies = false; + for (Imp imp : request.getImp()) { validateImp(imp); final ExtImpAdnuntius extImpAdnuntius = parseImpExt(imp); noCookies = noCookies || resolveIsNoCookies(extImpAdnuntius); @@ -123,13 +120,8 @@ public Result>> makeHttpRequests(BidRequest r if (imp.getXNative() != null) { adUnits.add(makeNativeAdUnit(imp, extImpAdnuntius)); } - - } catch (PreBidException e) { - return Result.withError(BidderError.badInput(e.getMessage())); } - } - try { return Result.withValues(createHttpRequests(networkToAdUnits, request, noCookies)); } catch (PreBidException e) { return Result.withError(BidderError.badInput(e.getMessage())); @@ -179,10 +171,6 @@ private static String targetId(String auId, String impId, String bidType) { return "%s-%s:%s".formatted(auId, impId, bidType); } - private static String targetId(String auId, String impId) { - return "%s-%s".formatted(auId, impId); - } - private static List> createDimensions(Banner banner) { final List> formats = new ArrayList<>(); @@ -259,34 +247,8 @@ private List> createHttpRequests( return adnuntiusRequests; } - private String makeEndpoint(BidRequest bidRequest, Boolean noCookies) { - try { - final String gdpr = extractGdpr(bidRequest.getRegs()); - final String url = StringUtils.isNotEmpty(gdpr) && alternativeEndpointUrl != null - ? HttpUtil.validateUrl(alternativeEndpointUrl) - : endpointUrl; - - final URIBuilder uriBuilder = new URIBuilder(url) - .addParameter("format", "prebidServer") - .addParameter("tzo", getTimeZoneOffset()); - - if (StringUtils.isNotEmpty(gdpr)) { - uriBuilder.addParameter("gdpr", gdpr); - } - - final String consent = extractConsent(bidRequest.getUser()); - if (StringUtils.isNotEmpty(consent)) { - uriBuilder.addParameter("consentString", consent); - } - - if (noCookies || extractNoCookies(bidRequest.getDevice())) { - uriBuilder.addParameter("noCookies", "true"); - } - - return uriBuilder.build().toString(); - } catch (URISyntaxException | IllegalArgumentException e) { - throw new PreBidException(e.getMessage()); - } + private static String targetIdForBids(String auId, String impId) { + return "%s-%s".formatted(auId, impId); } private String getTimeZoneOffset() { @@ -387,24 +349,62 @@ public Result> makeBids(BidderCall httpCall, B } } + private static Map parseAdUnits(AdnuntiusResponse adnuntiusResponse) { + final Map targetIdToAdsUnit = new HashMap<>(); + for (AdnuntiusAdUnit adUnit : adnuntiusResponse.getAdUnits()) { + if (isValid(adUnit)) { + final String targetId = extractTargetId(adUnit.getTargetId()); + final AdnuntiusAdUnit existingAdUnit = targetIdToAdsUnit.get(targetId); + if (existingAdUnit == null || getBidAmount(adUnit).compareTo(getBidAmount(existingAdUnit)) >= 0) { + targetIdToAdsUnit.put(targetId, adUnit); + } + } + } + + return targetIdToAdsUnit; + } + + private String makeEndpoint(BidRequest bidRequest, Boolean noCookies) { + try { + final String gdpr = extractGdpr(bidRequest.getRegs()); + final String url = StringUtils.isEmpty(gdpr) ? endpointUrl : euEndpoint; + + final URIBuilder uriBuilder = new URIBuilder(url) + .addParameter("format", "prebidServer") + .addParameter("tzo", getTimeZoneOffset()); + + if (StringUtils.isNotEmpty(gdpr)) { + uriBuilder.addParameter("gdpr", gdpr); + } + + final String consent = extractConsent(bidRequest.getUser()); + if (StringUtils.isNotEmpty(consent)) { + uriBuilder.addParameter("consentString", consent); + } + + if (noCookies || extractNoCookies(bidRequest.getDevice())) { + uriBuilder.addParameter("noCookies", "true"); + } + + return uriBuilder.build().toString(); + } catch (URISyntaxException | IllegalArgumentException e) { + throw new PreBidException(e.getMessage()); + } + } + private List extractBids(BidRequest bidRequest, AdnuntiusResponse adnuntiusResponse) { if (adnuntiusResponse == null || CollectionUtils.isEmpty(adnuntiusResponse.getAdUnits())) { return Collections.emptyList(); } - final Map targetIdToAdsUnit = adnuntiusResponse.getAdUnits().stream() - .filter(AdnuntiusBidder::isValid) - .collect(Collectors.toMap( - adUnit -> extractTargetId(adUnit.getTargetId()), - Function.identity(), - (first, second) -> getBidAmount(first).compareTo(getBidAmount(second)) >= 0 ? first : second)); + final Map targetIdToAdsUnit = parseAdUnits(adnuntiusResponse); String currency = null; final List bids = new ArrayList<>(); for (Imp imp : bidRequest.getImp()) { final ExtImpAdnuntius extImpAdnuntius = parseImpExt(imp); - final String targetId = targetId(extImpAdnuntius.getAuId(), imp.getId()); + final String targetId = targetIdForBids(extImpAdnuntius.getAuId(), imp.getId()); final AdnuntiusAdUnit adUnit = targetIdToAdsUnit.get(targetId); if (adUnit == null) { diff --git a/src/main/java/org/prebid/server/spring/config/bidder/AdnuntiusBidderConfiguration.java b/src/main/java/org/prebid/server/spring/config/bidder/AdnuntiusBidderConfiguration.java index edfe18165c2..3aca2e59cf8 100644 --- a/src/main/java/org/prebid/server/spring/config/bidder/AdnuntiusBidderConfiguration.java +++ b/src/main/java/org/prebid/server/spring/config/bidder/AdnuntiusBidderConfiguration.java @@ -10,7 +10,6 @@ import org.prebid.server.spring.config.bidder.util.BidderDepsAssembler; import org.prebid.server.spring.config.bidder.util.UsersyncerCreator; import org.prebid.server.spring.env.YamlPropertySourceFactory; -import org.prebid.server.util.ObjectUtil; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; @@ -43,7 +42,7 @@ BidderDeps adnuntiusBidderDeps(AdnuntiusConfigurationProperties adnuntiusConfigu .usersyncerCreator(UsersyncerCreator.create(externalUrl)) .bidderCreator(config -> new AdnuntiusBidder( config.getEndpoint(), - ObjectUtil.getIfNotNull(config.getExtraInfo(), ExtraInfo::getUrl), + config.getEuEndpoint(), clock, mapper)) .assemble(); @@ -54,13 +53,6 @@ BidderDeps adnuntiusBidderDeps(AdnuntiusConfigurationProperties adnuntiusConfigu @NoArgsConstructor private static class AdnuntiusConfigurationProperties extends BidderConfigurationProperties { - private ExtraInfo extraInfo = new ExtraInfo(); - } - - @Data - @NoArgsConstructor - private static class ExtraInfo { - - String url; + private String euEndpoint; } } diff --git a/src/main/resources/bidder-config/adnuntius.yaml b/src/main/resources/bidder-config/adnuntius.yaml index 5fd1d63edaa..b8a3006ae24 100644 --- a/src/main/resources/bidder-config/adnuntius.yaml +++ b/src/main/resources/bidder-config/adnuntius.yaml @@ -1,6 +1,7 @@ adapters: adnuntius: endpoint: https://ads.adnuntius.delivery/i + eu-endpoint: https://europe.delivery.adnuntius.com/i meta-info: maintainer-email: hello@adnuntius.com app-media-types: diff --git a/src/test/java/org/prebid/server/bidder/adnuntius/AdnuntiusBidderTest.java b/src/test/java/org/prebid/server/bidder/adnuntius/AdnuntiusBidderTest.java index 084de7478c4..2508ec90995 100644 --- a/src/test/java/org/prebid/server/bidder/adnuntius/AdnuntiusBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/adnuntius/AdnuntiusBidderTest.java @@ -65,7 +65,7 @@ public class AdnuntiusBidderTest extends VertxTest { private static final String ENDPOINT_URL = "https://test.domain.dm/uri"; - private static final String ALTERNATIVE_URL = "https://alternative.domain.dm/uri"; + private static final String EU_ENDPOINT_URL = "https://alternative.domain.dm/uri"; private AdnuntiusBidder target; @@ -74,7 +74,7 @@ public void setUp() { final Clock clock = Clock.system(ZoneId.of("UTC+05:00")); target = new AdnuntiusBidder( ENDPOINT_URL, - null, + EU_ENDPOINT_URL, clock, jacksonMapper); } @@ -88,6 +88,15 @@ public void creationShouldFailOnInvalidEndpointUrl() { jacksonMapper)); } + @Test + public void creationShouldFailOnInvalidEuEndpointUrl() { + assertThatIllegalArgumentException().isThrownBy(() -> new AdnuntiusBidder( + ENDPOINT_URL, + "invalid_url", + Clock.systemDefaultZone(), + jacksonMapper)); + } + @Test public void makeHttpRequestsShouldReturnErrorWhenSomeImpBannerAndNativeIsAbsent() { // given @@ -575,7 +584,7 @@ public void makeHttpRequestsShouldReturnRequestsWithCorrectUri() { final Result>> result = target.makeHttpRequests(bidRequest); // then - final String expectedUrl = givenExpectedUrl(ENDPOINT_URL, gdpr, consent); + final String expectedUrl = givenExpectedUrl(EU_ENDPOINT_URL, gdpr, consent); assertThat(result.getValue()) .extracting(HttpRequest::getUri) @@ -707,14 +716,8 @@ public void makeHttpRequestsShouldReturnRequestsWithCorrectUriIfExtDeviceImpNoCo } @Test - public void makeHttpRequestsShouldReturnRequestsWithBasicUriIfGdprAndConsentAreAbsentWhenAlternativeUriProvided() { + public void makeHttpRequestsShouldReturnRequestsWithBasicUriIfGdprAndConsentAreAbsent() { // given - target = new AdnuntiusBidder( - ENDPOINT_URL, - ALTERNATIVE_URL, - Clock.system(ZoneId.of("UTC+05:00")), - jacksonMapper); - final BidRequest bidRequest = givenBidRequest( request -> request .regs(Regs.builder().ext(ExtRegs.of(null, null, null, null)).build()) @@ -735,14 +738,8 @@ public void makeHttpRequestsShouldReturnRequestsWithBasicUriIfGdprAndConsentAreA } @Test - public void makeHttpRequestsShouldReturnRequestsWithBasicUriIfGdprIsAbsentWhenAlternativeUriProvided() { + public void makeHttpRequestsShouldReturnRequestsWithBasicUriIfGdprIsAbsent() { // given - target = new AdnuntiusBidder( - ENDPOINT_URL, - ALTERNATIVE_URL, - Clock.system(ZoneId.of("UTC+05:00")), - jacksonMapper); - final BidRequest bidRequest = givenBidRequest( request -> request .regs(Regs.builder().ext(ExtRegs.of(null, null, null, null)).build()) @@ -765,12 +762,6 @@ public void makeHttpRequestsShouldReturnRequestsWithBasicUriIfGdprIsAbsentWhenAl @Test public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfConsentIsAbsentAndGdprIsPresent() { // given - target = new AdnuntiusBidder( - ENDPOINT_URL, - ALTERNATIVE_URL, - Clock.system(ZoneId.of("UTC+05:00")), - jacksonMapper); - final BidRequest bidRequest = givenBidRequest( request -> request .regs(Regs.builder().ext(ExtRegs.of(1, null, null, null)).build()) @@ -782,7 +773,7 @@ public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfConsentIsAbs final Result>> result = target.makeHttpRequests(bidRequest); // then - final String expectedUrl = buildExpectedUrl(ALTERNATIVE_URL, 1, null, null); + final String expectedUrl = buildExpectedUrl(EU_ENDPOINT_URL, 1, null, null); assertThat(result.getValue()) .extracting(HttpRequest::getUri) @@ -790,39 +781,9 @@ public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfConsentIsAbs assertThat(result.getErrors()).isEmpty(); } - @Test - public void makeHttpRequestsShouldFailWhenGdprIsPresentAndAlternativeUriIsInvalid() { - // given - target = new AdnuntiusBidder( - ENDPOINT_URL, - "invalid_url", - Clock.system(ZoneId.of("UTC+05:00")), - jacksonMapper); - - final BidRequest bidRequest = givenBidRequest( - request -> request - .regs(Regs.builder().ext(ExtRegs.of(1, null, null, null)).build()) - .user(User.builder().ext(ExtUser.builder().consent(null).build()).build()), - givenBannerImp(identity()), - givenBannerImp(ExtImpAdnuntius.builder().network("network").build(), identity())); - - // when - final Result>> result = target.makeHttpRequests(bidRequest); - - // then - assertThat(result.getErrors()).containsExactly(BidderError.badInput("URL supplied is not valid: invalid_url")); - assertThat(result.getValue()).isEmpty(); - } - @Test public void makeHttpRequestsShouldReturnRequestsWithAlternativeUri() { // given - target = new AdnuntiusBidder( - ENDPOINT_URL, - ALTERNATIVE_URL, - Clock.system(ZoneId.of("UTC+05:00")), - jacksonMapper); - final Integer gdpr = 1; final String consent = "con sent"; final BidRequest bidRequest = givenBidRequest( @@ -836,7 +797,7 @@ public void makeHttpRequestsShouldReturnRequestsWithAlternativeUri() { final Result>> result = target.makeHttpRequests(bidRequest); // then - final String expectedUrl = givenExpectedUrl(ALTERNATIVE_URL, gdpr, consent); + final String expectedUrl = givenExpectedUrl(EU_ENDPOINT_URL, gdpr, consent); assertThat(result.getValue()) .extracting(HttpRequest::getUri) @@ -847,12 +808,6 @@ public void makeHttpRequestsShouldReturnRequestsWithAlternativeUri() { @Test public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfExtImpNoCookiesIsNull() { // given - target = new AdnuntiusBidder( - ENDPOINT_URL, - ALTERNATIVE_URL, - Clock.system(ZoneId.of("UTC+05:00")), - jacksonMapper); - final BidRequest bidRequest = givenBidRequest( request -> request.regs(Regs.builder().ext(ExtRegs.of(1, null, null, null)).build()), givenBannerImp(ExtImpAdnuntius.builder().network("network").build(), identity()), @@ -862,7 +817,7 @@ public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfExtImpNoCook final Result>> result = target.makeHttpRequests(bidRequest); // then - final String expectedUrl = buildExpectedUrl(ALTERNATIVE_URL, 1, null, null); + final String expectedUrl = buildExpectedUrl(EU_ENDPOINT_URL, 1, null, null); assertThat(result.getValue()) .extracting(HttpRequest::getUri) @@ -873,12 +828,6 @@ public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfExtImpNoCook @Test public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfExtImpNoCookiesIsFalse() { // given - target = new AdnuntiusBidder( - ENDPOINT_URL, - ALTERNATIVE_URL, - Clock.system(ZoneId.of("UTC+05:00")), - jacksonMapper); - final Boolean noCookies = false; final BidRequest bidRequest = givenBidRequest( request -> request.regs(Regs.builder().ext(ExtRegs.of(1, null, null, null)).build()), @@ -889,7 +838,7 @@ public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfExtImpNoCook final Result>> result = target.makeHttpRequests(bidRequest); // then - final String expectedUrl = givenExpectedUrl(ALTERNATIVE_URL, 1, noCookies); + final String expectedUrl = givenExpectedUrl(EU_ENDPOINT_URL, 1, noCookies); assertThat(result.getValue()) .extracting(HttpRequest::getUri) @@ -900,12 +849,6 @@ public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfExtImpNoCook @Test public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfExtImpNoCookiesIsTrue() { // given - target = new AdnuntiusBidder( - ENDPOINT_URL, - ALTERNATIVE_URL, - Clock.system(ZoneId.of("UTC+05:00")), - jacksonMapper); - final Boolean noCookies = true; final BidRequest bidRequest = givenBidRequest( request -> request.regs(Regs.builder().ext(ExtRegs.of(1, null, null, null)).build()), @@ -916,7 +859,7 @@ public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfExtImpNoCook final Result>> result = target.makeHttpRequests(bidRequest); // then - final String expectedUrl = givenExpectedUrl(ALTERNATIVE_URL, 1, noCookies); + final String expectedUrl = givenExpectedUrl(EU_ENDPOINT_URL, 1, noCookies); assertThat(result.getValue()) .extracting(HttpRequest::getUri) @@ -927,12 +870,6 @@ public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfExtImpNoCook @Test public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriAndPopulateExtDeviceWithNoCookies() { // given - target = new AdnuntiusBidder( - ENDPOINT_URL, - ALTERNATIVE_URL, - Clock.system(ZoneId.of("UTC+05:00")), - jacksonMapper); - final BidRequest bidRequest = givenBidRequest( request -> request .regs(Regs.builder().ext(ExtRegs.of(1, null, null, null)).build()) @@ -944,7 +881,7 @@ public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriAndPopulateExt final Result>> result = target.makeHttpRequests(bidRequest); // then - final String expectedUrl = buildExpectedUrl(ALTERNATIVE_URL, 1, null, null); + final String expectedUrl = buildExpectedUrl(EU_ENDPOINT_URL, 1, null, null); assertThat(result.getValue()) .extracting(HttpRequest::getUri) @@ -955,12 +892,6 @@ public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriAndPopulateExt @Test public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfExtDeviceImpNoCookiesIsFalse() { // given - target = new AdnuntiusBidder( - ENDPOINT_URL, - ALTERNATIVE_URL, - Clock.system(ZoneId.of("UTC+05:00")), - jacksonMapper); - final Boolean noCookies = false; final BidRequest bidRequest = givenBidRequest( request -> request @@ -973,7 +904,7 @@ public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfExtDeviceImp final Result>> result = target.makeHttpRequests(bidRequest); // then - final String expectedUrl = givenExpectedUrl(ALTERNATIVE_URL, 1, noCookies); + final String expectedUrl = givenExpectedUrl(EU_ENDPOINT_URL, 1, noCookies); assertThat(result.getValue()) .extracting(HttpRequest::getUri) @@ -984,12 +915,6 @@ public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfExtDeviceImp @Test public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfExtDeviceImpNoCookiesIsTrue() { // given - target = new AdnuntiusBidder( - ENDPOINT_URL, - ALTERNATIVE_URL, - Clock.system(ZoneId.of("UTC+05:00")), - jacksonMapper); - final Boolean noCookies = true; final BidRequest bidRequest = givenBidRequest( request -> request @@ -1002,7 +927,7 @@ public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfExtDeviceImp final Result>> result = target.makeHttpRequests(bidRequest); // then - final String expectedUrl = givenExpectedUrl(ALTERNATIVE_URL, 1, noCookies); + final String expectedUrl = givenExpectedUrl(EU_ENDPOINT_URL, 1, noCookies); assertThat(result.getValue()) .extracting(HttpRequest::getUri) diff --git a/src/test/java/org/prebid/server/it/AdnuntiusTest.java b/src/test/java/org/prebid/server/it/AdnuntiusTest.java index 9a03d73ccf5..b2847d98dda 100644 --- a/src/test/java/org/prebid/server/it/AdnuntiusTest.java +++ b/src/test/java/org/prebid/server/it/AdnuntiusTest.java @@ -18,7 +18,7 @@ public class AdnuntiusTest extends IntegrationTest { @Test public void openrtb2AuctionShouldRespondWithBidsFromAdnuntius() throws IOException, JSONException { // given - WIRE_MOCK_RULE.stubFor(post(urlPathEqualTo("/adnuntius-exchange")) + WIRE_MOCK_RULE.stubFor(post(urlPathEqualTo("/adnuntius-exchange-eu")) .withRequestBody(equalToJson(jsonFrom("openrtb2/adnuntius/test-adnuntius-bid-request.json"))) .willReturn(aResponse().withBody(jsonFrom("openrtb2/adnuntius/test-adnuntius-bid-response.json")))); diff --git a/src/test/resources/org/prebid/server/it/test-application.properties b/src/test/resources/org/prebid/server/it/test-application.properties index 450ae419cb5..3e01ceb08a9 100644 --- a/src/test/resources/org/prebid/server/it/test-application.properties +++ b/src/test/resources/org/prebid/server/it/test-application.properties @@ -51,6 +51,7 @@ adapters.admixer.enabled=true adapters.admixer.endpoint=http://localhost:8090/admixer-exchange adapters.adnuntius.enabled=true adapters.adnuntius.endpoint=http://localhost:8090/adnuntius-exchange +adapters.adnuntius.eu-endpoint=http://localhost:8090/adnuntius-exchange-eu adapters.adocean.enabled=true adapters.adocean.endpoint=http://localhost:8090/adocean-exchange adapters.adoppler.enabled=true From eab8a7d2fe16ba66007fc212a172e264eea3c72a Mon Sep 17 00:00:00 2001 From: antonbabak Date: Wed, 4 Jun 2025 15:16:44 +0200 Subject: [PATCH 3/3] Fix comments --- .../bidder/adnuntius/AdnuntiusBidder.java | 66 +++++---- .../bidder/adnuntius/AdnuntiusBidderTest.java | 132 +++++++++++++----- 2 files changed, 131 insertions(+), 67 deletions(-) diff --git a/src/main/java/org/prebid/server/bidder/adnuntius/AdnuntiusBidder.java b/src/main/java/org/prebid/server/bidder/adnuntius/AdnuntiusBidder.java index 95e5986b58d..1603cdc855b 100644 --- a/src/main/java/org/prebid/server/bidder/adnuntius/AdnuntiusBidder.java +++ b/src/main/java/org/prebid/server/bidder/adnuntius/AdnuntiusBidder.java @@ -93,7 +93,7 @@ public AdnuntiusBidder(String endpointUrl, JacksonMapper mapper) { this.endpointUrl = HttpUtil.validateUrl(Objects.requireNonNull(endpointUrl)); - this.euEndpoint = HttpUtil.validateUrl(Objects.requireNonNull(euEndpoint)); + this.euEndpoint = euEndpoint == null ? null : HttpUtil.validateUrl(euEndpoint); this.clock = Objects.requireNonNull(clock); this.mapper = Objects.requireNonNull(mapper); } @@ -247,8 +247,36 @@ private List> createHttpRequests( return adnuntiusRequests; } - private static String targetIdForBids(String auId, String impId) { - return "%s-%s".formatted(auId, impId); + private String makeEndpoint(BidRequest bidRequest, Boolean noCookies) { + try { + final String gdpr = extractGdpr(bidRequest.getRegs()); + final String url = StringUtils.isNotBlank(gdpr) ? euEndpoint : endpointUrl; + + if (url == null) { + throw new PreBidException("an EU endpoint is required but invalid"); + } + + final URIBuilder uriBuilder = new URIBuilder(url) + .addParameter("format", "prebidServer") + .addParameter("tzo", getTimeZoneOffset()); + + if (StringUtils.isNotEmpty(gdpr)) { + uriBuilder.addParameter("gdpr", gdpr); + } + + final String consent = extractConsent(bidRequest.getUser()); + if (StringUtils.isNotEmpty(consent)) { + uriBuilder.addParameter("consentString", consent); + } + + if (noCookies || extractNoCookies(bidRequest.getDevice())) { + uriBuilder.addParameter("noCookies", "true"); + } + + return uriBuilder.build().toString(); + } catch (URISyntaxException | IllegalArgumentException e) { + throw new PreBidException(e.getMessage()); + } } private String getTimeZoneOffset() { @@ -364,34 +392,6 @@ private static Map parseAdUnits(AdnuntiusResponse adnun return targetIdToAdsUnit; } - private String makeEndpoint(BidRequest bidRequest, Boolean noCookies) { - try { - final String gdpr = extractGdpr(bidRequest.getRegs()); - final String url = StringUtils.isEmpty(gdpr) ? endpointUrl : euEndpoint; - - final URIBuilder uriBuilder = new URIBuilder(url) - .addParameter("format", "prebidServer") - .addParameter("tzo", getTimeZoneOffset()); - - if (StringUtils.isNotEmpty(gdpr)) { - uriBuilder.addParameter("gdpr", gdpr); - } - - final String consent = extractConsent(bidRequest.getUser()); - if (StringUtils.isNotEmpty(consent)) { - uriBuilder.addParameter("consentString", consent); - } - - if (noCookies || extractNoCookies(bidRequest.getDevice())) { - uriBuilder.addParameter("noCookies", "true"); - } - - return uriBuilder.build().toString(); - } catch (URISyntaxException | IllegalArgumentException e) { - throw new PreBidException(e.getMessage()); - } - } - private List extractBids(BidRequest bidRequest, AdnuntiusResponse adnuntiusResponse) { if (adnuntiusResponse == null || CollectionUtils.isEmpty(adnuntiusResponse.getAdUnits())) { return Collections.emptyList(); @@ -463,6 +463,10 @@ private static String extractTargetId(String targetId) { return targetId == null ? null : targetId.split(":")[0]; } + private static String targetIdForBids(String auId, String impId) { + return "%s-%s".formatted(auId, impId); + } + private Bid createBid(AdnuntiusAd ad, BidRequest bidRequest, String adm, String impId, String bidType, int mtype) { final String adId = ad.getAdId(); final AdnuntiusBidExt bidExt = prepareBidExt(ad, bidRequest); diff --git a/src/test/java/org/prebid/server/bidder/adnuntius/AdnuntiusBidderTest.java b/src/test/java/org/prebid/server/bidder/adnuntius/AdnuntiusBidderTest.java index 2508ec90995..910a2b6514c 100644 --- a/src/test/java/org/prebid/server/bidder/adnuntius/AdnuntiusBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/adnuntius/AdnuntiusBidderTest.java @@ -65,7 +65,7 @@ public class AdnuntiusBidderTest extends VertxTest { private static final String ENDPOINT_URL = "https://test.domain.dm/uri"; - private static final String EU_ENDPOINT_URL = "https://alternative.domain.dm/uri"; + private static final String ALTERNATIVE_URL = "https://alternative.domain.dm/uri"; private AdnuntiusBidder target; @@ -74,7 +74,7 @@ public void setUp() { final Clock clock = Clock.system(ZoneId.of("UTC+05:00")); target = new AdnuntiusBidder( ENDPOINT_URL, - EU_ENDPOINT_URL, + null, clock, jacksonMapper); } @@ -568,30 +568,6 @@ public void makeHttpRequestsShouldReturnRequestsWithCorrectUriIfConsentIsAbsent( assertThat(result.getErrors()).isEmpty(); } - @Test - public void makeHttpRequestsShouldReturnRequestsWithCorrectUri() { - // given - final Integer gdpr = 1; - final String consent = "con sent"; - final BidRequest bidRequest = givenBidRequest( - request -> request - .regs(Regs.builder().ext(ExtRegs.of(gdpr, null, null, null)).build()) - .user(User.builder().ext(ExtUser.builder().consent(consent).build()).build()), - givenBannerImp(identity()), - givenBannerImp(ExtImpAdnuntius.builder().network("network").build(), identity())); - - // when - final Result>> result = target.makeHttpRequests(bidRequest); - - // then - final String expectedUrl = givenExpectedUrl(EU_ENDPOINT_URL, gdpr, consent); - - assertThat(result.getValue()) - .extracting(HttpRequest::getUri) - .containsExactly(expectedUrl, expectedUrl); - assertThat(result.getErrors()).isEmpty(); - } - @Test public void makeHttpRequestsShouldReturnRequestsWithCorrectUriIfExtImpNoCookiesIsNull() { // given @@ -716,8 +692,14 @@ public void makeHttpRequestsShouldReturnRequestsWithCorrectUriIfExtDeviceImpNoCo } @Test - public void makeHttpRequestsShouldReturnRequestsWithBasicUriIfGdprAndConsentAreAbsent() { + public void makeHttpRequestsShouldReturnRequestsWithBasicUriIfGdprAndConsentAreAbsentWhenAlternativeUriProvided() { // given + target = new AdnuntiusBidder( + ENDPOINT_URL, + ALTERNATIVE_URL, + Clock.system(ZoneId.of("UTC+05:00")), + jacksonMapper); + final BidRequest bidRequest = givenBidRequest( request -> request .regs(Regs.builder().ext(ExtRegs.of(null, null, null, null)).build()) @@ -738,8 +720,14 @@ public void makeHttpRequestsShouldReturnRequestsWithBasicUriIfGdprAndConsentAreA } @Test - public void makeHttpRequestsShouldReturnRequestsWithBasicUriIfGdprIsAbsent() { + public void makeHttpRequestsShouldReturnRequestsWithBasicUriIfGdprIsAbsentWhenAlternativeUriProvided() { // given + target = new AdnuntiusBidder( + ENDPOINT_URL, + ALTERNATIVE_URL, + Clock.system(ZoneId.of("UTC+05:00")), + jacksonMapper); + final BidRequest bidRequest = givenBidRequest( request -> request .regs(Regs.builder().ext(ExtRegs.of(null, null, null, null)).build()) @@ -762,6 +750,12 @@ public void makeHttpRequestsShouldReturnRequestsWithBasicUriIfGdprIsAbsent() { @Test public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfConsentIsAbsentAndGdprIsPresent() { // given + target = new AdnuntiusBidder( + ENDPOINT_URL, + ALTERNATIVE_URL, + Clock.system(ZoneId.of("UTC+05:00")), + jacksonMapper); + final BidRequest bidRequest = givenBidRequest( request -> request .regs(Regs.builder().ext(ExtRegs.of(1, null, null, null)).build()) @@ -773,7 +767,7 @@ public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfConsentIsAbs final Result>> result = target.makeHttpRequests(bidRequest); // then - final String expectedUrl = buildExpectedUrl(EU_ENDPOINT_URL, 1, null, null); + final String expectedUrl = buildExpectedUrl(ALTERNATIVE_URL, 1, null, null); assertThat(result.getValue()) .extracting(HttpRequest::getUri) @@ -781,9 +775,39 @@ public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfConsentIsAbs assertThat(result.getErrors()).isEmpty(); } + @Test + public void makeHttpRequestsShouldFailWhenGdprIsPresentAndAlternativeUriIsNotProvided() { + // given + target = new AdnuntiusBidder( + ENDPOINT_URL, + null, + Clock.system(ZoneId.of("UTC+05:00")), + jacksonMapper); + + final BidRequest bidRequest = givenBidRequest( + request -> request + .regs(Regs.builder().ext(ExtRegs.of(1, null, null, null)).build()) + .user(User.builder().ext(ExtUser.builder().consent(null).build()).build()), + givenBannerImp(identity()), + givenBannerImp(ExtImpAdnuntius.builder().network("network").build(), identity())); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + assertThat(result.getErrors()).containsExactly(BidderError.badInput("an EU endpoint is required but invalid")); + assertThat(result.getValue()).isEmpty(); + } + @Test public void makeHttpRequestsShouldReturnRequestsWithAlternativeUri() { // given + target = new AdnuntiusBidder( + ENDPOINT_URL, + ALTERNATIVE_URL, + Clock.system(ZoneId.of("UTC+05:00")), + jacksonMapper); + final Integer gdpr = 1; final String consent = "con sent"; final BidRequest bidRequest = givenBidRequest( @@ -797,7 +821,7 @@ public void makeHttpRequestsShouldReturnRequestsWithAlternativeUri() { final Result>> result = target.makeHttpRequests(bidRequest); // then - final String expectedUrl = givenExpectedUrl(EU_ENDPOINT_URL, gdpr, consent); + final String expectedUrl = givenExpectedUrl(ALTERNATIVE_URL, gdpr, consent); assertThat(result.getValue()) .extracting(HttpRequest::getUri) @@ -808,6 +832,12 @@ public void makeHttpRequestsShouldReturnRequestsWithAlternativeUri() { @Test public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfExtImpNoCookiesIsNull() { // given + target = new AdnuntiusBidder( + ENDPOINT_URL, + ALTERNATIVE_URL, + Clock.system(ZoneId.of("UTC+05:00")), + jacksonMapper); + final BidRequest bidRequest = givenBidRequest( request -> request.regs(Regs.builder().ext(ExtRegs.of(1, null, null, null)).build()), givenBannerImp(ExtImpAdnuntius.builder().network("network").build(), identity()), @@ -817,7 +847,7 @@ public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfExtImpNoCook final Result>> result = target.makeHttpRequests(bidRequest); // then - final String expectedUrl = buildExpectedUrl(EU_ENDPOINT_URL, 1, null, null); + final String expectedUrl = buildExpectedUrl(ALTERNATIVE_URL, 1, null, null); assertThat(result.getValue()) .extracting(HttpRequest::getUri) @@ -828,6 +858,12 @@ public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfExtImpNoCook @Test public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfExtImpNoCookiesIsFalse() { // given + target = new AdnuntiusBidder( + ENDPOINT_URL, + ALTERNATIVE_URL, + Clock.system(ZoneId.of("UTC+05:00")), + jacksonMapper); + final Boolean noCookies = false; final BidRequest bidRequest = givenBidRequest( request -> request.regs(Regs.builder().ext(ExtRegs.of(1, null, null, null)).build()), @@ -838,7 +874,7 @@ public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfExtImpNoCook final Result>> result = target.makeHttpRequests(bidRequest); // then - final String expectedUrl = givenExpectedUrl(EU_ENDPOINT_URL, 1, noCookies); + final String expectedUrl = givenExpectedUrl(ALTERNATIVE_URL, 1, noCookies); assertThat(result.getValue()) .extracting(HttpRequest::getUri) @@ -849,6 +885,12 @@ public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfExtImpNoCook @Test public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfExtImpNoCookiesIsTrue() { // given + target = new AdnuntiusBidder( + ENDPOINT_URL, + ALTERNATIVE_URL, + Clock.system(ZoneId.of("UTC+05:00")), + jacksonMapper); + final Boolean noCookies = true; final BidRequest bidRequest = givenBidRequest( request -> request.regs(Regs.builder().ext(ExtRegs.of(1, null, null, null)).build()), @@ -859,7 +901,7 @@ public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfExtImpNoCook final Result>> result = target.makeHttpRequests(bidRequest); // then - final String expectedUrl = givenExpectedUrl(EU_ENDPOINT_URL, 1, noCookies); + final String expectedUrl = givenExpectedUrl(ALTERNATIVE_URL, 1, noCookies); assertThat(result.getValue()) .extracting(HttpRequest::getUri) @@ -870,6 +912,12 @@ public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfExtImpNoCook @Test public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriAndPopulateExtDeviceWithNoCookies() { // given + target = new AdnuntiusBidder( + ENDPOINT_URL, + ALTERNATIVE_URL, + Clock.system(ZoneId.of("UTC+05:00")), + jacksonMapper); + final BidRequest bidRequest = givenBidRequest( request -> request .regs(Regs.builder().ext(ExtRegs.of(1, null, null, null)).build()) @@ -881,7 +929,7 @@ public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriAndPopulateExt final Result>> result = target.makeHttpRequests(bidRequest); // then - final String expectedUrl = buildExpectedUrl(EU_ENDPOINT_URL, 1, null, null); + final String expectedUrl = buildExpectedUrl(ALTERNATIVE_URL, 1, null, null); assertThat(result.getValue()) .extracting(HttpRequest::getUri) @@ -892,6 +940,12 @@ public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriAndPopulateExt @Test public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfExtDeviceImpNoCookiesIsFalse() { // given + target = new AdnuntiusBidder( + ENDPOINT_URL, + ALTERNATIVE_URL, + Clock.system(ZoneId.of("UTC+05:00")), + jacksonMapper); + final Boolean noCookies = false; final BidRequest bidRequest = givenBidRequest( request -> request @@ -904,7 +958,7 @@ public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfExtDeviceImp final Result>> result = target.makeHttpRequests(bidRequest); // then - final String expectedUrl = givenExpectedUrl(EU_ENDPOINT_URL, 1, noCookies); + final String expectedUrl = givenExpectedUrl(ALTERNATIVE_URL, 1, noCookies); assertThat(result.getValue()) .extracting(HttpRequest::getUri) @@ -915,6 +969,12 @@ public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfExtDeviceImp @Test public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfExtDeviceImpNoCookiesIsTrue() { // given + target = new AdnuntiusBidder( + ENDPOINT_URL, + ALTERNATIVE_URL, + Clock.system(ZoneId.of("UTC+05:00")), + jacksonMapper); + final Boolean noCookies = true; final BidRequest bidRequest = givenBidRequest( request -> request @@ -927,7 +987,7 @@ public void makeHttpRequestsShouldReturnRequestsWithAlternativeUriIfExtDeviceImp final Result>> result = target.makeHttpRequests(bidRequest); // then - final String expectedUrl = givenExpectedUrl(EU_ENDPOINT_URL, 1, noCookies); + final String expectedUrl = givenExpectedUrl(ALTERNATIVE_URL, 1, noCookies); assertThat(result.getValue()) .extracting(HttpRequest::getUri)