1717import org .prebid .server .bidder .model .HttpRequest ;
1818import org .prebid .server .bidder .model .HttpResponse ;
1919import org .prebid .server .bidder .model .Result ;
20+ import org .prebid .server .proto .openrtb .ext .ExtPrebid ;
21+ import org .prebid .server .proto .openrtb .ext .request .smilewanted .ExtImpSmilewanted ;
2022import org .prebid .server .util .HttpUtil ;
2123
24+ import java .math .BigDecimal ;
25+ import java .util .Arrays ;
2226import java .util .List ;
2327import java .util .Map ;
2428import java .util .function .Function ;
3236
3337public class SmileWantedBidderTest extends VertxTest {
3438
35- private static final String ENDPOINT_URL = "https://{{Host}}/test?param={{PublisherId }}" ;
39+ private static final String ENDPOINT_URL = "https://prebid-server.smilewanted.com/java/{{ZoneId }}" ;
3640
3741 private final SmileWantedBidder target = new SmileWantedBidder (ENDPOINT_URL , jacksonMapper );
3842
@@ -41,10 +45,76 @@ public void creationShouldFailOnInvalidEndpointUrl() {
4145 assertThatIllegalArgumentException ().isThrownBy (() -> new SmileWantedBidder ("invalid_url" , jacksonMapper ));
4246 }
4347
48+ @ Test
49+ public void makeHttpRequestsShouldReturnErrorIfImpExtCouldNotBeParsed () {
50+ // given
51+ final BidRequest bidRequest = BidRequest .builder ()
52+ .imp (singletonList (Imp .builder ()
53+ .id ("123" )
54+ .ext (mapper .valueToTree (ExtPrebid .of (null , mapper .createArrayNode ())))
55+ .build ()))
56+ .build ();
57+
58+ // when
59+ final Result <List <HttpRequest <BidRequest >>> result = target .makeHttpRequests (bidRequest );
60+
61+ // then
62+ assertThat (result .getValue ()).isEmpty ();
63+ assertThat (result .getErrors ()).hasSize (1 )
64+ .allSatisfy (error -> {
65+ assertThat (error .getType ()).isEqualTo (BidderError .Type .bad_input );
66+ assertThat (error .getMessage ()).startsWith ("Missing bidder ext in impression with id: 123" );
67+ });
68+ }
69+
70+ @ Test
71+ public void makeHttpRequestsShouldReturnSingleRequest () {
72+ // given
73+ final BidRequest bidRequest = BidRequest .builder ()
74+ .imp (List .of (
75+ givenImp ("zone123" ),
76+ Imp .builder ()
77+ .id ("456" )
78+ .ext (mapper .valueToTree (ExtPrebid .of (null , ExtImpSmilewanted .of ("zone123" ))))
79+ .build ()))
80+ .build ();
81+
82+ // when
83+ final Result <List <HttpRequest <BidRequest >>> result = target .makeHttpRequests (bidRequest );
84+
85+ // then
86+ assertThat (result .getErrors ()).isEmpty ();
87+ assertThat (result .getValue ()).hasSize (1 );
88+ final HttpRequest <BidRequest > httpRequest = result .getValue ().get (0 );
89+ assertThat (httpRequest .getPayload ()).isNotNull ();
90+ assertThat (httpRequest .getPayload ().getImp ()).hasSize (2 );
91+ assertThat (httpRequest .getPayload ().getAt ()).isEqualTo (1 );
92+ assertThat (httpRequest .getImpIds ()).containsExactlyInAnyOrder ("123" , "456" );
93+ }
94+
95+ @ Test
96+ public void makeHttpRequestsShouldBuildCorrectEndpointUrlWithZoneId () {
97+ // given
98+ final BidRequest bidRequest = BidRequest .builder ()
99+ .imp (singletonList (givenImp ("zone456" )))
100+ .build ();
101+
102+ // when
103+ final Result <List <HttpRequest <BidRequest >>> result = target .makeHttpRequests (bidRequest );
104+
105+ // then
106+ assertThat (result .getErrors ()).isEmpty ();
107+ assertThat (result .getValue ())
108+ .extracting (HttpRequest ::getUri )
109+ .containsExactly ("https://prebid-server.smilewanted.com/java/zone456" );
110+ }
111+
44112 @ Test
45113 public void makeHttpRequestsShouldCorrectlyAddHeaders () {
46114 // given
47- final BidRequest bidRequest = BidRequest .builder ().build ();
115+ final BidRequest bidRequest = BidRequest .builder ()
116+ .imp (singletonList (givenImp ("zone123" )))
117+ .build ();
48118
49119 // when
50120 final Result <List <HttpRequest <BidRequest >>> result = target .makeHttpRequests (bidRequest );
@@ -65,7 +135,9 @@ public void makeHttpRequestsShouldCorrectlyAddHeaders() {
65135 @ Test
66136 public void makeHttpRequestsShouldSetAtToOne () {
67137 // given
68- final BidRequest bidRequest = BidRequest .builder ().build ();
138+ final BidRequest bidRequest = BidRequest .builder ()
139+ .imp (singletonList (givenImp ("zone123" )))
140+ .build ();
69141
70142 // when
71143 final Result <List <HttpRequest <BidRequest >>> result = target .makeHttpRequests (bidRequest );
@@ -98,7 +170,7 @@ public void makeBidsShouldReturnErrorIfResponseBodyCouldNotBeParsed() {
98170 @ Test
99171 public void makeBidsShouldReturnEmptyListIfBidResponseIsNull () throws JsonProcessingException {
100172 // given
101- final BidderCall <BidRequest > httpCall = givenHttpCall (null , mapper . writeValueAsString ( null ) );
173+ final BidderCall <BidRequest > httpCall = givenHttpCall (null , ( BidResponse ) null );
102174
103175 // when
104176 final Result <List <BidderBid >> result = target .makeBids (httpCall , null );
@@ -111,8 +183,7 @@ public void makeBidsShouldReturnEmptyListIfBidResponseIsNull() throws JsonProces
111183 @ Test
112184 public void makeBidsShouldReturnEmptyListIfBidResponseSeatBidIsNull () throws JsonProcessingException {
113185 // given
114- final BidderCall <BidRequest > httpCall = givenHttpCall (null ,
115- mapper .writeValueAsString (BidResponse .builder ().build ()));
186+ final BidderCall <BidRequest > httpCall = givenHttpCall (null , BidResponse .builder ().build ());
116187
117188 // when
118189 final Result <List <BidderBid >> result = target .makeBids (httpCall , null );
@@ -130,8 +201,7 @@ public void makeBidsShouldReturnVideoBidIfVideoIsPresentInRequestImpAndCorrespon
130201 BidRequest .builder ()
131202 .imp (singletonList (Imp .builder ().id ("123" ).video (Video .builder ().build ()).build ()))
132203 .build (),
133- mapper .writeValueAsString (
134- givenBidResponse (bidBuilder -> bidBuilder .impid ("123" ))));
204+ givenBidResponse (bidBuilder -> bidBuilder .impid ("123" )));
135205
136206 // when
137207 final Result <List <BidderBid >> result = target .makeBids (httpCall , null );
@@ -148,8 +218,7 @@ public void makeBidsShouldReturnBannerBidIfVideoIsAbsentInRequestImp() throws Js
148218 final BidderCall <BidRequest > httpCall = givenHttpCall (BidRequest .builder ()
149219 .imp (singletonList (Imp .builder ().id ("123" ).build ()))
150220 .build (),
151- mapper .writeValueAsString (
152- givenBidResponse (bidBuilder -> bidBuilder .impid ("123" ))));
221+ givenBidResponse (bidBuilder -> bidBuilder .impid ("123" )));
153222
154223 // when
155224 final Result <List <BidderBid >> result = target .makeBids (httpCall , null );
@@ -160,6 +229,102 @@ public void makeBidsShouldReturnBannerBidIfVideoIsAbsentInRequestImp() throws Js
160229 .containsOnly (BidderBid .of (Bid .builder ().impid ("123" ).build (), banner , null ));
161230 }
162231
232+ @ Test
233+ public void makeBidsShouldReturnMultipleBidsFromSingleSeatBid () throws JsonProcessingException {
234+ // given
235+ final BidderCall <BidRequest > httpCall = givenHttpCall (
236+ BidRequest .builder ()
237+ .imp (List .of (
238+ Imp .builder ().id ("123" ).build (),
239+ Imp .builder ().id ("456" ).video (Video .builder ().build ()).build ()))
240+ .build (),
241+ BidResponse .builder ()
242+ .cur ("USD" )
243+ .seatbid (singletonList (SeatBid .builder ()
244+ .bid (List .of (
245+ Bid .builder ().impid ("123" ).price (BigDecimal .valueOf (1.0 )).build (),
246+ Bid .builder ().impid ("456" ).price (BigDecimal .valueOf (2.0 )).build ()))
247+ .build ()))
248+ .build ());
249+
250+ // when
251+ final Result <List <BidderBid >> result = target .makeBids (httpCall , null );
252+
253+ // then
254+ assertThat (result .getErrors ()).isEmpty ();
255+ assertThat (result .getValue ()).hasSize (2 )
256+ .containsExactlyInAnyOrder (
257+ BidderBid .of (Bid .builder ().impid ("123" ).price (BigDecimal .valueOf (1.0 )).build (), banner , "USD" ),
258+ BidderBid .of (Bid .builder ().impid ("456" ).price (BigDecimal .valueOf (2.0 )).build (), video , "USD" ));
259+ }
260+
261+ @ Test
262+ public void makeBidsShouldFilterNullBids () throws JsonProcessingException {
263+ // given
264+ final BidderCall <BidRequest > httpCall = givenHttpCall (
265+ BidRequest .builder ()
266+ .imp (singletonList (Imp .builder ().id ("123" ).build ()))
267+ .build (),
268+ BidResponse .builder ()
269+ .seatbid (singletonList (SeatBid .builder ()
270+ .bid (Arrays .asList (
271+ Bid .builder ().impid ("123" ).build (),
272+ null ,
273+ Bid .builder ().impid ("456" ).build ()))
274+ .build ()))
275+ .build ());
276+
277+ // when
278+ final Result <List <BidderBid >> result = target .makeBids (httpCall , null );
279+
280+ // then
281+ assertThat (result .getErrors ()).isEmpty ();
282+ assertThat (result .getValue ()).hasSize (2 )
283+ .extracting (BidderBid ::getBid )
284+ .extracting (Bid ::getImpid )
285+ .containsExactlyInAnyOrder ("123" , "456" );
286+ }
287+
288+ @ Test
289+ public void makeBidsShouldReturnBidWithCurrency () throws JsonProcessingException {
290+ // given
291+ final BidderCall <BidRequest > httpCall = givenHttpCall (
292+ BidRequest .builder ()
293+ .imp (singletonList (Imp .builder ().id ("123" ).build ()))
294+ .build (),
295+ BidResponse .builder ()
296+ .cur ("EUR" )
297+ .seatbid (singletonList (SeatBid .builder ()
298+ .bid (singletonList (Bid .builder ().impid ("123" ).build ()))
299+ .build ()))
300+ .build ());
301+
302+ // when
303+ final Result <List <BidderBid >> result = target .makeBids (httpCall , null );
304+
305+ // then
306+ assertThat (result .getErrors ()).isEmpty ();
307+ assertThat (result .getValue ())
308+ .extracting (BidderBid ::getBidCurrency )
309+ .containsExactly ("EUR" );
310+ }
311+
312+ @ Test
313+ public void makeBidsShouldReturnEmptyListIfSeatBidIsEmpty () throws JsonProcessingException {
314+ // given
315+ final BidderCall <BidRequest > httpCall = givenHttpCall (null ,
316+ BidResponse .builder ()
317+ .seatbid (singletonList (SeatBid .builder ().build ()))
318+ .build ());
319+
320+ // when
321+ final Result <List <BidderBid >> result = target .makeBids (httpCall , null );
322+
323+ // then
324+ assertThat (result .getErrors ()).isEmpty ();
325+ assertThat (result .getValue ()).isEmpty ();
326+ }
327+
163328 private static BidResponse givenBidResponse (Function <Bid .BidBuilder , Bid .BidBuilder > bidCustomizer ) {
164329 return BidResponse .builder ()
165330 .seatbid (singletonList (SeatBid .builder ().bid (singletonList (bidCustomizer .apply (Bid .builder ()).build ()))
@@ -173,4 +338,16 @@ private static BidderCall<BidRequest> givenHttpCall(BidRequest bidRequest, Strin
173338 HttpResponse .of (200 , null , body ),
174339 null );
175340 }
341+
342+ private static BidderCall <BidRequest > givenHttpCall (BidRequest bidRequest , BidResponse bidResponse )
343+ throws JsonProcessingException {
344+ return givenHttpCall (bidRequest , mapper .writeValueAsString (bidResponse ));
345+ }
346+
347+ private static Imp givenImp (String zoneId ) {
348+ return Imp .builder ()
349+ .id ("123" )
350+ .ext (mapper .valueToTree (ExtPrebid .of (null , ExtImpSmilewanted .of (zoneId ))))
351+ .build ();
352+ }
176353}
0 commit comments