Skip to content

Commit 00a9017

Browse files
committed
Yandex Bid Adapter : add support for video ads
1 parent 8a86567 commit 00a9017

File tree

2 files changed

+127
-7
lines changed

2 files changed

+127
-7
lines changed

src/main/java/org/prebid/server/bidder/yandex/YandexBidder.java

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import com.iab.openrtb.request.Format;
99
import com.iab.openrtb.request.Imp;
1010
import com.iab.openrtb.request.Site;
11+
import com.iab.openrtb.request.Video;
1112
import com.iab.openrtb.response.BidResponse;
1213
import com.iab.openrtb.response.SeatBid;
1314
import io.vertx.core.MultiMap;
@@ -46,6 +47,8 @@ public class YandexBidder implements Bidder<BidRequest> {
4647

4748
private static final String PAGE_ID_MACRO = "{{PageId}}";
4849
private static final String IMP_ID_MACRO = "{{ImpId}}";
50+
private static final String DISPLAY_MANAGER = "prebid.java";
51+
private static final String DISPLAY_MANAGER_VERSION = "1.1";
4952

5053
private final String endpointUrl;
5154
private final JacksonMapper mapper;
@@ -110,13 +113,20 @@ private ExtImpYandex parseAndValidateImpExt(ObjectNode impExtNode, final String
110113
}
111114

112115
private static Imp modifyImp(Imp imp) {
116+
final Imp.ImpBuilder impBuilder = imp.toBuilder()
117+
.displaymanager(DISPLAY_MANAGER)
118+
.displaymanagerver(DISPLAY_MANAGER_VERSION);
119+
113120
if (imp.getBanner() != null) {
114-
return imp.toBuilder().banner(modifyBanner(imp.getBanner())).build();
121+
return impBuilder.banner(modifyBanner(imp.getBanner())).build();
122+
}
123+
if (imp.getVideo() != null) {
124+
return impBuilder.video(modifyVideo(imp.getVideo())).build();
115125
}
116126
if (imp.getXNative() != null) {
117-
return imp;
127+
return impBuilder.build();
118128
}
119-
throw new PreBidException("Yandex only supports banner and native types. Ignoring imp id #%s"
129+
throw new PreBidException("Yandex only supports banner, video, and native types. Ignoring imp id #%s"
120130
.formatted(imp.getId()));
121131
}
122132

@@ -134,6 +144,30 @@ private static Banner modifyBanner(Banner banner) {
134144
return banner;
135145
}
136146

147+
private static Video modifyVideo(Video video) {
148+
final Integer width = video.getW();
149+
final Integer height = video.getH();
150+
if (width == null || height == null || width == 0 || height == 0) {
151+
throw new PreBidException("Invalid sizes provided for Video %sx%s".formatted(width, height));
152+
}
153+
154+
final Video.VideoBuilder videoBuilder = video.toBuilder();
155+
if (video.getMinduration() == null || video.getMinduration() == 0) {
156+
videoBuilder.minduration(1);
157+
}
158+
if (video.getMaxduration() == null || video.getMaxduration() == 0) {
159+
videoBuilder.maxduration(120);
160+
}
161+
if (CollectionUtils.isEmpty(video.getMimes())) {
162+
videoBuilder.mimes(Collections.singletonList("video/mp4"));
163+
}
164+
if (CollectionUtils.isEmpty(video.getProtocols())) {
165+
videoBuilder.protocols(Collections.singletonList(3));
166+
}
167+
168+
return videoBuilder.build();
169+
}
170+
137171
private String modifyUrl(ExtImpYandex extImpYandex, String referer, String currency) {
138172
final String resolvedUrl = endpointUrl
139173
.replace(PAGE_ID_MACRO, HttpUtil.encodeUrl(extImpYandex.getPageId().toString()))
@@ -217,15 +251,15 @@ private static BidType getBidType(String bidImpId, List<Imp> imps) {
217251
}
218252

219253
private static BidType resolveImpType(Imp imp) {
220-
if (imp.getXNative() != null) {
221-
return BidType.xNative;
222-
}
223254
if (imp.getBanner() != null) {
224255
return BidType.banner;
225256
}
226257
if (imp.getVideo() != null) {
227258
return BidType.video;
228259
}
260+
if (imp.getXNative() != null) {
261+
return BidType.xNative;
262+
}
229263
if (imp.getAudio() != null) {
230264
return BidType.audio;
231265
}

src/test/java/org/prebid/server/bidder/yandex/YandexBidderTest.java

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ public void makeHttpRequestsShouldCreateARequestForEachImpAndSkipImpsWithNoBanne
144144
final Result<List<HttpRequest<BidRequest>>> result = target.makeHttpRequests(bidRequest);
145145
// then
146146
assertThat(result.getErrors()).containsExactly(
147-
BidderError.badInput("Yandex only supports banner and native types. Ignoring imp id #blockA")
147+
BidderError.badInput("Yandex only supports banner, video, and native types. Ignoring imp id #blockA")
148148
);
149149
}
150150

@@ -215,6 +215,57 @@ public void makeHttpRequestsSetFirstImpressionBannerWidthAndHeightWhenFromFirstF
215215
.containsOnly(tuple(300, 600));
216216
}
217217

218+
@Test
219+
public void makeHttpRequestsShouldReturnErrorWhenVideoWidthIsZero() {
220+
// given
221+
final BidRequest bidRequest = givenBidRequest(
222+
impBuilder -> impBuilder.id("blockA").banner(null).video(Video.builder().w(0).h(600).build()),
223+
identity());
224+
225+
// when
226+
final Result<List<HttpRequest<BidRequest>>> result = target.makeHttpRequests(bidRequest);
227+
228+
// then
229+
assertThat(result.getValue()).isEmpty();
230+
assertThat(result.getErrors()).containsExactly(BidderError.badInput("Invalid sizes provided for Video 0x600"));
231+
}
232+
233+
@Test
234+
public void makeHttpRequestsShouldReturnErrorWhenVideoHeightIsZero() {
235+
// given
236+
final BidRequest bidRequest = givenBidRequest(
237+
impBuilder -> impBuilder.id("blockA").banner(null).video(Video.builder().w(300).h(0).build()),
238+
identity());
239+
240+
// when
241+
final Result<List<HttpRequest<BidRequest>>> result = target.makeHttpRequests(bidRequest);
242+
243+
// then
244+
assertThat(result.getValue()).isEmpty();
245+
assertThat(result.getErrors()).containsExactly(BidderError.badInput("Invalid sizes provided for Video 300x0"));
246+
}
247+
248+
@Test
249+
public void makeHttpRequestsShouldModifyVideoParameters() {
250+
// given
251+
final BidRequest bidRequest = givenBidRequest(
252+
impBuilder -> impBuilder.id("blockA").banner(null)
253+
.video(Video.builder().w(300).h(600).build()),
254+
identity());
255+
256+
// when
257+
final Result<List<HttpRequest<BidRequest>>> result = target.makeHttpRequests(bidRequest);
258+
259+
// then
260+
assertThat(result.getErrors()).isEmpty();
261+
assertThat(result.getValue()).hasSize(1)
262+
.extracting(HttpRequest::getPayload)
263+
.flatExtracting(BidRequest::getImp)
264+
.extracting(Imp::getVideo)
265+
.extracting(Video::getMinduration, Video::getMaxduration, Video::getMimes, Video::getProtocols)
266+
.containsOnly(tuple(1, 120, singletonList("video/mp4"), singletonList(3)));
267+
}
268+
218269
@Test
219270
public void makeBidsShouldReturnErrorIfResponseBodyCouldNotBeParsed() {
220271
// given
@@ -444,4 +495,39 @@ private static BidderCall<BidRequest> givenBidderCall(BidRequest bidRequest, Str
444495
HttpResponse.of(200, null, body),
445496
null);
446497
}
498+
499+
@Test
500+
public void makeHttpRequestsShouldSetDisplayManagerAndVersionForAllImpTypes() {
501+
// given
502+
final BidRequest bidRequest = BidRequest.builder()
503+
.site(Site.builder().id("1").build())
504+
.imp(asList(
505+
Imp.builder().id("bannerImp")
506+
.banner(Banner.builder().w(300).h(600).build())
507+
.ext(givenImpExt(1))
508+
.build(),
509+
Imp.builder().id("videoImp")
510+
.video(Video.builder().w(300).h(600).build())
511+
.ext(givenImpExt(2))
512+
.build(),
513+
Imp.builder().id("nativeImp")
514+
.xNative(Native.builder().build())
515+
.ext(givenImpExt(3))
516+
.build()))
517+
.build();
518+
519+
// when
520+
final Result<List<HttpRequest<BidRequest>>> result = target.makeHttpRequests(bidRequest);
521+
522+
// then
523+
assertThat(result.getErrors()).isEmpty();
524+
assertThat(result.getValue()).hasSize(3)
525+
.extracting(HttpRequest::getPayload)
526+
.flatExtracting(BidRequest::getImp)
527+
.extracting(Imp::getDisplaymanager, Imp::getDisplaymanagerver)
528+
.containsOnly(
529+
tuple("prebid.java", "1.1"),
530+
tuple("prebid.java", "1.1"),
531+
tuple("prebid.java", "1.1"));
532+
}
447533
}

0 commit comments

Comments
 (0)