Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Review deepintent adapter #1049

Merged
merged 2 commits into from
Dec 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package org.prebid.server.bidder.deepintent;

import com.fasterxml.jackson.core.type.TypeReference;
import com.iab.openrtb.request.Banner;
import com.iab.openrtb.request.BidRequest;
import com.iab.openrtb.request.Format;
import com.iab.openrtb.request.Imp;
import com.iab.openrtb.response.BidResponse;
import com.iab.openrtb.response.SeatBid;
Expand Down Expand Up @@ -55,8 +57,9 @@ public Result<List<HttpRequest<BidRequest>>> makeHttpRequests(BidRequest request

for (Imp imp : request.getImp()) {
try {
final Banner updatedBanner = buildImpBanner(imp.getBanner(), imp.getId());
final ExtImpDeepintent extImpDeepintent = parseImpExt(imp);
modifiedImps.add(modifyImp(imp, extImpDeepintent.getTagId()));
modifiedImps.add(modifyImp(imp, extImpDeepintent.getTagId(), updatedBanner));
} catch (PreBidException e) {
errors.add(BidderError.badInput(e.getMessage()));
}
Expand All @@ -69,16 +72,35 @@ public Result<List<HttpRequest<BidRequest>>> makeHttpRequests(BidRequest request
return Result.of(requests, errors);
}

private Banner buildImpBanner(Banner banner, String impId) {
if (banner == null) {
throw new PreBidException(String.format("We need a Banner Object in "
+ "the request, imp : %s", impId));
}

if (banner.getW() == null && banner.getH() == null) {
final List<Format> bannerFormats = banner.getFormat();
if (CollectionUtils.isEmpty(banner.getFormat())) {
throw new PreBidException(String.format("At least one size is required, imp : %s", impId));
}
final Format format = bannerFormats.get(0);
return banner.toBuilder().w(format.getW()).h(format.getH()).build();
}

return banner;
}

private ExtImpDeepintent parseImpExt(Imp imp) {
try {
return mapper.mapper().convertValue(imp.getExt(), DEEPINTENT_EXT_TYPE_REFERENCE).getBidder();
} catch (IllegalArgumentException e) {
throw new PreBidException(e.getMessage());
throw new PreBidException(String.format("Impression id=%s, has invalid Ext", imp.getId()));
}
}

private Imp modifyImp(Imp imp, String tagId) {
private Imp modifyImp(Imp imp, String tagId, Banner banner) {
return imp.toBuilder()
.banner(banner)
.tagid(tagId)
.displaymanager(DISPLAY_MANAGER)
.displaymanagerver(DISPLAY_MANAGER_VER)
Expand All @@ -102,20 +124,23 @@ private HttpRequest<BidRequest> createRequest(BidRequest request, Imp imp) {
@Override
public final Result<List<BidderBid>> makeBids(HttpCall<BidRequest> httpCall, BidRequest bidRequest) {
try {
final BidResponse bidResponse = mapper.decodeValue(httpCall.getResponse().getBody(), BidResponse.class);
return Result.of(extractBids(httpCall.getRequest().getPayload(), bidResponse), Collections.emptyList());
} catch (DecodeException e) {
return Result.withError(BidderError.badServerResponse(e.getMessage()));
return Result.of(extractBids(httpCall), Collections.emptyList());
} catch (PreBidException e) {
return Result.withError(BidderError.badInput(e.getMessage()));
return Result.withError(BidderError.badServerResponse(e.getMessage()));
}
}

private List<BidderBid> extractBids(BidRequest bidRequest, BidResponse bidResponse) {
private List<BidderBid> extractBids(HttpCall<BidRequest> httpCall) {
final BidResponse bidResponse;
try {
bidResponse = mapper.decodeValue(httpCall.getResponse().getBody(), BidResponse.class);
} catch (DecodeException e) {
throw new PreBidException(e.getMessage());
}
if (bidResponse == null || CollectionUtils.isEmpty(bidResponse.getSeatbid())) {
return Collections.emptyList();
}
return bidsFromResponse(bidRequest, bidResponse);
return bidsFromResponse(httpCall.getRequest().getPayload(), bidResponse);
}

private List<BidderBid> bidsFromResponse(BidRequest bidRequest, BidResponse bidResponse) {
Expand All @@ -131,9 +156,6 @@ private List<BidderBid> bidsFromResponse(BidRequest bidRequest, BidResponse bidR
private BidType getBidType(String impId, List<Imp> imps) {
for (Imp imp : imps) {
if (imp.getId().equals(impId)) {
if (imp.getVideo() != null && imp.getBanner() == null) {
return BidType.video;
}
return BidType.banner;
}
}
Expand Down
3 changes: 0 additions & 3 deletions src/main/resources/bidder-config/deepintent.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,12 @@ adapters:
maintainer-email: sourabh@deepintent.com
app-media-types:
- banner
- video
site-media-types:
- banner
- video
supported-vendors:
vendor-id: 541
usersync:
url: https://cdn.deepintent.com/syncpixel.html?gdpr={{gdpr}}&gdpr_consent={{gdpr_consent}}&us_privacy={{us_privacy}}&redir=
sd:
redirect-url: /setuid?bidder=deepintent&gdpr={{gdpr}}&gdpr_consent={{gdpr_consent}}&us_privacy={{us_privacy}}&uid=[uid]
cookie-family-name: deepintent
type: redirect
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import com.iab.openrtb.request.Banner;
import com.iab.openrtb.request.BidRequest;
import com.iab.openrtb.request.Format;
import com.iab.openrtb.request.Imp;
import com.iab.openrtb.request.Native;
import com.iab.openrtb.request.Video;
Expand Down Expand Up @@ -30,7 +31,6 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.prebid.server.proto.openrtb.ext.response.BidType.banner;
import static org.prebid.server.proto.openrtb.ext.response.BidType.video;

public class DeepintentBidderTest extends VertxTest {

Expand All @@ -56,18 +56,78 @@ public void creationShouldFailOnInvalidEndpointUrl() {
public void makeHttpRequestsShouldReturnErrorIfImpExtCouldNotBeParsed() {
// given
final BidRequest bidRequest = givenBidRequest(
impBuilder -> impBuilder.ext(mapper.valueToTree(ExtPrebid.of(null, mapper.createArrayNode()))));
impBuilder -> impBuilder
.id("impId")
.ext(mapper.valueToTree(ExtPrebid.of(null, mapper.createArrayNode()))));

// when
final Result<List<HttpRequest<BidRequest>>> result = deepintentBidder.makeHttpRequests(bidRequest);

// then
assertThat(result.getErrors()).hasSize(1);
assertThat(result.getErrors().get(0).getType()).isEqualTo(BidderError.Type.bad_input);
assertThat(result.getErrors()).allSatisfy(bidderError -> {
assertThat(bidderError.getType()).isEqualTo(BidderError.Type.bad_input);
assertThat(bidderError.getMessage()).isEqualTo("Impression id=impId, has invalid Ext");
});
}

@Test
public void shouldSetDislplayManagerAndVersionAndTagIdToRequestImp() {
public void makeHttpRequestsShouldReturnErrorIfImpBannerIsNull() {
// given
final BidRequest bidRequest = givenBidRequest(
impBuilder -> impBuilder.id("impId").banner(null));

// when
final Result<List<HttpRequest<BidRequest>>> result = deepintentBidder.makeHttpRequests(bidRequest);

// then
assertThat(result.getErrors()).hasSize(1);
assertThat(result.getErrors()).allSatisfy(bidderError -> {
assertThat(bidderError.getType()).isEqualTo(BidderError.Type.bad_input);
assertThat(bidderError.getMessage()).isEqualTo("We need a Banner Object in the request, imp : impId");
});
}

@Test
public void makeHttpRequestsShouldReturnErrorIfImpBannerHasNoSizeParametersPresent() {
// given
final BidRequest bidRequest = givenBidRequest(
impBuilder -> impBuilder.id("impId").banner(Banner.builder().build()));

// when
final Result<List<HttpRequest<BidRequest>>> result = deepintentBidder.makeHttpRequests(bidRequest);

// then
assertThat(result.getErrors()).hasSize(1);
assertThat(result.getErrors()).allSatisfy(bidderError -> {
assertThat(bidderError.getType()).isEqualTo(BidderError.Type.bad_input);
assertThat(bidderError.getMessage()).isEqualTo("At least one size is required, imp : impId");
});
}

@Test
public void makeHttpRequestsShouldSetMissedBannerSizeFromBannerFormat() {
// given
final BidRequest bidRequest = givenBidRequest(impBuilder -> impBuilder
.banner(Banner.builder().format(singletonList(Format.builder().w(77).h(88).build())).build()));

// when
final Result<List<HttpRequest<BidRequest>>> result = deepintentBidder.makeHttpRequests(bidRequest);

// then
assertThat(result.getErrors()).hasSize(0);
final Imp expectedImp = expectedImp(impBuilder -> impBuilder
.banner(Banner.builder().w(77).h(88)
.format(singletonList(Format.builder().w(77).h(88).build()))
.build()));
assertThat(result.getValue())
.extracting(HttpRequest::getPayload)
.flatExtracting(BidRequest::getImp)
.containsExactly(expectedImp);
}

@Test
public void makeHttpRequestsShouldSetDislplayManagerAndVersionAndTagIdToRequestImp() {
// given
final BidRequest bidRequest = givenBidRequest(identity());

Expand All @@ -76,12 +136,7 @@ public void shouldSetDislplayManagerAndVersionAndTagIdToRequestImp() {

// then
assertThat(result.getErrors()).hasSize(0);
final Imp expectedImp = Imp.builder()
.displaymanager(DISPLAY_MANAGER)
.displaymanagerver(DISPLAY_MANAGER_VERSION)
.tagid(IMP_EXT_TAG_ID)
.ext(mapper.valueToTree(ExtPrebid.of(null, ExtImpDeepintent.of(IMP_EXT_TAG_ID))))
.build();
final Imp expectedImp = expectedImp(identity());
assertThat(result.getValue())
.extracting(HttpRequest::getPayload)
.flatExtracting(BidRequest::getImp)
Expand All @@ -92,6 +147,7 @@ public void shouldSetDislplayManagerAndVersionAndTagIdToRequestImp() {
public void makeRequestShouldCreateRequestForEveryValidImp() {
// given
final Imp firstImp = Imp.builder()
.banner(Banner.builder().w(23).h(25).build())
.ext(mapper.valueToTree(ExtPrebid.of(null, ExtImpDeepintent.of(IMP_EXT_TAG_ID))))
.build();
final Imp secondImp = Imp.builder()
Expand All @@ -106,11 +162,7 @@ public void makeRequestShouldCreateRequestForEveryValidImp() {

// then
assertThat(result.getErrors()).hasSize(1);
final Imp expectedFirstImp = firstImp.toBuilder()
.displaymanager(DISPLAY_MANAGER)
.displaymanagerver(DISPLAY_MANAGER_VERSION)
.tagid(IMP_EXT_TAG_ID)
.build();
final Imp expectedFirstImp = expectedImp(identity());

assertThat(result.getValue())
.hasSize(1)
Expand All @@ -122,12 +174,11 @@ public void makeRequestShouldCreateRequestForEveryValidImp() {
@Test
public void makeRequestShouldCreateSeparateRequestForEveryImp() {
// given
final Imp firstImp = Imp.builder()
.ext(mapper.valueToTree(ExtPrebid.of(null, ExtImpDeepintent.of("firstImpTagId"))))
.build();
final Imp secondImp = Imp.builder()
.ext(mapper.valueToTree(ExtPrebid.of(null, ExtImpDeepintent.of("secondImpTagId"))))
.build();
final Imp firstImp = givenImp(impBuilder ->
impBuilder.ext(mapper.valueToTree(ExtPrebid.of(null, ExtImpDeepintent.of("firstImpTagId")))));
final Imp secondImp = givenImp(impBuilder ->
impBuilder.ext(mapper.valueToTree(ExtPrebid.of(null, ExtImpDeepintent.of("secondImpTagId")))));

final BidRequest bidRequest = BidRequest.builder()
.imp(Arrays.asList(firstImp, secondImp))
.build();
Expand All @@ -137,16 +188,17 @@ public void makeRequestShouldCreateSeparateRequestForEveryImp() {

// then
assertThat(result.getErrors()).hasSize(0);
final Imp expectedFirstImp = firstImp.toBuilder()
.displaymanager(DISPLAY_MANAGER)
.displaymanagerver(DISPLAY_MANAGER_VERSION)
.tagid("firstImpTagId")
.build();
final Imp expectedSecondImp = secondImp.toBuilder()
.displaymanager(DISPLAY_MANAGER)
.displaymanagerver(DISPLAY_MANAGER_VERSION)
.tagid("secondImpTagId")
.build();
final Imp expectedFirstImp =
expectedImp(impBuilder ->
impBuilder.ext(mapper.valueToTree(
ExtPrebid.of(null, ExtImpDeepintent.of("firstImpTagId"))))
.tagid("firstImpTagId"));

final Imp expectedSecondImp =
expectedImp(impBuilder ->
impBuilder.ext(mapper.valueToTree(
ExtPrebid.of(null, ExtImpDeepintent.of("secondImpTagId"))))
.tagid("secondImpTagId"));

assertThat(result.getValue())
.hasSize(2)
Expand All @@ -165,10 +217,10 @@ public void makeBidsShouldReturnErrorIfResponseBodyCouldNotBeParsed() {

// then
assertThat(result.getErrors()).hasSize(1);
assertThat(result.getErrors().get(0).getMessage()).startsWith("Failed to decode: Unrecognized token");
assertThat(result.getErrors())
.extracting(BidderError::getType)
.containsExactly(BidderError.Type.bad_server_response);
assertThat(result.getErrors()).allSatisfy(error -> {
assertThat(error.getMessage()).contains("Failed to decode: Unrecognized token");
assertThat(error.getType()).isEqualTo(BidderError.Type.bad_server_response);
});
assertThat(result.getValue()).isEmpty();
}

Expand Down Expand Up @@ -200,43 +252,6 @@ public void makeBidsShouldReturnEmptyListIfBidResponseSeatBidIsNull() throws Jso
assertThat(result.getValue()).isEmpty();
}

@Test
public void makeBidsShouldReturnBannerBidIfBannerIsPresentInRequestImp() throws JsonProcessingException {
// given
final HttpCall<BidRequest> httpCall = givenHttpCall(
BidRequest.builder()
.imp(singletonList(Imp.builder().id("123").banner(Banner.builder().build()).build()))
.build(),
mapper.writeValueAsString(
givenBidResponse(bidBuilder -> bidBuilder.impid("123"))));

// when
final Result<List<BidderBid>> result = deepintentBidder.makeBids(httpCall, null);

// then
assertThat(result.getErrors()).isEmpty();
assertThat(result.getValue())
.containsOnly(BidderBid.of(Bid.builder().impid("123").build(), banner, CURRENCY));
}

@Test
public void makeBidsShouldReturnVideoBidIfVideoIsPresentInRequestImp() throws JsonProcessingException {
// given
final HttpCall<BidRequest> httpCall = givenHttpCall(BidRequest.builder()
.imp(singletonList(Imp.builder().id("123").video(Video.builder().build()).build()))
.build(),
mapper.writeValueAsString(
givenBidResponse(bidBuilder -> bidBuilder.impid("123"))));

// when
final Result<List<BidderBid>> result = deepintentBidder.makeBids(httpCall, null);

// then
assertThat(result.getErrors()).isEmpty();
assertThat(result.getValue())
.containsOnly(BidderBid.of(Bid.builder().impid("123").build(), video, CURRENCY));
}

@Test
public void shouldReturnErrorIfBidImpIdNotFoundInImps() throws JsonProcessingException {
// given
Expand All @@ -251,7 +266,7 @@ public void shouldReturnErrorIfBidImpIdNotFoundInImps() throws JsonProcessingExc

// then
assertThat(result.getErrors())
.containsExactly(BidderError.badInput("Failed to find impression with id: notFoundId"));
.containsExactly(BidderError.badServerResponse("Failed to find impression with id: notFoundId"));
}

@Test
Expand Down Expand Up @@ -288,6 +303,17 @@ private static BidRequest givenBidRequest(Function<Imp.ImpBuilder, Imp.ImpBuilde

private static Imp givenImp(Function<Imp.ImpBuilder, Imp.ImpBuilder> impCustomizer) {
return impCustomizer.apply(Imp.builder()
.banner(Banner.builder().w(23).h(25).build())
.ext(mapper.valueToTree(ExtPrebid.of(null, ExtImpDeepintent.of(IMP_EXT_TAG_ID)))))
.build();
}

private Imp expectedImp(Function<Imp.ImpBuilder, Imp.ImpBuilder> impCustomizer) {
return impCustomizer.apply(Imp.builder()
.banner(Banner.builder().w(23).h(25).build())
.displaymanager(DISPLAY_MANAGER)
.displaymanagerver(DISPLAY_MANAGER_VERSION)
.tagid(IMP_EXT_TAG_ID)
.ext(mapper.valueToTree(ExtPrebid.of(null, ExtImpDeepintent.of(IMP_EXT_TAG_ID)))))
.build();
}
Expand Down