From 67620467dee7abff8708e18698ca23adb56ad115 Mon Sep 17 00:00:00 2001 From: Dmitrii Ermakov Date: Fri, 6 Jun 2025 12:40:31 +0300 Subject: [PATCH 01/11] Yandex Bid Adapter : add support for video ads --- .../server/bidder/yandex/YandexBidder.java | 46 ++++++++-- .../bidder/yandex/YandexBidderTest.java | 88 ++++++++++++++++++- 2 files changed, 127 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/prebid/server/bidder/yandex/YandexBidder.java b/src/main/java/org/prebid/server/bidder/yandex/YandexBidder.java index 46ed20a06f1..fa6931ad802 100644 --- a/src/main/java/org/prebid/server/bidder/yandex/YandexBidder.java +++ b/src/main/java/org/prebid/server/bidder/yandex/YandexBidder.java @@ -8,6 +8,7 @@ import com.iab.openrtb.request.Format; import com.iab.openrtb.request.Imp; import com.iab.openrtb.request.Site; +import com.iab.openrtb.request.Video; import com.iab.openrtb.response.BidResponse; import com.iab.openrtb.response.SeatBid; import io.vertx.core.MultiMap; @@ -46,6 +47,8 @@ public class YandexBidder implements Bidder { private static final String PAGE_ID_MACRO = "{{PageId}}"; private static final String IMP_ID_MACRO = "{{ImpId}}"; + private static final String DISPLAY_MANAGER = "prebid.java"; + private static final String DISPLAY_MANAGER_VERSION = "1.1"; private final String endpointUrl; private final JacksonMapper mapper; @@ -110,13 +113,20 @@ private ExtImpYandex parseAndValidateImpExt(ObjectNode impExtNode, final String } private static Imp modifyImp(Imp imp) { + final Imp.ImpBuilder impBuilder = imp.toBuilder() + .displaymanager(DISPLAY_MANAGER) + .displaymanagerver(DISPLAY_MANAGER_VERSION); + if (imp.getBanner() != null) { - return imp.toBuilder().banner(modifyBanner(imp.getBanner())).build(); + return impBuilder.banner(modifyBanner(imp.getBanner())).build(); + } + if (imp.getVideo() != null) { + return impBuilder.video(modifyVideo(imp.getVideo())).build(); } if (imp.getXNative() != null) { - return imp; + return impBuilder.build(); } - throw new PreBidException("Yandex only supports banner and native types. Ignoring imp id #%s" + throw new PreBidException("Yandex only supports banner, video, and native types. Ignoring imp id #%s" .formatted(imp.getId())); } @@ -134,6 +144,30 @@ private static Banner modifyBanner(Banner banner) { return banner; } + private static Video modifyVideo(Video video) { + final Integer width = video.getW(); + final Integer height = video.getH(); + if (width == null || height == null || width == 0 || height == 0) { + throw new PreBidException("Invalid sizes provided for Video %sx%s".formatted(width, height)); + } + + final Video.VideoBuilder videoBuilder = video.toBuilder(); + if (video.getMinduration() == null || video.getMinduration() == 0) { + videoBuilder.minduration(1); + } + if (video.getMaxduration() == null || video.getMaxduration() == 0) { + videoBuilder.maxduration(120); + } + if (CollectionUtils.isEmpty(video.getMimes())) { + videoBuilder.mimes(Collections.singletonList("video/mp4")); + } + if (CollectionUtils.isEmpty(video.getProtocols())) { + videoBuilder.protocols(Collections.singletonList(3)); + } + + return videoBuilder.build(); + } + private String modifyUrl(ExtImpYandex extImpYandex, String referer, String currency) { final String resolvedUrl = endpointUrl .replace(PAGE_ID_MACRO, HttpUtil.encodeUrl(extImpYandex.getPageId().toString())) @@ -217,15 +251,15 @@ private static BidType getBidType(String bidImpId, List imps) { } private static BidType resolveImpType(Imp imp) { - if (imp.getXNative() != null) { - return BidType.xNative; - } if (imp.getBanner() != null) { return BidType.banner; } if (imp.getVideo() != null) { return BidType.video; } + if (imp.getXNative() != null) { + return BidType.xNative; + } if (imp.getAudio() != null) { return BidType.audio; } diff --git a/src/test/java/org/prebid/server/bidder/yandex/YandexBidderTest.java b/src/test/java/org/prebid/server/bidder/yandex/YandexBidderTest.java index dbc3cf23856..dbed1c0aa24 100644 --- a/src/test/java/org/prebid/server/bidder/yandex/YandexBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/yandex/YandexBidderTest.java @@ -144,7 +144,7 @@ public void makeHttpRequestsShouldCreateARequestForEachImpAndSkipImpsWithNoBanne final Result>> result = target.makeHttpRequests(bidRequest); // then assertThat(result.getErrors()).containsExactly( - BidderError.badInput("Yandex only supports banner and native types. Ignoring imp id #blockA") + BidderError.badInput("Yandex only supports banner, video, and native types. Ignoring imp id #blockA") ); } @@ -215,6 +215,57 @@ public void makeHttpRequestsSetFirstImpressionBannerWidthAndHeightWhenFromFirstF .containsOnly(tuple(300, 600)); } + @Test + public void makeHttpRequestsShouldReturnErrorWhenVideoWidthIsZero() { + // given + final BidRequest bidRequest = givenBidRequest( + impBuilder -> impBuilder.id("blockA").banner(null).video(Video.builder().w(0).h(600).build()), + identity()); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + assertThat(result.getValue()).isEmpty(); + assertThat(result.getErrors()).containsExactly(BidderError.badInput("Invalid sizes provided for Video 0x600")); + } + + @Test + public void makeHttpRequestsShouldReturnErrorWhenVideoHeightIsZero() { + // given + final BidRequest bidRequest = givenBidRequest( + impBuilder -> impBuilder.id("blockA").banner(null).video(Video.builder().w(300).h(0).build()), + identity()); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + assertThat(result.getValue()).isEmpty(); + assertThat(result.getErrors()).containsExactly(BidderError.badInput("Invalid sizes provided for Video 300x0")); + } + + @Test + public void makeHttpRequestsShouldModifyVideoParameters() { + // given + final BidRequest bidRequest = givenBidRequest( + impBuilder -> impBuilder.id("blockA").banner(null) + .video(Video.builder().w(300).h(600).build()), + identity()); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + assertThat(result.getErrors()).isEmpty(); + assertThat(result.getValue()).hasSize(1) + .extracting(HttpRequest::getPayload) + .flatExtracting(BidRequest::getImp) + .extracting(Imp::getVideo) + .extracting(Video::getMinduration, Video::getMaxduration, Video::getMimes, Video::getProtocols) + .containsOnly(tuple(1, 120, singletonList("video/mp4"), singletonList(3))); + } + @Test public void makeBidsShouldReturnErrorIfResponseBodyCouldNotBeParsed() { // given @@ -444,4 +495,39 @@ private static BidderCall givenBidderCall(BidRequest bidRequest, Str HttpResponse.of(200, null, body), null); } + + @Test + public void makeHttpRequestsShouldSetDisplayManagerAndVersionForAllImpTypes() { + // given + final BidRequest bidRequest = BidRequest.builder() + .site(Site.builder().id("1").build()) + .imp(asList( + Imp.builder().id("bannerImp") + .banner(Banner.builder().w(300).h(600).build()) + .ext(givenImpExt(1)) + .build(), + Imp.builder().id("videoImp") + .video(Video.builder().w(300).h(600).build()) + .ext(givenImpExt(2)) + .build(), + Imp.builder().id("nativeImp") + .xNative(Native.builder().build()) + .ext(givenImpExt(3)) + .build())) + .build(); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + assertThat(result.getErrors()).isEmpty(); + assertThat(result.getValue()).hasSize(3) + .extracting(HttpRequest::getPayload) + .flatExtracting(BidRequest::getImp) + .extracting(Imp::getDisplaymanager, Imp::getDisplaymanagerver) + .containsOnly( + tuple("prebid.java", "1.1"), + tuple("prebid.java", "1.1"), + tuple("prebid.java", "1.1")); + } } From ab53806b92b0e4035fa8ae65aedf7b7955bb9dc8 Mon Sep 17 00:00:00 2001 From: Dmitrii Ermakov Date: Tue, 10 Jun 2025 16:03:00 +0300 Subject: [PATCH 02/11] Fix test: resources request.json --- .../server/it/openrtb2/yandex/test-yandex-bid-request.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/resources/org/prebid/server/it/openrtb2/yandex/test-yandex-bid-request.json b/src/test/resources/org/prebid/server/it/openrtb2/yandex/test-yandex-bid-request.json index c833c0633f5..4db9a09b23b 100644 --- a/src/test/resources/org/prebid/server/it/openrtb2/yandex/test-yandex-bid-request.json +++ b/src/test/resources/org/prebid/server/it/openrtb2/yandex/test-yandex-bid-request.json @@ -8,6 +8,8 @@ "w": 300, "h": 600 }, + "displaymanager" : "prebid.java", + "displaymanagerver" : "1.1", "ext": { "tid": "${json-unit.any-string}", "bidder": { From f02bdd3e3e8b366373cb0f7809bbff78fa79d643 Mon Sep 17 00:00:00 2001 From: Dmitrii Ermakov Date: Thu, 31 Jul 2025 16:41:29 +0300 Subject: [PATCH 03/11] CR fix --- .../server/bidder/yandex/YandexBidder.java | 34 ++-- .../bidder/yandex/YandexBidderTest.java | 145 +++++++++++++----- 2 files changed, 134 insertions(+), 45 deletions(-) diff --git a/src/main/java/org/prebid/server/bidder/yandex/YandexBidder.java b/src/main/java/org/prebid/server/bidder/yandex/YandexBidder.java index fa6931ad802..ada3a3c4bb9 100644 --- a/src/main/java/org/prebid/server/bidder/yandex/YandexBidder.java +++ b/src/main/java/org/prebid/server/bidder/yandex/YandexBidder.java @@ -117,17 +117,30 @@ private static Imp modifyImp(Imp imp) { .displaymanager(DISPLAY_MANAGER) .displaymanagerver(DISPLAY_MANAGER_VERSION); + boolean hasValidFormat = false; + if (imp.getBanner() != null) { - return impBuilder.banner(modifyBanner(imp.getBanner())).build(); + impBuilder.banner(modifyBanner(imp.getBanner())); + hasValidFormat = true; } + if (imp.getVideo() != null) { - return impBuilder.video(modifyVideo(imp.getVideo())).build(); + impBuilder.video(modifyVideo(imp.getVideo())); + hasValidFormat = true; } + + // Обрабатываем native формат if (imp.getXNative() != null) { - return impBuilder.build(); + impBuilder.xNative(imp.getXNative()); + hasValidFormat = true; } - throw new PreBidException("Yandex only supports banner, video, and native types. Ignoring imp id #%s" - .formatted(imp.getId())); + + if (!hasValidFormat) { + throw new PreBidException("Imp #%s must contain at least one valid format (banner, video, or native)" + .formatted(imp.getId())); + } + + return impBuilder.build(); } private static Banner modifyBanner(Banner banner) { @@ -201,6 +214,10 @@ private HttpRequest buildHttpRequest(BidRequest outgoingRequest, Str private static MultiMap headers(BidRequest bidRequest) { final MultiMap headers = HttpUtil.headers(); + + headers.add(HttpUtil.X_OPENRTB_VERSION_HEADER, "2.5"); + HttpUtil.addHeaderIfValueIsNotEmpty(headers, "Referer", getReferer(bidRequest)); + final Device device = bidRequest.getDevice(); if (device != null) { HttpUtil.addHeaderIfValueIsNotEmpty(headers, HttpUtil.ACCEPT_LANGUAGE_HEADER, device.getLanguage()); @@ -251,17 +268,14 @@ private static BidType getBidType(String bidImpId, List imps) { } private static BidType resolveImpType(Imp imp) { - if (imp.getBanner() != null) { - return BidType.banner; - } if (imp.getVideo() != null) { return BidType.video; } if (imp.getXNative() != null) { return BidType.xNative; } - if (imp.getAudio() != null) { - return BidType.audio; + if (imp.getBanner() != null) { + return BidType.banner; } throw new PreBidException("Processing an invalid impression; cannot resolve impression type for imp #%s" .formatted(imp.getId())); diff --git a/src/test/java/org/prebid/server/bidder/yandex/YandexBidderTest.java b/src/test/java/org/prebid/server/bidder/yandex/YandexBidderTest.java index dbed1c0aa24..b63179a5ddf 100644 --- a/src/test/java/org/prebid/server/bidder/yandex/YandexBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/yandex/YandexBidderTest.java @@ -2,7 +2,6 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.node.ObjectNode; -import com.iab.openrtb.request.Audio; import com.iab.openrtb.request.Banner; import com.iab.openrtb.request.BidRequest; import com.iab.openrtb.request.Device; @@ -36,7 +35,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; import static org.assertj.core.api.Assertions.tuple; -import static org.prebid.server.proto.openrtb.ext.response.BidType.audio; import static org.prebid.server.proto.openrtb.ext.response.BidType.banner; import static org.prebid.server.proto.openrtb.ext.response.BidType.video; import static org.prebid.server.proto.openrtb.ext.response.BidType.xNative; @@ -144,7 +142,7 @@ public void makeHttpRequestsShouldCreateARequestForEachImpAndSkipImpsWithNoBanne final Result>> result = target.makeHttpRequests(bidRequest); // then assertThat(result.getErrors()).containsExactly( - BidderError.badInput("Yandex only supports banner, video, and native types. Ignoring imp id #blockA") + BidderError.badInput("Imp #blockA must contain at least one valid format (banner, video, or native)") ); } @@ -345,44 +343,20 @@ public void makeBidsShouldReturnErrorWhenBidImpIdIsNotPresent() throws JsonProce } @Test - public void makeBidsShouldReturnBannerAndNative() throws JsonProcessingException { - // given - final BidderCall bidderCall = givenBidderCall( - BidRequest.builder() - .imp(asList(Imp.builder().id("blockA").xNative(Native.builder().build()).build(), - Imp.builder().id("blockB").banner(Banner.builder().build()).build())) - .build(), - mapper.writeValueAsString(BidResponse.builder() - .cur("USD") - .seatbid(singletonList(SeatBid.builder() - .bid(asList(Bid.builder().impid("blockA").build(), - Bid.builder().impid("blockB").build())) - .build())) - .build())); - - // when - final Result> result = target.makeBids(bidderCall, null); - - // then - assertThat(result.getErrors()).isEmpty(); - assertThat(result.getValue()) - .containsOnly(BidderBid.of(Bid.builder().impid("blockA").build(), xNative, "USD"), - BidderBid.of(Bid.builder().impid("blockB").build(), banner, "USD")); - } - - @Test - public void makeBidsShouldReturnVideoAndAudio() throws JsonProcessingException { + public void makeBidsShouldReturnAllSupportedTypes() throws JsonProcessingException { // given final BidderCall bidderCall = givenBidderCall( BidRequest.builder() .imp(asList(Imp.builder().id("blockA").video(Video.builder().build()).build(), - Imp.builder().id("blockB").audio(Audio.builder().build()).build())) + Imp.builder().id("blockB").banner(Banner.builder().build()).build(), + Imp.builder().id("blockC").xNative(Native.builder().build()).build())) .build(), mapper.writeValueAsString(BidResponse.builder() .cur("USD") .seatbid(singletonList(SeatBid.builder() .bid(asList(Bid.builder().impid("blockA").build(), - Bid.builder().impid("blockB").build())) + Bid.builder().impid("blockB").build(), + Bid.builder().impid("blockC").build())) .build())) .build())); @@ -393,7 +367,8 @@ public void makeBidsShouldReturnVideoAndAudio() throws JsonProcessingException { assertThat(result.getErrors()).isEmpty(); assertThat(result.getValue()) .containsOnly(BidderBid.of(Bid.builder().impid("blockA").build(), video, "USD"), - BidderBid.of(Bid.builder().impid("blockB").build(), audio, "USD")); + BidderBid.of(Bid.builder().impid("blockB").build(), banner, "USD"), + BidderBid.of(Bid.builder().impid("blockC").build(), xNative, "USD")); } @Test @@ -424,7 +399,7 @@ public void makeBidsShouldReturnError() throws JsonProcessingException { public void makeHttpRequestsShouldSetExpectedHeaders() { // given final BidRequest bidRequest = givenBidRequest(identity(), - requestBuilder -> requestBuilder.site(null) + requestBuilder -> requestBuilder.site(Site.builder().id("1").page("https://example.com").build()) .device(Device.builder().ua("UA").language("EN").ip("127.0.0.1").build())); // when @@ -439,7 +414,9 @@ public void makeHttpRequestsShouldSetExpectedHeaders() { tuple("X-Forwarded-For", "127.0.0.1"), tuple("X-Real-Ip", "127.0.0.1"), tuple("Content-Type", "application/json;charset=utf-8"), - tuple("Accept", "application/json")); + tuple("Accept", "application/json"), + tuple("x-openrtb-version", "2.5"), + tuple("Referer", "https://example.com")); } @Test @@ -496,6 +473,104 @@ private static BidderCall givenBidderCall(BidRequest bidRequest, Str null); } + @Test + public void makeHttpRequestsShouldSupportMultiFormatImpression() { + // given + final BidRequest bidRequest = BidRequest.builder() + .site(Site.builder().id("1").build()) + .imp(singletonList( + Imp.builder().id("multiFormatImp") + .banner(Banner.builder().w(300).h(600).build()) + .video(Video.builder().w(300).h(600).build()) + .xNative(Native.builder().build()) + .ext(givenImpExt(1)) + .build())) + .build(); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + assertThat(result.getErrors()).isEmpty(); + assertThat(result.getValue()).hasSize(1); + + final Imp modifiedImp = result.getValue().getFirst().getPayload().getImp().getFirst(); + assertThat(modifiedImp.getBanner()).isNotNull(); + assertThat(modifiedImp.getVideo()).isNotNull(); + assertThat(modifiedImp.getXNative()).isNotNull(); + assertThat(modifiedImp.getDisplaymanager()).isEqualTo("prebid.java"); + assertThat(modifiedImp.getDisplaymanagerver()).isEqualTo("1.1"); + } + + @Test + public void makeHttpRequestsShouldSupportMultiFormatImpressionWithPartialErrors() { + // given + final BidRequest bidRequest = BidRequest.builder() + .site(Site.builder().id("1").build()) + .imp(singletonList( + Imp.builder().id("multiFormatImpWithErrors") + .banner(Banner.builder().w(0).h(0).build()) // Invalid banner + .video(Video.builder().w(300).h(600).build()) // Valid video + .xNative(Native.builder().build()) // Valid native + .ext(givenImpExt(1)) + .build())) + .build(); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + assertThat(result.getErrors()).containsExactly( + BidderError.badInput("Invalid sizes provided for Banner 0x0")); + assertThat(result.getValue()).isEmpty(); + } + + @Test + public void makeHttpRequestsShouldReturnErrorWhenNoValidFormats() { + // given + final BidRequest bidRequest = BidRequest.builder() + .site(Site.builder().id("1").build()) + .imp(singletonList( + Imp.builder().id("noValidFormats") + .banner(Banner.builder().w(0).h(0).build()) // Invalid banner + .video(Video.builder().w(0).h(0).build()) // Invalid video + .ext(givenImpExt(1)) + .build())) + .build(); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + assertThat(result.getErrors()) + .containsExactly(BidderError.badInput("Invalid sizes provided for Banner 0x0")); + assertThat(result.getValue()).isEmpty(); + } + + @Test + public void makeBidsShouldReturnCorrectBidTypeForMultiFormatImpression() throws JsonProcessingException { + // given + final BidRequest bidRequest = BidRequest.builder() + .imp(singletonList( + Imp.builder().id("multiFormatImp") + .banner(Banner.builder().w(300).h(600).build()) + .video(Video.builder().w(300).h(600).build()) + .xNative(Native.builder().build()) + .build())) + .build(); + + final BidResponse bidResponse = givenBidResponse(bidBuilder -> bidBuilder.impid("multiFormatImp")); + + // when + final Result> result = target.makeBids( + givenBidderCall(bidRequest, mapper.writeValueAsString(bidResponse)), bidRequest); + + // then + assertThat(result.getErrors()).isEmpty(); + assertThat(result.getValue()).hasSize(1); + assertThat(result.getValue().getFirst().getType()).isEqualTo(video); // Video has highest priority + } + @Test public void makeHttpRequestsShouldSetDisplayManagerAndVersionForAllImpTypes() { // given From e3ee9b1c0665937f4c89573206df2200397460c8 Mon Sep 17 00:00:00 2001 From: Dmitrii Ermakov Date: Thu, 31 Jul 2025 18:03:36 +0300 Subject: [PATCH 04/11] +video in bidder config --- src/main/resources/bidder-config/yandex.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/resources/bidder-config/yandex.yaml b/src/main/resources/bidder-config/yandex.yaml index f980fe3cb5e..e07f6859701 100644 --- a/src/main/resources/bidder-config/yandex.yaml +++ b/src/main/resources/bidder-config/yandex.yaml @@ -7,6 +7,7 @@ adapters: app-media-types: site-media-types: - banner + - video - native vendor-id: 0 usersync: From 7a25e604790419450fff7512d33a8e5330ce4e20 Mon Sep 17 00:00:00 2001 From: Dmitrii Ermakov Date: Fri, 1 Aug 2025 16:21:49 +0300 Subject: [PATCH 05/11] One more PR fix --- .../server/bidder/yandex/YandexBidder.java | 42 ++-- .../bidder/yandex/YandexBidderTest.java | 188 +++++++++++------- 2 files changed, 131 insertions(+), 99 deletions(-) diff --git a/src/main/java/org/prebid/server/bidder/yandex/YandexBidder.java b/src/main/java/org/prebid/server/bidder/yandex/YandexBidder.java index ada3a3c4bb9..9bdcc600d93 100644 --- a/src/main/java/org/prebid/server/bidder/yandex/YandexBidder.java +++ b/src/main/java/org/prebid/server/bidder/yandex/YandexBidder.java @@ -113,37 +113,25 @@ private ExtImpYandex parseAndValidateImpExt(ObjectNode impExtNode, final String } private static Imp modifyImp(Imp imp) { - final Imp.ImpBuilder impBuilder = imp.toBuilder() - .displaymanager(DISPLAY_MANAGER) - .displaymanagerver(DISPLAY_MANAGER_VERSION); - - boolean hasValidFormat = false; - - if (imp.getBanner() != null) { - impBuilder.banner(modifyBanner(imp.getBanner())); - hasValidFormat = true; - } - - if (imp.getVideo() != null) { - impBuilder.video(modifyVideo(imp.getVideo())); - hasValidFormat = true; - } - - // Обрабатываем native формат - if (imp.getXNative() != null) { - impBuilder.xNative(imp.getXNative()); - hasValidFormat = true; - } - - if (!hasValidFormat) { + if (imp.getBanner() == null && imp.getVideo() == null && imp.getXNative() == null) { throw new PreBidException("Imp #%s must contain at least one valid format (banner, video, or native)" .formatted(imp.getId())); } - - return impBuilder.build(); + + return imp.toBuilder() + .displaymanager(DISPLAY_MANAGER) + .displaymanagerver(DISPLAY_MANAGER_VERSION) + .banner(modifyBanner(imp.getBanner())) + .video(modifyVideo(imp.getVideo())) + .xNative(imp.getXNative()) + .build(); } private static Banner modifyBanner(Banner banner) { + if (banner == null) { + return null; + } + final Integer weight = banner.getW(); final Integer height = banner.getH(); final List format = banner.getFormat(); @@ -158,6 +146,10 @@ private static Banner modifyBanner(Banner banner) { } private static Video modifyVideo(Video video) { + if (video == null) { + return null; + } + final Integer width = video.getW(); final Integer height = video.getH(); if (width == null || height == null || width == 0 || height == 0) { diff --git a/src/test/java/org/prebid/server/bidder/yandex/YandexBidderTest.java b/src/test/java/org/prebid/server/bidder/yandex/YandexBidderTest.java index b63179a5ddf..9f700bdf840 100644 --- a/src/test/java/org/prebid/server/bidder/yandex/YandexBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/yandex/YandexBidderTest.java @@ -343,20 +343,39 @@ public void makeBidsShouldReturnErrorWhenBidImpIdIsNotPresent() throws JsonProce } @Test - public void makeBidsShouldReturnAllSupportedTypes() throws JsonProcessingException { + public void makeBidsShouldReturnVideoBid() throws JsonProcessingException { // given final BidderCall bidderCall = givenBidderCall( BidRequest.builder() - .imp(asList(Imp.builder().id("blockA").video(Video.builder().build()).build(), - Imp.builder().id("blockB").banner(Banner.builder().build()).build(), - Imp.builder().id("blockC").xNative(Native.builder().build()).build())) + .imp(singletonList(Imp.builder().id("blockA").video(Video.builder().build()).build())) .build(), mapper.writeValueAsString(BidResponse.builder() .cur("USD") .seatbid(singletonList(SeatBid.builder() - .bid(asList(Bid.builder().impid("blockA").build(), - Bid.builder().impid("blockB").build(), - Bid.builder().impid("blockC").build())) + .bid(singletonList(Bid.builder().impid("blockA").build())) + .build())) + .build())); + + // when + final Result> result = target.makeBids(bidderCall, null); + + // then + assertThat(result.getErrors()).isEmpty(); + assertThat(result.getValue()) + .containsOnly(BidderBid.of(Bid.builder().impid("blockA").build(), video, "USD")); + } + + @Test + public void makeBidsShouldReturnBannerBid() throws JsonProcessingException { + // given + final BidderCall bidderCall = givenBidderCall( + BidRequest.builder() + .imp(singletonList(Imp.builder().id("blockB").banner(Banner.builder().build()).build())) + .build(), + mapper.writeValueAsString(BidResponse.builder() + .cur("USD") + .seatbid(singletonList(SeatBid.builder() + .bid(singletonList(Bid.builder().impid("blockB").build())) .build())) .build())); @@ -366,9 +385,30 @@ public void makeBidsShouldReturnAllSupportedTypes() throws JsonProcessingExcepti // then assertThat(result.getErrors()).isEmpty(); assertThat(result.getValue()) - .containsOnly(BidderBid.of(Bid.builder().impid("blockA").build(), video, "USD"), - BidderBid.of(Bid.builder().impid("blockB").build(), banner, "USD"), - BidderBid.of(Bid.builder().impid("blockC").build(), xNative, "USD")); + .containsOnly(BidderBid.of(Bid.builder().impid("blockB").build(), banner, "USD")); + } + + @Test + public void makeBidsShouldReturnNativeBid() throws JsonProcessingException { + // given + final BidderCall bidderCall = givenBidderCall( + BidRequest.builder() + .imp(singletonList(Imp.builder().id("blockC").xNative(Native.builder().build()).build())) + .build(), + mapper.writeValueAsString(BidResponse.builder() + .cur("USD") + .seatbid(singletonList(SeatBid.builder() + .bid(singletonList(Bid.builder().impid("blockC").build())) + .build())) + .build())); + + // when + final Result> result = target.makeBids(bidderCall, null); + + // then + assertThat(result.getErrors()).isEmpty(); + assertThat(result.getValue()) + .containsOnly(BidderBid.of(Bid.builder().impid("blockC").build(), xNative, "USD")); } @Test @@ -395,11 +435,35 @@ public void makeBidsShouldReturnError() throws JsonProcessingException { assertThat(result.getValue()).isEmpty(); } + @Test + public void makeBidsShouldReturnCorrectBidTypeForMultiFormatImpression() throws JsonProcessingException { + // given + final BidRequest bidRequest = BidRequest.builder() + .imp(singletonList( + Imp.builder().id("multiFormatImp") + .banner(Banner.builder().w(300).h(600).build()) + .video(Video.builder().w(300).h(600).build()) + .xNative(Native.builder().build()) + .build())) + .build(); + + final BidResponse bidResponse = givenBidResponse(bidBuilder -> bidBuilder.impid("multiFormatImp")); + + // when + final Result> result = target.makeBids( + givenBidderCall(bidRequest, mapper.writeValueAsString(bidResponse)), bidRequest); + + // then + assertThat(result.getErrors()).isEmpty(); + assertThat(result.getValue()).hasSize(1); + assertThat(result.getValue().getFirst().getType()).isEqualTo(video); // Video has highest priority + } + @Test public void makeHttpRequestsShouldSetExpectedHeaders() { // given final BidRequest bidRequest = givenBidRequest(identity(), - requestBuilder -> requestBuilder.site(Site.builder().id("1").page("https://example.com").build()) + requestBuilder -> requestBuilder.site(Site.builder().id("1").page("https://example.com/path?query=value").build()) .device(Device.builder().ua("UA").language("EN").ip("127.0.0.1").build())); // when @@ -416,7 +480,7 @@ public void makeHttpRequestsShouldSetExpectedHeaders() { tuple("Content-Type", "application/json;charset=utf-8"), tuple("Accept", "application/json"), tuple("x-openrtb-version", "2.5"), - tuple("Referer", "https://example.com")); + tuple("Referer", "https://example.com/path?query=value")); } @Test @@ -424,7 +488,7 @@ public void makeHttpRequestsShouldCreateCorrectURL() { // given final BidRequest bidRequest = BidRequest.builder() .imp(singletonList(givenImp(impBuilder -> impBuilder.id("blockA").ext(givenImpExt(1))))) - .site(Site.builder().id("1").page("https://domain.com/").build()) + .site(Site.builder().id("1").page("https://example.com/path?query=value").build()) .cur(asList("EUR", "USD")) .build(); // when @@ -434,43 +498,7 @@ public void makeHttpRequestsShouldCreateCorrectURL() { assertThat(result.getErrors()).isEmpty(); assertThat(result.getValue()).extracting(HttpRequest::getUri) .containsExactly("https://test.endpoint.com/?" - + "target-ref=https%3A%2F%2Fdomain.com%2F&ssp-cur=EUR"); - } - - private static BidRequest givenBidRequest( - Function impCustomizer, - Function requestCustomizer) { - return requestCustomizer.apply(BidRequest.builder() - .site(Site.builder().id("1").build()) - .imp(singletonList(givenImp(impCustomizer)))) - .build(); - } - - private static Imp givenImp(Function impCustomizer) { - return impCustomizer.apply(Imp.builder() - .banner(Banner.builder().w(300).h(600).build()) - .ext(givenImpExt(1))) - .build(); - } - - private static ObjectNode givenImpExt(int impId) { - return mapper.valueToTree(ExtPrebid.of(null, ExtImpYandex.of(134001, impId))); - } - - private static BidResponse givenBidResponse(Function bidCustomizer) { - return BidResponse.builder() - .cur("USD") - .seatbid(singletonList(SeatBid.builder() - .bid(singletonList(bidCustomizer.apply(Bid.builder()).build())) - .build())) - .build(); - } - - private static BidderCall givenBidderCall(BidRequest bidRequest, String body) { - return BidderCall.succeededHttp( - HttpRequest.builder().payload(bidRequest).build(), - HttpResponse.of(200, null, body), - null); + + "target-ref=https%3A%2F%2Fexample.com%2Fpath%3Fquery%3Dvalue&ssp-cur=EUR"); } @Test @@ -547,30 +575,6 @@ public void makeHttpRequestsShouldReturnErrorWhenNoValidFormats() { assertThat(result.getValue()).isEmpty(); } - @Test - public void makeBidsShouldReturnCorrectBidTypeForMultiFormatImpression() throws JsonProcessingException { - // given - final BidRequest bidRequest = BidRequest.builder() - .imp(singletonList( - Imp.builder().id("multiFormatImp") - .banner(Banner.builder().w(300).h(600).build()) - .video(Video.builder().w(300).h(600).build()) - .xNative(Native.builder().build()) - .build())) - .build(); - - final BidResponse bidResponse = givenBidResponse(bidBuilder -> bidBuilder.impid("multiFormatImp")); - - // when - final Result> result = target.makeBids( - givenBidderCall(bidRequest, mapper.writeValueAsString(bidResponse)), bidRequest); - - // then - assertThat(result.getErrors()).isEmpty(); - assertThat(result.getValue()).hasSize(1); - assertThat(result.getValue().getFirst().getType()).isEqualTo(video); // Video has highest priority - } - @Test public void makeHttpRequestsShouldSetDisplayManagerAndVersionForAllImpTypes() { // given @@ -605,4 +609,40 @@ public void makeHttpRequestsShouldSetDisplayManagerAndVersionForAllImpTypes() { tuple("prebid.java", "1.1"), tuple("prebid.java", "1.1")); } + + private static BidRequest givenBidRequest( + Function impCustomizer, + Function requestCustomizer) { + return requestCustomizer.apply(BidRequest.builder() + .site(Site.builder().id("1").build()) + .imp(singletonList(givenImp(impCustomizer)))) + .build(); + } + + private static Imp givenImp(Function impCustomizer) { + return impCustomizer.apply(Imp.builder() + .banner(Banner.builder().w(300).h(600).build()) + .ext(givenImpExt(1))) + .build(); + } + + private static ObjectNode givenImpExt(int impId) { + return mapper.valueToTree(ExtPrebid.of(null, ExtImpYandex.of(134001, impId))); + } + + private static BidResponse givenBidResponse(Function bidCustomizer) { + return BidResponse.builder() + .cur("USD") + .seatbid(singletonList(SeatBid.builder() + .bid(singletonList(bidCustomizer.apply(Bid.builder()).build())) + .build())) + .build(); + } + + private static BidderCall givenBidderCall(BidRequest bidRequest, String body) { + return BidderCall.succeededHttp( + HttpRequest.builder().payload(bidRequest).build(), + HttpResponse.of(200, null, body), + null); + } } From 73efc5e9a953a527a73ee119b68e5f8ff529e7d6 Mon Sep 17 00:00:00 2001 From: Dmitrii Ermakov Date: Wed, 13 Aug 2025 14:31:16 +0300 Subject: [PATCH 06/11] fix header + tests --- .../server/bidder/yandex/YandexBidder.java | 21 +++++++++++++++---- .../bidder/yandex/YandexBidderTest.java | 2 +- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/prebid/server/bidder/yandex/YandexBidder.java b/src/main/java/org/prebid/server/bidder/yandex/YandexBidder.java index 9bdcc600d93..5b36a3be979 100644 --- a/src/main/java/org/prebid/server/bidder/yandex/YandexBidder.java +++ b/src/main/java/org/prebid/server/bidder/yandex/YandexBidder.java @@ -81,6 +81,19 @@ public Result>> makeHttpRequests(BidRequest request return Result.of(bidRequests, errors); } + private static String getDomain(BidRequest request) { + return Optional.ofNullable(request.getSite()) + .map(Site::getPage) + .map(pageUrl -> { + try { + return new URIBuilder(pageUrl).getHost(); + } catch (URISyntaxException e) { + return null; + } + }) + .orElse(null); + } + private static String getReferer(BidRequest request) { return Optional.ofNullable(request.getSite()) .map(Site::getPage) @@ -117,7 +130,7 @@ private static Imp modifyImp(Imp imp) { throw new PreBidException("Imp #%s must contain at least one valid format (banner, video, or native)" .formatted(imp.getId())); } - + return imp.toBuilder() .displaymanager(DISPLAY_MANAGER) .displaymanagerver(DISPLAY_MANAGER_VERSION) @@ -131,7 +144,7 @@ private static Banner modifyBanner(Banner banner) { if (banner == null) { return null; } - + final Integer weight = banner.getW(); final Integer height = banner.getH(); final List format = banner.getFormat(); @@ -149,7 +162,7 @@ private static Video modifyVideo(Video video) { if (video == null) { return null; } - + final Integer width = video.getW(); final Integer height = video.getH(); if (width == null || height == null || width == 0 || height == 0) { @@ -208,7 +221,7 @@ private static MultiMap headers(BidRequest bidRequest) { final MultiMap headers = HttpUtil.headers(); headers.add(HttpUtil.X_OPENRTB_VERSION_HEADER, "2.5"); - HttpUtil.addHeaderIfValueIsNotEmpty(headers, "Referer", getReferer(bidRequest)); + HttpUtil.addHeaderIfValueIsNotEmpty(headers, "Referer", getDomain(bidRequest)); final Device device = bidRequest.getDevice(); if (device != null) { diff --git a/src/test/java/org/prebid/server/bidder/yandex/YandexBidderTest.java b/src/test/java/org/prebid/server/bidder/yandex/YandexBidderTest.java index 9f700bdf840..194962f3051 100644 --- a/src/test/java/org/prebid/server/bidder/yandex/YandexBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/yandex/YandexBidderTest.java @@ -480,7 +480,7 @@ public void makeHttpRequestsShouldSetExpectedHeaders() { tuple("Content-Type", "application/json;charset=utf-8"), tuple("Accept", "application/json"), tuple("x-openrtb-version", "2.5"), - tuple("Referer", "https://example.com/path?query=value")); + tuple("Referer", "example.com")); } @Test From 00613ef87e981ec649e9d61c127be024da468ceb Mon Sep 17 00:00:00 2001 From: Dmitrii Ermakov Date: Mon, 18 Aug 2025 15:59:25 +0300 Subject: [PATCH 07/11] Revert "fix header + tests" This reverts commit e1ad64d0590396a0c092b0774c2f20e3620260ca. --- .../server/bidder/yandex/YandexBidder.java | 21 ++++--------------- .../bidder/yandex/YandexBidderTest.java | 2 +- 2 files changed, 5 insertions(+), 18 deletions(-) diff --git a/src/main/java/org/prebid/server/bidder/yandex/YandexBidder.java b/src/main/java/org/prebid/server/bidder/yandex/YandexBidder.java index 5b36a3be979..9bdcc600d93 100644 --- a/src/main/java/org/prebid/server/bidder/yandex/YandexBidder.java +++ b/src/main/java/org/prebid/server/bidder/yandex/YandexBidder.java @@ -81,19 +81,6 @@ public Result>> makeHttpRequests(BidRequest request return Result.of(bidRequests, errors); } - private static String getDomain(BidRequest request) { - return Optional.ofNullable(request.getSite()) - .map(Site::getPage) - .map(pageUrl -> { - try { - return new URIBuilder(pageUrl).getHost(); - } catch (URISyntaxException e) { - return null; - } - }) - .orElse(null); - } - private static String getReferer(BidRequest request) { return Optional.ofNullable(request.getSite()) .map(Site::getPage) @@ -130,7 +117,7 @@ private static Imp modifyImp(Imp imp) { throw new PreBidException("Imp #%s must contain at least one valid format (banner, video, or native)" .formatted(imp.getId())); } - + return imp.toBuilder() .displaymanager(DISPLAY_MANAGER) .displaymanagerver(DISPLAY_MANAGER_VERSION) @@ -144,7 +131,7 @@ private static Banner modifyBanner(Banner banner) { if (banner == null) { return null; } - + final Integer weight = banner.getW(); final Integer height = banner.getH(); final List format = banner.getFormat(); @@ -162,7 +149,7 @@ private static Video modifyVideo(Video video) { if (video == null) { return null; } - + final Integer width = video.getW(); final Integer height = video.getH(); if (width == null || height == null || width == 0 || height == 0) { @@ -221,7 +208,7 @@ private static MultiMap headers(BidRequest bidRequest) { final MultiMap headers = HttpUtil.headers(); headers.add(HttpUtil.X_OPENRTB_VERSION_HEADER, "2.5"); - HttpUtil.addHeaderIfValueIsNotEmpty(headers, "Referer", getDomain(bidRequest)); + HttpUtil.addHeaderIfValueIsNotEmpty(headers, "Referer", getReferer(bidRequest)); final Device device = bidRequest.getDevice(); if (device != null) { diff --git a/src/test/java/org/prebid/server/bidder/yandex/YandexBidderTest.java b/src/test/java/org/prebid/server/bidder/yandex/YandexBidderTest.java index 194962f3051..9f700bdf840 100644 --- a/src/test/java/org/prebid/server/bidder/yandex/YandexBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/yandex/YandexBidderTest.java @@ -480,7 +480,7 @@ public void makeHttpRequestsShouldSetExpectedHeaders() { tuple("Content-Type", "application/json;charset=utf-8"), tuple("Accept", "application/json"), tuple("x-openrtb-version", "2.5"), - tuple("Referer", "example.com")); + tuple("Referer", "https://example.com/path?query=value")); } @Test From 2db652e9e6a067b7e990c732a07ea4bf22a32b65 Mon Sep 17 00:00:00 2001 From: Dmitrii Ermakov Date: Fri, 5 Sep 2025 18:24:43 +0300 Subject: [PATCH 08/11] PR fix --- .../org/prebid/server/bidder/yandex/YandexBidder.java | 11 ++++------- src/main/resources/bidder-config/yandex.yaml | 2 +- .../prebid/server/bidder/yandex/YandexBidderTest.java | 5 ++--- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/prebid/server/bidder/yandex/YandexBidder.java b/src/main/java/org/prebid/server/bidder/yandex/YandexBidder.java index 9bdcc600d93..d3851455d1d 100644 --- a/src/main/java/org/prebid/server/bidder/yandex/YandexBidder.java +++ b/src/main/java/org/prebid/server/bidder/yandex/YandexBidder.java @@ -117,7 +117,7 @@ private static Imp modifyImp(Imp imp) { throw new PreBidException("Imp #%s must contain at least one valid format (banner, video, or native)" .formatted(imp.getId())); } - + return imp.toBuilder() .displaymanager(DISPLAY_MANAGER) .displaymanagerver(DISPLAY_MANAGER_VERSION) @@ -131,7 +131,7 @@ private static Banner modifyBanner(Banner banner) { if (banner == null) { return null; } - + final Integer weight = banner.getW(); final Integer height = banner.getH(); final List format = banner.getFormat(); @@ -149,7 +149,7 @@ private static Video modifyVideo(Video video) { if (video == null) { return null; } - + final Integer width = video.getW(); final Integer height = video.getH(); if (width == null || height == null || width == 0 || height == 0) { @@ -163,9 +163,6 @@ private static Video modifyVideo(Video video) { if (video.getMaxduration() == null || video.getMaxduration() == 0) { videoBuilder.maxduration(120); } - if (CollectionUtils.isEmpty(video.getMimes())) { - videoBuilder.mimes(Collections.singletonList("video/mp4")); - } if (CollectionUtils.isEmpty(video.getProtocols())) { videoBuilder.protocols(Collections.singletonList(3)); } @@ -208,7 +205,7 @@ private static MultiMap headers(BidRequest bidRequest) { final MultiMap headers = HttpUtil.headers(); headers.add(HttpUtil.X_OPENRTB_VERSION_HEADER, "2.5"); - HttpUtil.addHeaderIfValueIsNotEmpty(headers, "Referer", getReferer(bidRequest)); + HttpUtil.addHeaderIfValueIsNotEmpty(headers, HttpUtil.REFERER_HEADER, getReferer(bidRequest)); final Device device = bidRequest.getDevice(); if (device != null) { diff --git a/src/main/resources/bidder-config/yandex.yaml b/src/main/resources/bidder-config/yandex.yaml index e07f6859701..11800ddb11a 100644 --- a/src/main/resources/bidder-config/yandex.yaml +++ b/src/main/resources/bidder-config/yandex.yaml @@ -13,6 +13,6 @@ adapters: usersync: cookie-family-name: yandex redirect: - url: https://an.yandex.ru/mapuid/yandex/?ssp-id=10500&gdpr={{gdpr}}&gdpr_consent={{gdpr_consent}}&location={{redirect_url}} + url: https://yandex.ru/an/mapuid/yandex/?ssp-id=10500&gdpr={{gdpr}}&gdpr_consent={{gdpr_consent}}&location={{redirect_url}} support-cors: false uid-macro: '{YANDEXUID}' diff --git a/src/test/java/org/prebid/server/bidder/yandex/YandexBidderTest.java b/src/test/java/org/prebid/server/bidder/yandex/YandexBidderTest.java index 9f700bdf840..3a7eee8cdd6 100644 --- a/src/test/java/org/prebid/server/bidder/yandex/YandexBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/yandex/YandexBidderTest.java @@ -182,7 +182,6 @@ public void makeHttpRequestsShouldReturnErrorWhenBannerHasNoFormats() { final BidRequest bidRequest = givenBidRequest( impBuilder -> impBuilder.id("blockA").banner(Banner.builder().build()), identity()); - // when final Result>> result = target.makeHttpRequests(bidRequest); @@ -260,8 +259,8 @@ public void makeHttpRequestsShouldModifyVideoParameters() { .extracting(HttpRequest::getPayload) .flatExtracting(BidRequest::getImp) .extracting(Imp::getVideo) - .extracting(Video::getMinduration, Video::getMaxduration, Video::getMimes, Video::getProtocols) - .containsOnly(tuple(1, 120, singletonList("video/mp4"), singletonList(3))); + .extracting(Video::getMinduration, Video::getMaxduration, Video::getProtocols) + .containsOnly(tuple(1, 120, singletonList(3))); } @Test From 6aeb12a1112f67df1dac4b03def4ec77f1303d68 Mon Sep 17 00:00:00 2001 From: Dmitrii Ermakov Date: Wed, 1 Oct 2025 18:25:02 +0300 Subject: [PATCH 09/11] Change test order --- .../bidder/yandex/YandexBidderTest.java | 308 +++++++++--------- 1 file changed, 157 insertions(+), 151 deletions(-) diff --git a/src/test/java/org/prebid/server/bidder/yandex/YandexBidderTest.java b/src/test/java/org/prebid/server/bidder/yandex/YandexBidderTest.java index 3a7eee8cdd6..d88851f1e00 100644 --- a/src/test/java/org/prebid/server/bidder/yandex/YandexBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/yandex/YandexBidderTest.java @@ -49,6 +49,8 @@ public void creationShouldFailOnInvalidEndpointUrl() { assertThatIllegalArgumentException().isThrownBy(() -> new YandexBidder("invalid_url", jacksonMapper)); } + // ========== makeHttpRequest* tests ========== + @Test public void makeHttpRequestsShouldReturnErrorIfImpExtCouldNotBeParsed() { // given @@ -263,6 +265,159 @@ public void makeHttpRequestsShouldModifyVideoParameters() { .containsOnly(tuple(1, 120, singletonList(3))); } + @Test + public void makeHttpRequestsShouldSetExpectedHeaders() { + // given + final BidRequest bidRequest = givenBidRequest(identity(), + requestBuilder -> requestBuilder.site(Site.builder().id("1").page("https://example.com/path?query=value").build()) + .device(Device.builder().ua("UA").language("EN").ip("127.0.0.1").build())); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + assertThat(result.getErrors()).isEmpty(); + assertThat(result.getValue().getFirst().getHeaders()) + .extracting(Map.Entry::getKey, Map.Entry::getValue) + .containsOnly(tuple("Accept-Language", "EN"), + tuple("User-Agent", "UA"), + tuple("X-Forwarded-For", "127.0.0.1"), + tuple("X-Real-Ip", "127.0.0.1"), + tuple("Content-Type", "application/json;charset=utf-8"), + tuple("Accept", "application/json"), + tuple("x-openrtb-version", "2.5"), + tuple("Referer", "https://example.com/path?query=value")); + } + + @Test + public void makeHttpRequestsShouldCreateCorrectURL() { + // given + final BidRequest bidRequest = BidRequest.builder() + .imp(singletonList(givenImp(impBuilder -> impBuilder.id("blockA").ext(givenImpExt(1))))) + .site(Site.builder().id("1").page("https://example.com/path?query=value").build()) + .cur(asList("EUR", "USD")) + .build(); + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + assertThat(result.getErrors()).isEmpty(); + assertThat(result.getValue()).extracting(HttpRequest::getUri) + .containsExactly("https://test.endpoint.com/?" + + "target-ref=https%3A%2F%2Fexample.com%2Fpath%3Fquery%3Dvalue&ssp-cur=EUR"); + } + + @Test + public void makeHttpRequestsShouldSupportMultiFormatImpression() { + // given + final BidRequest bidRequest = BidRequest.builder() + .site(Site.builder().id("1").build()) + .imp(singletonList( + Imp.builder().id("multiFormatImp") + .banner(Banner.builder().w(300).h(600).build()) + .video(Video.builder().w(300).h(600).build()) + .xNative(Native.builder().build()) + .ext(givenImpExt(1)) + .build())) + .build(); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + assertThat(result.getErrors()).isEmpty(); + assertThat(result.getValue()).hasSize(1); + + final Imp modifiedImp = result.getValue().getFirst().getPayload().getImp().getFirst(); + assertThat(modifiedImp.getBanner()).isNotNull(); + assertThat(modifiedImp.getVideo()).isNotNull(); + assertThat(modifiedImp.getXNative()).isNotNull(); + assertThat(modifiedImp.getDisplaymanager()).isEqualTo("prebid.java"); + assertThat(modifiedImp.getDisplaymanagerver()).isEqualTo("1.1"); + } + + @Test + public void makeHttpRequestsShouldSupportMultiFormatImpressionWithPartialErrors() { + // given + final BidRequest bidRequest = BidRequest.builder() + .site(Site.builder().id("1").build()) + .imp(singletonList( + Imp.builder().id("multiFormatImpWithErrors") + .banner(Banner.builder().w(0).h(0).build()) // Invalid banner + .video(Video.builder().w(300).h(600).build()) // Valid video + .xNative(Native.builder().build()) // Valid native + .ext(givenImpExt(1)) + .build())) + .build(); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + assertThat(result.getErrors()).containsExactly( + BidderError.badInput("Invalid sizes provided for Banner 0x0")); + assertThat(result.getValue()).isEmpty(); + } + + @Test + public void makeHttpRequestsShouldReturnErrorWhenNoValidFormats() { + // given + final BidRequest bidRequest = BidRequest.builder() + .site(Site.builder().id("1").build()) + .imp(singletonList( + Imp.builder().id("noValidFormats") + .banner(Banner.builder().w(0).h(0).build()) // Invalid banner + .video(Video.builder().w(0).h(0).build()) // Invalid video + .ext(givenImpExt(1)) + .build())) + .build(); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + assertThat(result.getErrors()) + .containsExactly(BidderError.badInput("Invalid sizes provided for Banner 0x0")); + assertThat(result.getValue()).isEmpty(); + } + + @Test + public void makeHttpRequestsShouldSetDisplayManagerAndVersionForAllImpTypes() { + // given + final BidRequest bidRequest = BidRequest.builder() + .site(Site.builder().id("1").build()) + .imp(asList( + Imp.builder().id("bannerImp") + .banner(Banner.builder().w(300).h(600).build()) + .ext(givenImpExt(1)) + .build(), + Imp.builder().id("videoImp") + .video(Video.builder().w(300).h(600).build()) + .ext(givenImpExt(2)) + .build(), + Imp.builder().id("nativeImp") + .xNative(Native.builder().build()) + .ext(givenImpExt(3)) + .build())) + .build(); + + // when + final Result>> result = target.makeHttpRequests(bidRequest); + + // then + assertThat(result.getErrors()).isEmpty(); + assertThat(result.getValue()).hasSize(3) + .extracting(HttpRequest::getPayload) + .flatExtracting(BidRequest::getImp) + .extracting(Imp::getDisplaymanager, Imp::getDisplaymanagerver) + .containsOnly( + tuple("prebid.java", "1.1"), + tuple("prebid.java", "1.1"), + tuple("prebid.java", "1.1")); + } + + // ========== makeBids* tests ========== + @Test public void makeBidsShouldReturnErrorIfResponseBodyCouldNotBeParsed() { // given @@ -458,156 +613,7 @@ public void makeBidsShouldReturnCorrectBidTypeForMultiFormatImpression() throws assertThat(result.getValue().getFirst().getType()).isEqualTo(video); // Video has highest priority } - @Test - public void makeHttpRequestsShouldSetExpectedHeaders() { - // given - final BidRequest bidRequest = givenBidRequest(identity(), - requestBuilder -> requestBuilder.site(Site.builder().id("1").page("https://example.com/path?query=value").build()) - .device(Device.builder().ua("UA").language("EN").ip("127.0.0.1").build())); - - // when - final Result>> result = target.makeHttpRequests(bidRequest); - - // then - assertThat(result.getErrors()).isEmpty(); - assertThat(result.getValue().getFirst().getHeaders()) - .extracting(Map.Entry::getKey, Map.Entry::getValue) - .containsOnly(tuple("Accept-Language", "EN"), - tuple("User-Agent", "UA"), - tuple("X-Forwarded-For", "127.0.0.1"), - tuple("X-Real-Ip", "127.0.0.1"), - tuple("Content-Type", "application/json;charset=utf-8"), - tuple("Accept", "application/json"), - tuple("x-openrtb-version", "2.5"), - tuple("Referer", "https://example.com/path?query=value")); - } - - @Test - public void makeHttpRequestsShouldCreateCorrectURL() { - // given - final BidRequest bidRequest = BidRequest.builder() - .imp(singletonList(givenImp(impBuilder -> impBuilder.id("blockA").ext(givenImpExt(1))))) - .site(Site.builder().id("1").page("https://example.com/path?query=value").build()) - .cur(asList("EUR", "USD")) - .build(); - // when - final Result>> result = target.makeHttpRequests(bidRequest); - - // then - assertThat(result.getErrors()).isEmpty(); - assertThat(result.getValue()).extracting(HttpRequest::getUri) - .containsExactly("https://test.endpoint.com/?" - + "target-ref=https%3A%2F%2Fexample.com%2Fpath%3Fquery%3Dvalue&ssp-cur=EUR"); - } - - @Test - public void makeHttpRequestsShouldSupportMultiFormatImpression() { - // given - final BidRequest bidRequest = BidRequest.builder() - .site(Site.builder().id("1").build()) - .imp(singletonList( - Imp.builder().id("multiFormatImp") - .banner(Banner.builder().w(300).h(600).build()) - .video(Video.builder().w(300).h(600).build()) - .xNative(Native.builder().build()) - .ext(givenImpExt(1)) - .build())) - .build(); - - // when - final Result>> result = target.makeHttpRequests(bidRequest); - - // then - assertThat(result.getErrors()).isEmpty(); - assertThat(result.getValue()).hasSize(1); - - final Imp modifiedImp = result.getValue().getFirst().getPayload().getImp().getFirst(); - assertThat(modifiedImp.getBanner()).isNotNull(); - assertThat(modifiedImp.getVideo()).isNotNull(); - assertThat(modifiedImp.getXNative()).isNotNull(); - assertThat(modifiedImp.getDisplaymanager()).isEqualTo("prebid.java"); - assertThat(modifiedImp.getDisplaymanagerver()).isEqualTo("1.1"); - } - - @Test - public void makeHttpRequestsShouldSupportMultiFormatImpressionWithPartialErrors() { - // given - final BidRequest bidRequest = BidRequest.builder() - .site(Site.builder().id("1").build()) - .imp(singletonList( - Imp.builder().id("multiFormatImpWithErrors") - .banner(Banner.builder().w(0).h(0).build()) // Invalid banner - .video(Video.builder().w(300).h(600).build()) // Valid video - .xNative(Native.builder().build()) // Valid native - .ext(givenImpExt(1)) - .build())) - .build(); - - // when - final Result>> result = target.makeHttpRequests(bidRequest); - - // then - assertThat(result.getErrors()).containsExactly( - BidderError.badInput("Invalid sizes provided for Banner 0x0")); - assertThat(result.getValue()).isEmpty(); - } - - @Test - public void makeHttpRequestsShouldReturnErrorWhenNoValidFormats() { - // given - final BidRequest bidRequest = BidRequest.builder() - .site(Site.builder().id("1").build()) - .imp(singletonList( - Imp.builder().id("noValidFormats") - .banner(Banner.builder().w(0).h(0).build()) // Invalid banner - .video(Video.builder().w(0).h(0).build()) // Invalid video - .ext(givenImpExt(1)) - .build())) - .build(); - - // when - final Result>> result = target.makeHttpRequests(bidRequest); - - // then - assertThat(result.getErrors()) - .containsExactly(BidderError.badInput("Invalid sizes provided for Banner 0x0")); - assertThat(result.getValue()).isEmpty(); - } - - @Test - public void makeHttpRequestsShouldSetDisplayManagerAndVersionForAllImpTypes() { - // given - final BidRequest bidRequest = BidRequest.builder() - .site(Site.builder().id("1").build()) - .imp(asList( - Imp.builder().id("bannerImp") - .banner(Banner.builder().w(300).h(600).build()) - .ext(givenImpExt(1)) - .build(), - Imp.builder().id("videoImp") - .video(Video.builder().w(300).h(600).build()) - .ext(givenImpExt(2)) - .build(), - Imp.builder().id("nativeImp") - .xNative(Native.builder().build()) - .ext(givenImpExt(3)) - .build())) - .build(); - - // when - final Result>> result = target.makeHttpRequests(bidRequest); - - // then - assertThat(result.getErrors()).isEmpty(); - assertThat(result.getValue()).hasSize(3) - .extracting(HttpRequest::getPayload) - .flatExtracting(BidRequest::getImp) - .extracting(Imp::getDisplaymanager, Imp::getDisplaymanagerver) - .containsOnly( - tuple("prebid.java", "1.1"), - tuple("prebid.java", "1.1"), - tuple("prebid.java", "1.1")); - } + // ========== Helper methods ========== private static BidRequest givenBidRequest( Function impCustomizer, @@ -644,4 +650,4 @@ private static BidderCall givenBidderCall(BidRequest bidRequest, Str HttpResponse.of(200, null, body), null); } -} +} \ No newline at end of file From 5a2942e7cc9e1436741f39757513094d4b71fca9 Mon Sep 17 00:00:00 2001 From: Dmitrii Ermakov Date: Thu, 9 Oct 2025 16:55:54 +0300 Subject: [PATCH 10/11] Add empty line in the test file --- .../java/org/prebid/server/bidder/yandex/YandexBidderTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/prebid/server/bidder/yandex/YandexBidderTest.java b/src/test/java/org/prebid/server/bidder/yandex/YandexBidderTest.java index d88851f1e00..396b1eb4e43 100644 --- a/src/test/java/org/prebid/server/bidder/yandex/YandexBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/yandex/YandexBidderTest.java @@ -650,4 +650,4 @@ private static BidderCall givenBidderCall(BidRequest bidRequest, Str HttpResponse.of(200, null, body), null); } -} \ No newline at end of file +} From aa80224156ccf73e9f1021bebf02ddc613588f53 Mon Sep 17 00:00:00 2001 From: Dmitrii Ermakov Date: Mon, 13 Oct 2025 16:58:18 +0300 Subject: [PATCH 11/11] pr fix --- .../org/prebid/server/bidder/yandex/YandexBidderTest.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/test/java/org/prebid/server/bidder/yandex/YandexBidderTest.java b/src/test/java/org/prebid/server/bidder/yandex/YandexBidderTest.java index 396b1eb4e43..26322943187 100644 --- a/src/test/java/org/prebid/server/bidder/yandex/YandexBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/yandex/YandexBidderTest.java @@ -49,8 +49,6 @@ public void creationShouldFailOnInvalidEndpointUrl() { assertThatIllegalArgumentException().isThrownBy(() -> new YandexBidder("invalid_url", jacksonMapper)); } - // ========== makeHttpRequest* tests ========== - @Test public void makeHttpRequestsShouldReturnErrorIfImpExtCouldNotBeParsed() { // given @@ -416,8 +414,6 @@ public void makeHttpRequestsShouldSetDisplayManagerAndVersionForAllImpTypes() { tuple("prebid.java", "1.1")); } - // ========== makeBids* tests ========== - @Test public void makeBidsShouldReturnErrorIfResponseBodyCouldNotBeParsed() { // given @@ -613,8 +609,6 @@ public void makeBidsShouldReturnCorrectBidTypeForMultiFormatImpression() throws assertThat(result.getValue().getFirst().getType()).isEqualTo(video); // Video has highest priority } - // ========== Helper methods ========== - private static BidRequest givenBidRequest( Function impCustomizer, Function requestCustomizer) {