diff --git a/src/main/java/org/prebid/server/bidder/adkernel/AdkernelBidder.java b/src/main/java/org/prebid/server/bidder/adkernel/AdkernelBidder.java index d632fc37e21..44c3eaf45ab 100644 --- a/src/main/java/org/prebid/server/bidder/adkernel/AdkernelBidder.java +++ b/src/main/java/org/prebid/server/bidder/adkernel/AdkernelBidder.java @@ -246,11 +246,7 @@ private static BidderBid makeBidderBid(Bid bid, List imps, String currency) final Optional mfSuffix = getMfSuffix(bid.getImpid()); final Bid updatedBid = mfSuffix.map(suffix -> removeMfSuffixFromImpId(bid, suffix)).orElse(bid); - final BidType bidType = mfSuffix - .flatMap(AdkernelBidder::getTypeFromMsSuffix) - .orElseGet(() -> getTypeFromImp(updatedBid.getImpid(), imps)); - - return BidderBid.of(updatedBid, bidType, currency); + return BidderBid.of(updatedBid, getBidType(bid), currency); } private static Optional getMfSuffix(String impId) { @@ -265,35 +261,19 @@ private static Bid removeMfSuffixFromImpId(Bid bid, String mfSuffix) { .build(); } - private static Optional getTypeFromMsSuffix(String msSuffix) { - final BidType bidType = switch (msSuffix) { - case MF_SUFFIX_BANNER -> BidType.banner; - case MF_SUFFIX_VIDEO -> BidType.video; - case MF_SUFFIX_AUDIO -> BidType.audio; - case MF_SUFFIX_NATIVE -> BidType.xNative; - default -> null; - }; - - return Optional.ofNullable(bidType); - } - - private static BidType getTypeFromImp(String impId, List imps) { - for (Imp imp : imps) { - if (!imp.getId().equals(impId)) { - continue; - } - - if (imp.getBanner() != null) { - return BidType.banner; - } else if (imp.getVideo() != null) { - return BidType.video; - } else if (imp.getAudio() != null) { - return BidType.audio; - } else if (imp.getXNative() != null) { - return BidType.xNative; - } + private static BidType getBidType(Bid bid) { + final Integer markupType = bid.getMtype(); + if (markupType == null) { + throw new PreBidException("Missing MType for bid: " + bid.getId()); } - return BidType.video; + return switch (markupType) { + case 1 -> BidType.banner; + case 2 -> BidType.video; + case 3 -> BidType.audio; + case 4 -> BidType.xNative; + default -> throw new PreBidException( + "Unsupported MType %d".formatted(markupType)); + }; } } diff --git a/src/test/java/org/prebid/server/bidder/adkernel/AdkernelBidderTest.java b/src/test/java/org/prebid/server/bidder/adkernel/AdkernelBidderTest.java index 00d618e1404..8759cc04679 100644 --- a/src/test/java/org/prebid/server/bidder/adkernel/AdkernelBidderTest.java +++ b/src/test/java/org/prebid/server/bidder/adkernel/AdkernelBidderTest.java @@ -15,6 +15,7 @@ import com.iab.openrtb.response.BidResponse; import com.iab.openrtb.response.SeatBid; import io.vertx.core.http.HttpMethod; +import lombok.SneakyThrows; import org.junit.jupiter.api.Test; import org.prebid.server.VertxTest; import org.prebid.server.bidder.model.BidderBid; @@ -284,19 +285,14 @@ public void makeBidsShouldReturnErrorWhenSeatBidsCountIsNotOne() throws JsonProc } @Test - public void makeBidsShouldResolveBidTypeFromMfSuffixWhenPresent() throws JsonProcessingException { + public void makeBidsShouldResolveBidTypeToBannerWhenMTypeIsOne() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( givenBidRequest( identity(), impBuilder -> impBuilder.id("123").banner(Banner.builder().build()) .video(Video.builder().build())), - mapper.writeValueAsString( - givenBidResponse( - bidBuilder -> bidBuilder.impid("123b__mf"), - bidBuilder -> bidBuilder.impid("123v__mf"), - bidBuilder -> bidBuilder.impid("123a__mf"), - bidBuilder -> bidBuilder.impid("123n__mf")))); + givenBidResponse(bidBuilder -> bidBuilder.mtype(1).impid("123b__mf"))); // when final Result> result = target.makeBids(httpCall, null); @@ -304,152 +300,106 @@ public void makeBidsShouldResolveBidTypeFromMfSuffixWhenPresent() throws JsonPro // then assertThat(result.getErrors()).isEmpty(); assertThat(result.getValue()) - .containsExactlyInAnyOrder( - BidderBid.of(Bid.builder().impid("123").build(), banner, "USD"), - BidderBid.of(Bid.builder().impid("123").build(), video, "USD"), - BidderBid.of(Bid.builder().impid("123").build(), audio, "USD"), - BidderBid.of(Bid.builder().impid("123").build(), xNative, "USD")); + .extracting(BidderBid::getType) + .containsExactly(banner); } @Test - public void makeBidsShouldResolveVideoBidTypeFromImpWhenMfSuffixIsAbsentAndVideoPresentInRequestImp() - throws JsonProcessingException { - - // given - final BidderCall httpCall = givenHttpCall( - givenBidRequest( - identity(), - impBuilder -> impBuilder - .id("123") - .video(Video.builder().build()) - .banner(null) - .audio(null) - .xNative(null)), - mapper.writeValueAsString(givenBidResponse(bidBuilder -> bidBuilder.impid("123")))); - - // when - final Result> result = target.makeBids(httpCall, null); - - // then - assertThat(result.getErrors()).isEmpty(); - assertThat(result.getValue()).containsExactly( - BidderBid.of(Bid.builder().impid("123").build(), video, "USD")); - } - - @Test - public void makeBidsShouldResolveBannerBidTypeFromImpWhenMfSuffixIsAbsentAndBannerPresentInRequestImp() - throws JsonProcessingException { - + public void makeBidsShouldResolveBidTypeToVideoWhenMTypeIsTwo() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( givenBidRequest( identity(), - impBuilder -> impBuilder - .id("123") - .video(null) - .banner(Banner.builder().build()) - .audio(null) - .xNative(null)), - mapper.writeValueAsString(givenBidResponse(bidBuilder -> bidBuilder.impid("123")))); + impBuilder -> impBuilder.id("123").banner(Banner.builder().build()) + .video(Video.builder().build())), + givenBidResponse(bidBuilder -> bidBuilder.mtype(2).impid("123b__mf"))); // when final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getValue()).containsExactly( - BidderBid.of(Bid.builder().impid("123").build(), banner, "USD")); + assertThat(result.getValue()) + .extracting(BidderBid::getType) + .containsExactly(video); } @Test - public void makeBidsShouldResolveAudioBidTypeFromImpWhenMfSuffixIsAbsentAndAudioPresentInRequestImp() - throws JsonProcessingException { - + public void makeBidsShouldResolveBidTypeToAudioWhenMTypeIsThree() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( givenBidRequest( identity(), - impBuilder -> impBuilder - .id("123") - .video(null) - .banner(null) - .audio(Audio.builder().build()) - .xNative(null)), - mapper.writeValueAsString(givenBidResponse(bidBuilder -> bidBuilder.impid("123")))); + impBuilder -> impBuilder.id("123").banner(Banner.builder().build()) + .video(Video.builder().build())), + givenBidResponse(bidBuilder -> bidBuilder.mtype(3).impid("123b__mf"))); // when final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getValue()).containsExactly( - BidderBid.of(Bid.builder().impid("123").build(), audio, "USD")); + assertThat(result.getValue()) + .extracting(BidderBid::getType) + .containsExactly(audio); } @Test - public void makeBidsShouldResolveNativeBidTypeFromImpWhenMfSuffixIsAbsentAndNativePresentInRequestImp() - throws JsonProcessingException { - + public void makeBidsShouldResolveBidTypeToNativeWhenMTypeIsFour() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( givenBidRequest( identity(), - impBuilder -> impBuilder - .id("123") - .video(null) - .banner(null) - .audio(null) - .xNative(Native.builder().build())), - mapper.writeValueAsString(givenBidResponse(bidBuilder -> bidBuilder.impid("123")))); + impBuilder -> impBuilder.id("123").banner(Banner.builder().build()) + .video(Video.builder().build())), + givenBidResponse(bidBuilder -> bidBuilder.mtype(4).impid("123b__mf"))); // when final Result> result = target.makeBids(httpCall, null); // then assertThat(result.getErrors()).isEmpty(); - assertThat(result.getValue()).containsExactly( - BidderBid.of(Bid.builder().impid("123").build(), xNative, "USD")); + assertThat(result.getValue()) + .extracting(BidderBid::getType) + .containsExactly(xNative); } @Test - public void makeBidsShouldReturnVideoBid() throws JsonProcessingException { + public void makeBidsShouldReturnErrorIfMtypeIsMissing() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( givenBidRequest( identity(), - impBuilder -> impBuilder.id("123") + impBuilder -> impBuilder.id("123").banner(Banner.builder().build()) .video(Video.builder().build())), - mapper.writeValueAsString( - givenBidResponse(bidBuilder -> bidBuilder.impid("123")))); + givenBidResponse(bidBuilder -> bidBuilder.id("bidId").mtype(null).impid("123b__mf"))); // when final Result> result = target.makeBids(httpCall, null); // then - assertThat(result.getErrors()).isEmpty(); - assertThat(result.getValue()) - .containsExactly(BidderBid.of(Bid.builder().impid("123").build(), video, "USD")); + assertThat(result.getErrors()) + .containsExactly(BidderError.badServerResponse("Missing MType for bid: bidId")); + assertThat(result.getValue()).isEmpty(); } @Test - public void makeBidsShouldReturnBannerBidIfRequestImpHasBanner() throws JsonProcessingException { + public void makeBidsShouldReturnErrorIfMtypeIsNotValid() throws JsonProcessingException { // given final BidderCall httpCall = givenHttpCall( givenBidRequest( identity(), - builder -> builder.id("123") - .video(Video.builder().build()) - .banner(Banner.builder().build())), - mapper.writeValueAsString( - givenBidResponse(bidBuilder -> bidBuilder.impid("123")))); + impBuilder -> impBuilder.id("123").banner(Banner.builder().build()) + .video(Video.builder().build())), + givenBidResponse(bidBuilder -> bidBuilder.id("bidId").mtype(10).impid("123b__mf"))); // when final Result> result = target.makeBids(httpCall, null); // then - assertThat(result.getErrors()).isEmpty(); - assertThat(result.getValue()) - .containsExactly(BidderBid.of(Bid.builder().impid("123").build(), banner, "USD")); + assertThat(result.getErrors()) + .containsExactly(BidderError.badServerResponse("Unsupported MType 10")); + assertThat(result.getValue()).isEmpty(); } @SafeVarargs @@ -477,15 +427,16 @@ private static ObjectNode givenImpExt(Integer zoneId) { } @SafeVarargs - private static BidResponse givenBidResponse(UnaryOperator... bidCustomizers) { - return BidResponse.builder() + @SneakyThrows + private String givenBidResponse(UnaryOperator... bidCustomizers) { + return mapper.writeValueAsString(BidResponse.builder() .cur("USD") .seatbid(singletonList(SeatBid.builder() .bid(Arrays.stream(bidCustomizers) .map(bidCustomizer -> bidCustomizer.apply(Bid.builder()).build()) .toList()) .build())) - .build(); + .build()); } private static BidderCall givenHttpCall(BidRequest bidRequest, String body) { diff --git a/src/test/resources/org/prebid/server/it/openrtb2/adkernel/test-adkernel-bid-response.json b/src/test/resources/org/prebid/server/it/openrtb2/adkernel/test-adkernel-bid-response.json index d91df0ca089..03821c0471a 100644 --- a/src/test/resources/org/prebid/server/it/openrtb2/adkernel/test-adkernel-bid-response.json +++ b/src/test/resources/org/prebid/server/it/openrtb2/adkernel/test-adkernel-bid-response.json @@ -11,6 +11,7 @@ "crid": "2002", "adid": "2002", "adm": "", + "mtype": 1, "adomain": [ "tag-example.com" ] @@ -19,4 +20,4 @@ } ], "bidid": "bid_id" -} \ No newline at end of file +} diff --git a/src/test/resources/org/prebid/server/it/openrtb2/adkernel/test-auction-adkernel-response.json b/src/test/resources/org/prebid/server/it/openrtb2/adkernel/test-auction-adkernel-response.json index d6cfad2d245..92b00eb8c2b 100644 --- a/src/test/resources/org/prebid/server/it/openrtb2/adkernel/test-auction-adkernel-response.json +++ b/src/test/resources/org/prebid/server/it/openrtb2/adkernel/test-auction-adkernel-response.json @@ -14,6 +14,7 @@ ], "cid": "1001", "crid": "2002", + "mtype": 1, "ext": { "prebid": { "type": "banner"