Skip to content

Commit 7cf2464

Browse files
fix tests
1 parent 2e1b6a5 commit 7cf2464

6 files changed

Lines changed: 166 additions & 30 deletions

File tree

src/main/java/org/prebid/server/bidder/showheroes/ShowheroesBidder.java

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
package org.prebid.server.bidder.showheroes;
22

33
import com.fasterxml.jackson.core.type.TypeReference;
4+
import com.fasterxml.jackson.databind.JsonNode;
45
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
56
import com.fasterxml.jackson.databind.node.ObjectNode;
6-
import com.iab.openrtb.request.Banner;
77
import com.iab.openrtb.request.BidRequest;
88
import com.iab.openrtb.request.Imp;
9-
import com.iab.openrtb.request.Video;
9+
import com.iab.openrtb.request.Source;
1010
import com.iab.openrtb.response.Bid;
1111
import com.iab.openrtb.response.BidResponse;
1212
import com.iab.openrtb.response.SeatBid;
@@ -25,6 +25,7 @@
2525
import org.prebid.server.proto.openrtb.ext.request.ExtRequest;
2626
import org.prebid.server.proto.openrtb.ext.request.ExtRequestPrebid;
2727
import org.prebid.server.proto.openrtb.ext.request.ExtRequestPrebidChannel;
28+
import org.prebid.server.proto.openrtb.ext.request.ExtSource;
2829
import org.prebid.server.proto.openrtb.ext.request.showheroes.ExtImpShowheroes;
2930
import org.prebid.server.proto.openrtb.ext.response.BidType;
3031
import org.prebid.server.util.BidderUtil;
@@ -43,22 +44,26 @@ public class ShowheroesBidder implements Bidder<BidRequest> {
4344

4445
private static final String BID_CURRENCY = "EUR";
4546
private static final String DEFAULT_ORTB_CURRENCY = "USD";
47+
private static final String PBSP_JAVA = "java";
4648
private static final TypeReference<ExtPrebid<?, ExtImpShowheroes>> SHOWHEROES_EXT_TYPE_REFERENCE =
4749
new TypeReference<>() {
4850
};
4951

5052
private final String endpointUrl;
5153
private final CurrencyConversionService currencyConversionService;
5254
private final JacksonMapper mapper;
55+
private final String pbsVersion;
5356

5457
public ShowheroesBidder(String endpointUrl,
5558
CurrencyConversionService currencyConversionService,
5659
PrebidVersionProvider prebidVersionProvider,
5760
JacksonMapper mapper) {
5861

59-
this.endpointUrl = HttpUtil.validateUrlSyntax(Objects.requireNonNull(endpointUrl));
62+
this.endpointUrl = HttpUtil.validateUrl(Objects.requireNonNull(endpointUrl));
6063
this.currencyConversionService = Objects.requireNonNull(currencyConversionService);
6164
this.mapper = Objects.requireNonNull(mapper);
65+
66+
this.pbsVersion = prebidVersionProvider.getNameVersionRecord();
6267
}
6368

6469
private BidderError validate(BidRequest bidRequest) {
@@ -83,17 +88,15 @@ private ExtRequestPrebidChannel getPrebidChannel(BidRequest bidRequest) {
8388
}
8489

8590
private Imp processImpression(BidRequest bidRequest, Imp imp, ExtRequestPrebidChannel prebidChannel) {
86-
final Banner banner = imp.getBanner();
87-
final Video video = imp.getVideo();
88-
if (banner == null && video == null) {
89-
throw new PreBidException("Impression must contain one of banner, video or native");
91+
if (imp.getBanner() == null && imp.getVideo() == null) {
92+
throw new PreBidException("Impression must contain one of banner or video");
9093
}
9194

9295
final ExtImpShowheroes extImpShowheroes = mapper.mapper()
9396
.convertValue(imp.getExt(), SHOWHEROES_EXT_TYPE_REFERENCE).getBidder();
9497
if (extImpShowheroes == null || extImpShowheroes.getUnitId() == null
9598
|| extImpShowheroes.getUnitId().isBlank()) {
96-
throw new PreBidException("Ext.imp.bidder.unitId is required");
99+
throw new PreBidException("unitId is required");
97100
}
98101

99102
String channelName = null;
@@ -136,6 +139,29 @@ private Imp processImpression(BidRequest bidRequest, Imp imp, ExtRequestPrebidCh
136139
.build();
137140
}
138141

142+
private Source getPBSSource(BidRequest bidRequest) {
143+
Source source = bidRequest.getSource();
144+
if (source == null) {
145+
source = Source.builder().build();
146+
}
147+
148+
ExtSource extSource = source.getExt();
149+
if (extSource == null) {
150+
extSource = ExtSource.of(null);
151+
}
152+
153+
JsonNode prebidExt = extSource.getProperty("pbs");
154+
if (prebidExt == null || !prebidExt.isObject()) {
155+
prebidExt = mapper.mapper().createObjectNode();
156+
}
157+
158+
((ObjectNode) prebidExt).put("pbsv", pbsVersion).put("pbsp", PBSP_JAVA);
159+
160+
extSource.addProperty("pbs", prebidExt);
161+
162+
return source.toBuilder().ext(extSource).build();
163+
}
164+
139165
@Override
140166
public Result<List<HttpRequest<BidRequest>>> makeHttpRequests(BidRequest request) {
141167
final BidderError validationError = validate(request);
@@ -158,7 +184,15 @@ public Result<List<HttpRequest<BidRequest>>> makeHttpRequests(BidRequest request
158184
}
159185
}
160186

161-
httpRequests.add(makeHttpRequest(request.toBuilder().imp(modifiedImps).build()));
187+
if (modifiedImps.isEmpty()) {
188+
return Result.of(httpRequests, errors);
189+
}
190+
Source source = request.getSource();
191+
if (pbsVersion != null) {
192+
source = getPBSSource(request);
193+
}
194+
195+
httpRequests.add(makeHttpRequest(request.toBuilder().imp(modifiedImps).source(source).build()));
162196
return Result.of(httpRequests, errors);
163197
}
164198

@@ -207,7 +241,7 @@ private BidType getBidType(Bid bid) {
207241
return switch (bid.getMtype()) {
208242
case 1 -> BidType.banner;
209243
case 2 -> BidType.video;
210-
default -> BidType.video; // if not provided video is assumed
244+
case null, default -> BidType.video; // if not provided video is assumed
211245
};
212246
}
213247
}

src/test/java/org/prebid/server/bidder/showheroes/ShowheroesBidderTest.java

Lines changed: 107 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,39 @@
77
import com.iab.openrtb.request.Imp;
88
import com.iab.openrtb.request.Site;
99
import com.iab.openrtb.request.Video;
10+
import com.iab.openrtb.request.Source;
1011
import com.iab.openrtb.response.Bid;
1112
import com.iab.openrtb.response.BidResponse;
1213
import com.iab.openrtb.response.SeatBid;
14+
import org.junit.jupiter.api.BeforeEach;
1315
import org.junit.jupiter.api.Test;
16+
import org.junit.jupiter.api.extension.ExtendWith;
17+
import org.mockito.Mock;
18+
import org.mockito.junit.jupiter.MockitoExtension;
1419
import org.prebid.server.VertxTest;
1520
import org.prebid.server.bidder.model.BidderBid;
1621
import org.prebid.server.bidder.model.BidderCall;
1722
import org.prebid.server.bidder.model.BidderError;
1823
import org.prebid.server.bidder.model.HttpRequest;
1924
import org.prebid.server.bidder.model.HttpResponse;
2025
import org.prebid.server.bidder.model.Result;
26+
import org.prebid.server.currency.CurrencyConversionService;
2127
import org.prebid.server.proto.openrtb.ext.ExtPrebid;
2228
import org.prebid.server.proto.openrtb.ext.request.showheroes.ExtImpShowheroes;
29+
import org.prebid.server.version.PrebidVersionProvider;
2330

2431
import java.math.BigDecimal;
2532
import java.util.List;
2633
import java.util.Map;
2734
import java.util.function.Function;
2835

36+
import static org.mockito.ArgumentMatchers.any;
37+
import static org.mockito.ArgumentMatchers.anyString;
38+
import static org.mockito.ArgumentMatchers.eq;
39+
import static org.mockito.Mock.Strictness.LENIENT;
40+
import static org.mockito.Mockito.never;
41+
import static org.mockito.Mockito.verify;
42+
import static org.mockito.BDDMockito.given;
2943
import static java.util.Collections.singletonList;
3044
import static java.util.function.Function.identity;
3145
import static org.assertj.core.api.Assertions.assertThat;
@@ -34,15 +48,30 @@
3448
import static org.prebid.server.proto.openrtb.ext.response.BidType.banner;
3549
import static org.prebid.server.proto.openrtb.ext.response.BidType.video;
3650

51+
@ExtendWith(MockitoExtension.class)
3752
public class ShowheroesBidderTest extends VertxTest {
3853

3954
private static final String ENDPOINT_URL = "https://ads.showheroes.com/";
4055

41-
private final ShowheroesBidder target = new ShowheroesBidder(ENDPOINT_URL, jacksonMapper);
56+
private ShowheroesBidder target;
57+
58+
@Mock(strictness = LENIENT)
59+
private CurrencyConversionService currencyConversionService;
60+
61+
@Mock(strictness = LENIENT)
62+
private PrebidVersionProvider prebidVersionProvider;
63+
64+
@BeforeEach
65+
public void setUp() {
66+
// set always 'test_version' as Prebid version for testing
67+
given(prebidVersionProvider.getNameVersionRecord()).willReturn("test_version");
68+
target = new ShowheroesBidder(ENDPOINT_URL, currencyConversionService, prebidVersionProvider, jacksonMapper);
69+
}
4270

4371
@Test
4472
public void creationShouldFailOnInvalidEndpointUrl() {
45-
assertThatIllegalArgumentException().isThrownBy(() -> new ShowheroesBidder("invalid_url", jacksonMapper));
73+
assertThatIllegalArgumentException().isThrownBy(() -> new ShowheroesBidder("invalid_url",
74+
currencyConversionService, prebidVersionProvider, jacksonMapper));
4675
}
4776

4877
@Test
@@ -74,26 +103,39 @@ public void makeHttpRequestsShouldReturnErrorWhenUnitIdIsEmpty() {
74103
// then
75104
assertThat(result.getErrors()).hasSize(1)
76105
.extracting(BidderError::getMessage)
77-
.containsExactly("unitId parameter is required");
106+
.containsExactly("unitId is required");
78107
assertThat(result.getValue()).isEmpty();
79108
}
80109

81110
@Test
82-
public void makeHttpRequestsShouldReturnErrorWhenSitePageAndAppBundleAreEmpty() {
111+
public void makeHttpRequestsShouldReturnErrorWhenSitePageIsEmpty() {
83112
// given
84113
final BidRequest bidRequest = BidRequest.builder()
85114
.imp(singletonList(givenImp(identity())))
86-
.site(Site.builder().page("").build())
87-
.app(App.builder().bundle("").build())
115+
.site(Site.builder().build())
88116
.build();
89117

90118
// when
91119
final Result<List<HttpRequest<BidRequest>>> result = target.makeHttpRequests(bidRequest);
92120

93121
// then
94-
assertThat(result.getErrors()).hasSize(1)
95-
.extracting(BidderError::getMessage)
96-
.containsExactly("site.page or app.bundle is required");
122+
assertThat(result.getErrors()).hasSize(1);
123+
assertThat(result.getValue()).isEmpty();
124+
}
125+
126+
@Test
127+
public void makeHttpRequestsShouldReturnErrorWhenAppBundleIsEmpty() {
128+
// given
129+
final BidRequest bidRequest = BidRequest.builder()
130+
.imp(singletonList(givenImp(identity())))
131+
.app(App.builder().build())
132+
.build();
133+
134+
// when
135+
final Result<List<HttpRequest<BidRequest>>> result = target.makeHttpRequests(bidRequest);
136+
137+
// then
138+
assertThat(result.getErrors()).hasSize(1);
97139
assertThat(result.getValue()).isEmpty();
98140
}
99141

@@ -112,19 +154,68 @@ public void makeHttpRequestsShouldCreateCorrectURL() {
112154
}
113155

114156
@Test
115-
public void makeHttpRequestsShouldConvertCurrencyFromUsdToEur() {
116-
// given
157+
public void makeHttpRequestsShouldReturnPbsVersion() {
117158
final BidRequest bidRequest = givenBidRequest(identity());
118159

119160
// when
120161
final Result<List<HttpRequest<BidRequest>>> result = target.makeHttpRequests(bidRequest);
121162

122163
// then
123164
assertThat(result.getErrors()).isEmpty();
124-
assertThat(result.getValue()).hasSize(1);
165+
assertThat(result.getValue())
166+
.extracting(HttpRequest::getPayload)
167+
.extracting(BidRequest::getSource)
168+
.extracting(Source::getExt)
169+
.extracting(ext -> ext.getProperty("pbs"))
170+
.containsExactly(mapper.createObjectNode()
171+
.put("pbsv", "test_version")
172+
.put("pbsp", "java"));
173+
}
125174

126-
final BidRequest outgoingRequest = result.getValue().get(0).getPayload();
127-
assertThat(outgoingRequest.getCur()).containsExactly("EUR");
175+
@Test
176+
public void makeHttpRequestsShouldConvertCurrencyFromUsdToEur() {
177+
final BidRequest bidRequest = BidRequest.builder()
178+
.imp(List.of(givenImp(impBuilder -> impBuilder.bidfloor(BigDecimal.ONE).bidfloorcur("USD"))))
179+
.app(App.builder().bundle("test_bundle").build())
180+
.build();
181+
182+
given(currencyConversionService.convertCurrency(any(), any(), anyString(), anyString()))
183+
.willReturn(BigDecimal.TEN);
184+
185+
// when
186+
final Result<List<HttpRequest<BidRequest>>> result = target.makeHttpRequests(bidRequest);
187+
188+
// then
189+
assertThat(result.getErrors()).isEmpty();
190+
verify(currencyConversionService).convertCurrency(eq(BigDecimal.ONE), any(), eq("USD"), eq("EUR"));
191+
assertThat(result.getValue()).hasSize(1).doesNotContainNull()
192+
.extracting(httpRequest -> mapper.readValue(httpRequest.getBody(), BidRequest.class))
193+
.flatExtracting(BidRequest::getImp).doesNotContainNull()
194+
.extracting(Imp::getBidfloor, Imp::getBidfloorcur)
195+
.containsOnly(tuple(BigDecimal.TEN, "EUR"));
196+
}
197+
198+
@Test
199+
public void makeHttpRequestsShouldNotConvertCurrencyEur() {
200+
final BidRequest bidRequest = BidRequest.builder()
201+
.imp(List.of(givenImp(impBuilder -> impBuilder.bidfloor(BigDecimal.ONE).bidfloorcur("EUR"))))
202+
.app(App.builder().bundle("test_bundle").build())
203+
.build();
204+
205+
given(currencyConversionService.convertCurrency(any(), any(), anyString(), anyString()))
206+
.willReturn(BigDecimal.TEN);
207+
208+
// when
209+
final Result<List<HttpRequest<BidRequest>>> result = target.makeHttpRequests(bidRequest);
210+
211+
// then
212+
assertThat(result.getErrors()).isEmpty();
213+
verify(currencyConversionService, never()).convertCurrency(any(), any(), anyString(), anyString());
214+
assertThat(result.getValue()).hasSize(1).doesNotContainNull()
215+
.extracting(httpRequest -> mapper.readValue(httpRequest.getBody(), BidRequest.class))
216+
.flatExtracting(BidRequest::getImp).doesNotContainNull()
217+
.extracting(Imp::getBidfloor, Imp::getBidfloorcur)
218+
.containsOnly(tuple(BigDecimal.ONE, "EUR"));
128219
}
129220

130221
@Test
@@ -162,7 +253,8 @@ public void makeHttpRequestsShouldSetCorrectHeaders() {
162253
assertThat(result.getErrors()).isEmpty();
163254
assertThat(result.getValue()).hasSize(1);
164255

165-
final Map<String, String> headers = result.getValue().get(0).getHeaders();
256+
final Map<String, String> headers = result.getValue().get(0).getHeaders().entries().stream()
257+
.collect(java.util.stream.Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
166258
assertThat(headers).containsEntry("Content-Type", "application/json;charset=utf-8")
167259
.containsEntry("Accept", "application/json");
168260
}

src/test/resources/org/prebid/server/it/openrtb2/showheroes/test-auction-showheroes-response.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"adid": "adid",
1212
"cid": "cid",
1313
"crid": "crid",
14+
"mtype": 1,
1415
"ext": {
1516
"prebid": {
1617
"type": "banner",

src/test/resources/org/prebid/server/it/openrtb2/showheroes/test-showheroes-bid-request.json

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@
1212
"ext": {
1313
"tid": "${json-unit.any-string}",
1414
"bidder": {
15-
"unitId": "1234"
15+
"unitId": "12345"
16+
},
17+
"params": {
18+
"unitId": "12345"
1619
}
1720
}
1821
}
@@ -33,12 +36,14 @@
3336
},
3437
"at": 1,
3538
"tmax": "${json-unit.any-number}",
36-
"cur": ["EUR"],
39+
"cur": ["USD"],
3740
"source": {
3841
"tid": "${json-unit.any-string}",
3942
"ext": {
40-
"str": "10.0",
41-
"version": "{{ pbs.java.version }}"
43+
"pbs": {
44+
"pbsv": "{{ pbs.java.version }}",
45+
"pbsp": "java"
46+
}
4247
}
4348
},
4449
"regs": {

src/test/resources/org/prebid/server/it/openrtb2/showheroes/test-showheroes-bid-response.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"id": "bid_id",
1111
"impid": "imp_id",
1212
"cid": "cid",
13+
"mtype": 1,
1314
"ext": {
1415
"prebid": {
1516
"type": "banner"
@@ -19,5 +20,6 @@
1920
],
2021
"type": "banner"
2122
}
22-
]
23+
],
24+
"cur": "USD"
2325
}

src/test/resources/org/prebid/server/it/test-application.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,8 @@ adapters.sspbc.enabled=true
539539
adapters.sspbc.endpoint=http://localhost:8090/sspbc-exchange
540540
adapters.sharethrough.enabled=true
541541
adapters.sharethrough.endpoint=http://localhost:8090/sharethrough-exchange
542+
adapters.showheroes.enabled=true
543+
adapters.showheroes.endpoint=http://localhost:8090/showheroes-exchange
542544
adapters.silvermob.enabled=true
543545
adapters.silvermob.endpoint=http://localhost:8090/silvermob-exchange
544546
adapters.silverpush.enabled=true

0 commit comments

Comments
 (0)