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 );
@@ -123,15 +194,13 @@ public void makeBidsShouldReturnEmptyListIfBidResponseSeatBidIsNull() throws Jso
123194 }
124195
125196 @ Test
126- public void makeBidsShouldReturnVideoBidIfVideoIsPresentInRequestImpAndCorrespondingBid ()
127- throws JsonProcessingException {
197+ public void makeBidsShouldReturnVideoBidIfVideoIsPresentInRequestImpAndCorrespondingBid () throws JsonProcessingException {
128198 // given
129199 final BidderCall <BidRequest > httpCall = givenHttpCall (
130200 BidRequest .builder ()
131201 .imp (singletonList (Imp .builder ().id ("123" ).video (Video .builder ().build ()).build ()))
132202 .build (),
133- mapper .writeValueAsString (
134- givenBidResponse (bidBuilder -> bidBuilder .impid ("123" ))));
203+ givenBidResponse (bidBuilder -> bidBuilder .impid ("123" )));
135204
136205 // when
137206 final Result <List <BidderBid >> result = target .makeBids (httpCall , null );
@@ -148,8 +217,7 @@ public void makeBidsShouldReturnBannerBidIfVideoIsAbsentInRequestImp() throws Js
148217 final BidderCall <BidRequest > httpCall = givenHttpCall (BidRequest .builder ()
149218 .imp (singletonList (Imp .builder ().id ("123" ).build ()))
150219 .build (),
151- mapper .writeValueAsString (
152- givenBidResponse (bidBuilder -> bidBuilder .impid ("123" ))));
220+ givenBidResponse (bidBuilder -> bidBuilder .impid ("123" )));
153221
154222 // when
155223 final Result <List <BidderBid >> result = target .makeBids (httpCall , null );
@@ -160,6 +228,102 @@ public void makeBidsShouldReturnBannerBidIfVideoIsAbsentInRequestImp() throws Js
160228 .containsOnly (BidderBid .of (Bid .builder ().impid ("123" ).build (), banner , null ));
161229 }
162230
231+ @ Test
232+ public void makeBidsShouldReturnMultipleBidsFromSingleSeatBid () throws JsonProcessingException {
233+ // given
234+ final BidderCall <BidRequest > httpCall = givenHttpCall (
235+ BidRequest .builder ()
236+ .imp (List .of (
237+ Imp .builder ().id ("123" ).build (),
238+ Imp .builder ().id ("456" ).video (Video .builder ().build ()).build ()))
239+ .build (),
240+ BidResponse .builder ()
241+ .cur ("USD" )
242+ .seatbid (singletonList (SeatBid .builder ()
243+ .bid (List .of (
244+ Bid .builder ().impid ("123" ).price (BigDecimal .valueOf (1.0 )).build (),
245+ Bid .builder ().impid ("456" ).price (BigDecimal .valueOf (2.0 )).build ()))
246+ .build ()))
247+ .build ());
248+
249+ // when
250+ final Result <List <BidderBid >> result = target .makeBids (httpCall , null );
251+
252+ // then
253+ assertThat (result .getErrors ()).isEmpty ();
254+ assertThat (result .getValue ()).hasSize (2 )
255+ .containsExactlyInAnyOrder (
256+ BidderBid .of (Bid .builder ().impid ("123" ).price (BigDecimal .valueOf (1.0 )).build (), banner , "USD" ),
257+ BidderBid .of (Bid .builder ().impid ("456" ).price (BigDecimal .valueOf (2.0 )).build (), video , "USD" ));
258+ }
259+
260+ @ Test
261+ public void makeBidsShouldFilterNullBids () throws JsonProcessingException {
262+ // given
263+ final BidderCall <BidRequest > httpCall = givenHttpCall (
264+ BidRequest .builder ()
265+ .imp (singletonList (Imp .builder ().id ("123" ).build ()))
266+ .build (),
267+ BidResponse .builder ()
268+ .seatbid (singletonList (SeatBid .builder ()
269+ .bid (Arrays .asList (
270+ Bid .builder ().impid ("123" ).build (),
271+ null ,
272+ Bid .builder ().impid ("456" ).build ()))
273+ .build ()))
274+ .build ());
275+
276+ // when
277+ final Result <List <BidderBid >> result = target .makeBids (httpCall , null );
278+
279+ // then
280+ assertThat (result .getErrors ()).isEmpty ();
281+ assertThat (result .getValue ()).hasSize (2 )
282+ .extracting (BidderBid ::getBid )
283+ .extracting (Bid ::getImpid )
284+ .containsExactlyInAnyOrder ("123" , "456" );
285+ }
286+
287+ @ Test
288+ public void makeBidsShouldReturnBidWithCurrency () throws JsonProcessingException {
289+ // given
290+ final BidderCall <BidRequest > httpCall = givenHttpCall (
291+ BidRequest .builder ()
292+ .imp (singletonList (Imp .builder ().id ("123" ).build ()))
293+ .build (),
294+ BidResponse .builder ()
295+ .cur ("EUR" )
296+ .seatbid (singletonList (SeatBid .builder ()
297+ .bid (singletonList (Bid .builder ().impid ("123" ).build ()))
298+ .build ()))
299+ .build ());
300+
301+ // when
302+ final Result <List <BidderBid >> result = target .makeBids (httpCall , null );
303+
304+ // then
305+ assertThat (result .getErrors ()).isEmpty ();
306+ assertThat (result .getValue ())
307+ .extracting (BidderBid ::getBidCurrency )
308+ .containsExactly ("EUR" );
309+ }
310+
311+ @ Test
312+ public void makeBidsShouldReturnEmptyListIfSeatBidIsEmpty () throws JsonProcessingException {
313+ // given
314+ final BidderCall <BidRequest > httpCall = givenHttpCall (null ,
315+ BidResponse .builder ()
316+ .seatbid (singletonList (SeatBid .builder ().build ()))
317+ .build ());
318+
319+ // when
320+ final Result <List <BidderBid >> result = target .makeBids (httpCall , null );
321+
322+ // then
323+ assertThat (result .getErrors ()).isEmpty ();
324+ assertThat (result .getValue ()).isEmpty ();
325+ }
326+
163327 private static BidResponse givenBidResponse (Function <Bid .BidBuilder , Bid .BidBuilder > bidCustomizer ) {
164328 return BidResponse .builder ()
165329 .seatbid (singletonList (SeatBid .builder ().bid (singletonList (bidCustomizer .apply (Bid .builder ()).build ()))
@@ -173,4 +337,16 @@ private static BidderCall<BidRequest> givenHttpCall(BidRequest bidRequest, Strin
173337 HttpResponse .of (200 , null , body ),
174338 null );
175339 }
340+
341+ private static BidderCall <BidRequest > givenHttpCall (BidRequest bidRequest , BidResponse bidResponse )
342+ throws JsonProcessingException {
343+ return givenHttpCall (bidRequest , mapper .writeValueAsString (bidResponse ));
344+ }
345+
346+ private static Imp givenImp (String zoneId ) {
347+ return Imp .builder ()
348+ .id ("123" )
349+ .ext (mapper .valueToTree (ExtPrebid .of (null , ExtImpSmilewanted .of (zoneId ))))
350+ .build ();
351+ }
176352}
0 commit comments