108108import org .prebid .server .proto .openrtb .ext .response .ExtBidPrebid ;
109109import org .prebid .server .proto .openrtb .ext .response .ExtBidPrebidMeta ;
110110import org .prebid .server .util .HttpUtil ;
111+ import org .prebid .server .version .PrebidVersionProvider ;
111112
112113import java .io .IOException ;
113114import java .math .BigDecimal ;
@@ -147,8 +148,10 @@ public class RubiconBidderTest extends VertxTest {
147148
148149 private static final String BIDDER_NAME = "bidderName" ;
149150 private static final String ENDPOINT_URL = "http://rubiconproject.com/exchange.json?tk_xint=prebid" ;
151+ private static final String EXTERNAL_URL = "http://localhost:8080" ;
150152 private static final String USERNAME = "username" ;
151153 private static final String PASSWORD = "password" ;
154+ private static final String PBS_VERSION = "pbs_version" ;
152155 private static final List <String > SUPPORTED_VENDORS = Arrays .asList ("activeview" , "comscore" ,
153156 "doubleverify" , "integralads" , "moat" , "sizmek" , "whiteops" );
154157
@@ -158,34 +161,44 @@ public class RubiconBidderTest extends VertxTest {
158161 @ Mock (strictness = LENIENT )
159162 private CurrencyConversionService currencyConversionService ;
160163
164+ @ Mock (strictness = LENIENT )
165+ private PrebidVersionProvider versionProvider ;
166+
161167 private RubiconBidder target ;
162168
163169 @ BeforeEach
164170 public void setUp () {
165- target = new RubiconBidder (BIDDER_NAME ,
171+ target = new RubiconBidder (
172+ BIDDER_NAME ,
166173 ENDPOINT_URL ,
174+ EXTERNAL_URL ,
167175 USERNAME ,
168176 PASSWORD ,
169177 SUPPORTED_VENDORS ,
170178 false ,
171179 true ,
172180 currencyConversionService ,
173181 priceFloorResolver ,
182+ versionProvider ,
174183 jacksonMapper );
184+
185+ given (versionProvider .getNameVersionRecord ()).willReturn ("pbs_version" );
175186 }
176187
177188 @ Test
178189 public void creationShouldFailOnInvalidEndpointUrl () {
179190 assertThatIllegalArgumentException ().isThrownBy (
180191 () -> new RubiconBidder (BIDDER_NAME ,
181192 "invalid_url" ,
193+ EXTERNAL_URL ,
182194 USERNAME ,
183195 PASSWORD ,
184196 SUPPORTED_VENDORS ,
185197 false ,
186198 true ,
187199 currencyConversionService ,
188200 priceFloorResolver ,
201+ versionProvider ,
189202 jacksonMapper ));
190203 }
191204
@@ -623,17 +636,17 @@ public void makeHttpRequestsShouldFillImpExt() {
623636 final Result <List <HttpRequest <BidRequest >>> result = target .makeHttpRequests (bidRequest );
624637
625638 // then
639+ final ObjectNode expectedTarget = givenImpExtRpTarget ().setAll (
640+ (ObjectNode ) mapper .valueToTree (Inventory .of (singletonList ("5-star" ), singletonList ("tech" ))));
641+
626642 assertThat (result .getErrors ()).isEmpty ();
627643 assertThat (result .getValue ()).hasSize (1 ).doesNotContainNull ()
628644 .extracting (httpRequest -> mapper .readValue (httpRequest .getBody (), BidRequest .class ))
629645 .flatExtracting (BidRequest ::getImp ).doesNotContainNull ()
630646 .extracting (Imp ::getExt ).doesNotContainNull ()
631647 .extracting (ext -> mapper .treeToValue (ext , RubiconImpExt .class ))
632- .containsOnly (RubiconImpExt .builder ()
633- .rp (RubiconImpExtRp .of (4001 ,
634- mapper .valueToTree (Inventory .of (singletonList ("5-star" ), singletonList ("tech" ))),
635- RubiconImpExtRpTrack .of ("" , "" ),
636- null ))
648+ .containsExactly (RubiconImpExt .builder ()
649+ .rp (RubiconImpExtRp .of (4001 , expectedTarget , RubiconImpExtRpTrack .of ("" , "" ), null ))
637650 .skadn (givenSkadn )
638651 .maxbids (1 )
639652 .build ());
@@ -832,13 +845,15 @@ public void shouldNotSetSizeIfVideoSizeProcessingLogicIsDisabledAndBidderParamsI
832845 target = new RubiconBidder (
833846 BIDDER_NAME ,
834847 ENDPOINT_URL ,
848+ EXTERNAL_URL ,
835849 USERNAME ,
836850 PASSWORD ,
837851 SUPPORTED_VENDORS ,
838852 true ,
839853 false ,
840854 currencyConversionService ,
841855 priceFloorResolver ,
856+ versionProvider ,
842857 jacksonMapper );
843858 final BidRequest bidRequest = givenBidRequest (
844859 builder -> builder .instl (1 ).video (Video .builder ().placement (1 ).build ()),
@@ -863,13 +878,15 @@ public void shouldSetSizeFromBidderParamsWhenVideoSizeProcessingLogicIsDisabled(
863878 target = new RubiconBidder (
864879 BIDDER_NAME ,
865880 ENDPOINT_URL ,
881+ EXTERNAL_URL ,
866882 USERNAME ,
867883 PASSWORD ,
868884 SUPPORTED_VENDORS ,
869885 true ,
870886 false ,
871887 currencyConversionService ,
872888 priceFloorResolver ,
889+ versionProvider ,
873890 jacksonMapper );
874891 final BidRequest bidRequest = givenBidRequest (
875892 builder -> builder .instl (1 ).video (Video .builder ().placement (1 ).build ()),
@@ -2493,11 +2510,14 @@ public void makeHttpRequestsShouldCreateRequestPerImp() {
24932510 final Result <List <HttpRequest <BidRequest >>> result = target .makeHttpRequests (bidRequest );
24942511
24952512 // then
2513+ final RubiconImpExtRp expectedImpExtRp = RubiconImpExtRp .of (
2514+ null , givenImpExtRpTarget (), RubiconImpExtRpTrack .of ("" , "" ), null );
2515+
24962516 final BidRequest expectedBidRequest1 = BidRequest .builder ()
24972517 .imp (singletonList (Imp .builder ()
24982518 .video (Video .builder ().build ())
24992519 .ext (mapper .valueToTree (RubiconImpExt .builder ()
2500- .rp (RubiconImpExtRp . of ( null , null , RubiconImpExtRpTrack . of ( "" , "" ), null ) )
2520+ .rp (expectedImpExtRp )
25012521 .maxbids (1 )
25022522 .build ()))
25032523 .build ()))
@@ -2508,7 +2528,7 @@ public void makeHttpRequestsShouldCreateRequestPerImp() {
25082528 .video (Video .builder ().build ())
25092529 .ext (mapper .valueToTree (
25102530 RubiconImpExt .builder ()
2511- .rp (RubiconImpExtRp . of ( null , null , RubiconImpExtRpTrack . of ( "" , "" ), null ) )
2531+ .rp (expectedImpExtRp )
25122532 .maxbids (1 )
25132533 .build ()))
25142534 .build ()))
@@ -2544,8 +2564,7 @@ public void makeHttpRequestsShouldCopyAndModifyDataFieldsToRubiconImpExtRpTarget
25442564 .extracting (objectNode -> mapper .convertValue (objectNode , RubiconImpExt .class ))
25452565 .extracting (RubiconImpExt ::getRp )
25462566 .extracting (RubiconImpExtRp ::getTarget )
2547- .containsOnly (mapper .createObjectNode ()
2548- .<ObjectNode >set ("property2" , mapper .createArrayNode ().add ("value2" )));
2567+ .containsExactly (givenImpExtRpTarget ().set ("property2" , mapper .createArrayNode ().add ("value2" )));
25492568 }
25502569
25512570 @ Test
@@ -2592,7 +2611,7 @@ public void makeHttpRequestsShouldCopySiteExtDataFieldsToRubiconImpExtRpTarget()
25922611 .extracting (objectNode -> mapper .convertValue (objectNode , RubiconImpExt .class ))
25932612 .extracting (RubiconImpExt ::getRp )
25942613 .extracting (RubiconImpExtRp ::getTarget )
2595- .containsOnly ( mapper . createObjectNode ().set ("property" , mapper .createArrayNode ().add ("value" )));
2614+ .containsExactly ( givenImpExtRpTarget ().set ("property" , mapper .createArrayNode ().add ("value" )));
25962615 }
25972616
25982617 @ Test
@@ -2618,7 +2637,27 @@ public void makeHttpRequestsShouldCopyAppExtDataFieldsToRubiconImpExtRpTarget()
26182637 .extracting (objectNode -> mapper .convertValue (objectNode , RubiconImpExt .class ))
26192638 .extracting (RubiconImpExt ::getRp )
26202639 .extracting (RubiconImpExtRp ::getTarget )
2621- .containsOnly (mapper .createObjectNode ().set ("property" , mapper .createArrayNode ().add ("value" )));
2640+ .containsOnly (givenImpExtRpTarget ().set ("property" , mapper .createArrayNode ().add ("value" )));
2641+ }
2642+
2643+ @ Test
2644+ public void makeHttpRequestsShouldSetXapiFieldsToRubiconImpExtRpTarget () {
2645+ // given
2646+ final BidRequest bidRequest = givenBidRequest (impBuilder -> impBuilder .video (Video .builder ().build ()));
2647+
2648+ // when
2649+ final Result <List <HttpRequest <BidRequest >>> result = target .makeHttpRequests (bidRequest );
2650+
2651+ // then
2652+ assertThat (result .getErrors ()).isEmpty ();
2653+ assertThat (result .getValue ())
2654+ .extracting (httpRequest -> mapper .readValue (httpRequest .getBody (), BidRequest .class ))
2655+ .flatExtracting (BidRequest ::getImp )
2656+ .extracting (Imp ::getExt )
2657+ .extracting (objectNode -> mapper .convertValue (objectNode , RubiconImpExt .class ))
2658+ .extracting (RubiconImpExt ::getRp )
2659+ .extracting (RubiconImpExtRp ::getTarget )
2660+ .containsExactly (givenImpExtRpTarget ());
26222661 }
26232662
26242663 @ Test
@@ -2737,6 +2776,9 @@ public void makeHttpRequestsShouldCopyDataSearchToRubiconImpExtRpTargetSearch()
27372776 final Result <List <HttpRequest <BidRequest >>> result = target .makeHttpRequests (bidRequest );
27382777
27392778 // then
2779+ final ObjectNode expectedTarget = givenImpExtRpTarget ()
2780+ .set ("search" , mapper .createArrayNode ().add ("imp ext data search" ));
2781+
27402782 assertThat (result .getErrors ()).isEmpty ();
27412783 assertThat (result .getValue ())
27422784 .extracting (httpRequest -> mapper .readValue (httpRequest .getBody (), BidRequest .class ))
@@ -2745,7 +2787,7 @@ public void makeHttpRequestsShouldCopyDataSearchToRubiconImpExtRpTargetSearch()
27452787 .extracting (objectNode -> mapper .convertValue (objectNode , RubiconImpExt .class ))
27462788 .extracting (RubiconImpExt ::getRp )
27472789 .extracting (RubiconImpExtRp ::getTarget )
2748- .containsOnly ( mapper . readTree ( "{ \" search \" :[ \" imp ext data search \" ]}" ) );
2790+ .containsExactly ( expectedTarget );
27492791 }
27502792
27512793 @ Test
@@ -2794,8 +2836,7 @@ public void makeHttpRequestsShouldMergeSiteAttributesAndCopyToRubiconImpExtRpTar
27942836 .extracting (objectNode -> mapper .convertValue (objectNode , RubiconImpExt .class ))
27952837 .extracting (RubiconImpExt ::getRp )
27962838 .extracting (RubiconImpExtRp ::getTarget )
2797- .containsOnly (mapper .createObjectNode ()
2798- .<ObjectNode >set ("page" , mapper .createArrayNode ().add ("site page" )));
2839+ .containsExactly (givenImpExtRpTarget ().set ("page" , mapper .createArrayNode ().add ("site page" )));
27992840 }
28002841
28012842 @ Test
@@ -3002,8 +3043,8 @@ public void makeHttpRequestsShouldReturnOnlyLineItemRequestsWithExpectedFieldsWh
30023043 .flatExtracting (BidRequest ::getImp )
30033044 .extracting (imp -> mapper .treeToValue (imp .getExt (), RubiconImpExt .class ).getRp ().getTarget ())
30043045 .containsOnly (
3005- mapper . readTree ( "{ \" line_item\" : \ " 123\" } " ),
3006- mapper . readTree ( "{ \" line_item\" : \ " 234\" } " ));
3046+ givenImpExtRpTarget (). put ( " line_item" , "123" ),
3047+ givenImpExtRpTarget (). put ( " line_item" , "234" ));
30073048 }
30083049
30093050 @ Test
@@ -3719,8 +3760,8 @@ public void makeBidsShouldReturnNativeBidIfNativeIsPresent() throws JsonProcessi
37193760 public void makeBidsShouldReturnBidWithRandomlyGeneratedId () throws JsonProcessingException {
37203761 // given
37213762 target = new RubiconBidder (
3722- BIDDER_NAME , ENDPOINT_URL , USERNAME , PASSWORD , SUPPORTED_VENDORS , true , true ,
3723- currencyConversionService , priceFloorResolver , jacksonMapper );
3763+ BIDDER_NAME , ENDPOINT_URL , ENDPOINT_URL , USERNAME , PASSWORD , SUPPORTED_VENDORS , true , true ,
3764+ currencyConversionService , priceFloorResolver , versionProvider , jacksonMapper );
37243765
37253766 final BidderCall <BidRequest > httpCall = givenHttpCall (givenBidRequest (identity ()),
37263767 mapper .writeValueAsString (RubiconBidResponse .builder ()
@@ -3745,8 +3786,8 @@ public void makeBidsShouldReturnBidWithRandomlyGeneratedId() throws JsonProcessi
37453786 public void makeBidsShouldReturnBidWithCurrencyFromBidResponse () throws JsonProcessingException {
37463787 // given
37473788 target = new RubiconBidder (
3748- BIDDER_NAME , ENDPOINT_URL , USERNAME , PASSWORD , SUPPORTED_VENDORS , true , true ,
3749- currencyConversionService , priceFloorResolver , jacksonMapper );
3789+ BIDDER_NAME , ENDPOINT_URL , EXTERNAL_URL , USERNAME , PASSWORD , SUPPORTED_VENDORS , true , true ,
3790+ currencyConversionService , priceFloorResolver , versionProvider , jacksonMapper );
37503791
37513792 final BidderCall <BidRequest > httpCall = givenHttpCall (givenBidRequest (identity ()),
37523793 mapper .writeValueAsString (RubiconBidResponse .builder ()
@@ -3942,6 +3983,13 @@ private static Data givenTestDataWithSegmentEntries(Integer segtax) {
39423983 .build ();
39433984 }
39443985
3986+ private static ObjectNode givenImpExtRpTarget () {
3987+ return mapper .createObjectNode ()
3988+ .put ("pbs_login" , USERNAME )
3989+ .put ("pbs_version" , PBS_VERSION )
3990+ .put ("pbs_url" , EXTERNAL_URL );
3991+ }
3992+
39453993 @ AllArgsConstructor (staticName = "of" )
39463994 @ Value
39473995 private static class Inventory {
0 commit comments