22
33import com .fasterxml .jackson .core .JsonProcessingException ;
44import com .fasterxml .jackson .databind .node .ObjectNode ;
5+ import java .math .BigDecimal ;
56import com .iab .openrtb .request .App ;
67import com .iab .openrtb .request .Banner ;
78import com .iab .openrtb .request .BidRequest ;
@@ -458,7 +459,7 @@ public void makeBidsShouldReturnVideoBid() throws JsonProcessingException {
458459 }
459460
460461 @ Test
461- public void makeBidsShouldThrowErrorWhenMediaTypeIsMissing () throws JsonProcessingException {
462+ public void makeBidsShouldReturnErrorWhenMediaTypeIsMissing () throws JsonProcessingException {
462463 // given
463464 final BidderCall <BidRequest > httpCall = givenHttpCall (
464465 givenBidResponse (bidBuilder -> bidBuilder .impid ("123" )));
@@ -469,7 +470,36 @@ public void makeBidsShouldThrowErrorWhenMediaTypeIsMissing() throws JsonProcessi
469470 // then
470471 assertThat (result .getValue ()).isEmpty ();
471472 assertThat (result .getErrors ()).hasSize (1 )
472- .containsOnly (BidderError .badServerResponse ("unsupported mtype: null" ));
473+ .containsOnly (BidderError .badServerResponse ("could not define media type for impression: 123" ));
474+ }
475+
476+ @ Test
477+ public void makeBidsShouldReturnValidBidsAndErrorsForMixedMediaTypes () throws JsonProcessingException {
478+ // given
479+ final BidderCall <BidRequest > httpCall = givenHttpCall (
480+ mapper .writeValueAsString (BidResponse .builder ()
481+ .cur ("USD" )
482+ .seatbid (singletonList (SeatBid .builder ()
483+ .bid (Arrays .asList (
484+ Bid .builder ().mtype (1 ).impid ("valid1" ).build (), // valid banner
485+ Bid .builder ().mtype (3 ).impid ("invalid1" ).build (), // invalid mtype
486+ Bid .builder ().mtype (2 ).impid ("valid2" ).build (), // valid video
487+ Bid .builder ().mtype (null ).impid ("invalid2" ).build () // null mtype
488+ ))
489+ .build ()))
490+ .build ()));
491+
492+ // when
493+ final Result <List <BidderBid >> result = target .makeBids (httpCall , null );
494+
495+ // then
496+ assertThat (result .getValue ()).hasSize (2 )
497+ .extracting (bidderBid -> bidderBid .getBid ().getImpid ())
498+ .containsExactly ("valid1" , "valid2" );
499+ assertThat (result .getErrors ()).hasSize (2 )
500+ .containsExactly (
501+ BidderError .badServerResponse ("could not define media type for impression: invalid1" ),
502+ BidderError .badServerResponse ("could not define media type for impression: invalid2" ));
473503 }
474504
475505 private String givenBidResponse (UnaryOperator <Bid .BidBuilder > bidCustomizer ) throws JsonProcessingException {
@@ -509,4 +539,204 @@ private static ObjectNode impExt(String publisherId, String supplySourceId) {
509539 return mapper .valueToTree (ExtPrebid .of (null , ExtImpTheTradeDesk .of (publisherId , supplySourceId )));
510540 }
511541
542+
543+ @ Test
544+ public void makeBidsShouldReplacePriceMacroInNurlAndAdmWithBidPrice () throws JsonProcessingException {
545+ // given
546+ final BidderCall <BidRequest > httpCall = givenHttpCall (
547+ givenBidResponse (bidBuilder -> bidBuilder
548+ .mtype (1 )
549+ .impid ("123" )
550+ .price (BigDecimal .valueOf (1.23 ))
551+ .nurl ("http://example.com/nurl?price=${AUCTION_PRICE}" )
552+ .adm ("<div>Price: ${AUCTION_PRICE}</div>" )));
553+
554+ // when
555+ final Result <List <BidderBid >> result = target .makeBids (httpCall , null );
556+
557+ // then
558+ assertThat (result .getErrors ()).isEmpty ();
559+ assertThat (result .getValue ()).hasSize (1 );
560+ final BidderBid bidderBid = result .getValue ().getFirst ();
561+ assertThat (bidderBid .getBid ().getNurl ()).isEqualTo ("http://example.com/nurl?price=1.23" );
562+ assertThat (bidderBid .getBid ().getAdm ()).isEqualTo ("<div>Price: 1.23</div>" );
563+ assertThat (bidderBid .getBid ().getPrice ()).isEqualTo (BigDecimal .valueOf (1.23 ));
564+ }
565+
566+ @ Test
567+ public void makeBidsShouldReplacePriceMacroWithZeroWhenBidPriceIsNull () throws JsonProcessingException {
568+ // given
569+ final BidderCall <BidRequest > httpCall = givenHttpCall (
570+ givenBidResponse (bidBuilder -> bidBuilder
571+ .mtype (1 )
572+ .impid ("123" )
573+ .price (null )
574+ .nurl ("http://example.com/nurl?price=${AUCTION_PRICE}" )
575+ .adm ("<div>Price: ${AUCTION_PRICE}</div>" )));
576+
577+ // when
578+ final Result <List <BidderBid >> result = target .makeBids (httpCall , null );
579+
580+ // then
581+ assertThat (result .getErrors ()).isEmpty ();
582+ assertThat (result .getValue ()).hasSize (1 );
583+ final BidderBid bidderBid = result .getValue ().getFirst ();
584+ assertThat (bidderBid .getBid ().getNurl ()).isEqualTo ("http://example.com/nurl?price=0" );
585+ assertThat (bidderBid .getBid ().getAdm ()).isEqualTo ("<div>Price: 0</div>" );
586+ }
587+
588+ @ Test
589+ public void makeBidsShouldReplacePriceMacroWithZeroWhenBidPriceIsZero () throws JsonProcessingException {
590+ // given
591+ final BidderCall <BidRequest > httpCall = givenHttpCall (
592+ givenBidResponse (bidBuilder -> bidBuilder
593+ .mtype (1 )
594+ .impid ("123" )
595+ .price (BigDecimal .ZERO )
596+ .nurl ("http://example.com/nurl?price=${AUCTION_PRICE}" )
597+ .adm ("<div>Price: ${AUCTION_PRICE}</div>" )));
598+
599+ // when
600+ final Result <List <BidderBid >> result = target .makeBids (httpCall , null );
601+
602+ // then
603+ assertThat (result .getErrors ()).isEmpty ();
604+ assertThat (result .getValue ()).hasSize (1 );
605+ final BidderBid bidderBid = result .getValue ().getFirst ();
606+ assertThat (bidderBid .getBid ().getNurl ()).isEqualTo ("http://example.com/nurl?price=0" );
607+ assertThat (bidderBid .getBid ().getAdm ()).isEqualTo ("<div>Price: 0</div>" );
608+ }
609+
610+ @ Test
611+ public void makeBidsShouldReplacePriceMacroInNurlOnlyWhenAdmDoesNotContainMacro () throws JsonProcessingException {
612+ // given
613+ final BidderCall <BidRequest > httpCall = givenHttpCall (
614+ givenBidResponse (bidBuilder -> bidBuilder
615+ .mtype (1 )
616+ .impid ("123" )
617+ .price (BigDecimal .valueOf (5.67 ))
618+ .nurl ("http://example.com/nurl?price=${AUCTION_PRICE}" )
619+ .adm ("<div>No macro here</div>" )));
620+
621+ // when
622+ final Result <List <BidderBid >> result = target .makeBids (httpCall , null );
623+
624+ // then
625+ assertThat (result .getErrors ()).isEmpty ();
626+ assertThat (result .getValue ()).hasSize (1 );
627+ final BidderBid bidderBid = result .getValue ().getFirst ();
628+ assertThat (bidderBid .getBid ().getNurl ()).isEqualTo ("http://example.com/nurl?price=5.67" );
629+ assertThat (bidderBid .getBid ().getAdm ()).isEqualTo ("<div>No macro here</div>" );
630+ }
631+
632+ @ Test
633+ public void makeBidsShouldReplacePriceMacroInAdmOnlyWhenNurlDoesNotContainMacro () throws JsonProcessingException {
634+ // given
635+ final BidderCall <BidRequest > httpCall = givenHttpCall (
636+ givenBidResponse (bidBuilder -> bidBuilder
637+ .mtype (1 )
638+ .impid ("123" )
639+ .price (BigDecimal .valueOf (8.90 ))
640+ .nurl ("http://example.com/nurl" )
641+ .adm ("<div>Price: ${AUCTION_PRICE}</div>" )));
642+
643+ // when
644+ final Result <List <BidderBid >> result = target .makeBids (httpCall , null );
645+
646+ // then
647+ assertThat (result .getErrors ()).isEmpty ();
648+ assertThat (result .getValue ()).hasSize (1 );
649+ final BidderBid bidderBid = result .getValue ().getFirst ();
650+ assertThat (bidderBid .getBid ().getNurl ()).isEqualTo ("http://example.com/nurl" );
651+ assertThat (bidderBid .getBid ().getAdm ()).isEqualTo ("<div>Price: 8.90</div>" );
652+ }
653+
654+ @ Test
655+ public void makeBidsShouldNotReplacePriceMacroWhenNurlAndAdmDoNotContainMacro () throws JsonProcessingException {
656+ // given
657+ final BidderCall <BidRequest > httpCall = givenHttpCall (
658+ givenBidResponse (bidBuilder -> bidBuilder
659+ .mtype (1 )
660+ .impid ("123" )
661+ .price (BigDecimal .valueOf (12.34 ))
662+ .nurl ("http://example.com/nurl" )
663+ .adm ("<div>No macro</div>" )));
664+
665+ // when
666+ final Result <List <BidderBid >> result = target .makeBids (httpCall , null );
667+
668+ // then
669+ assertThat (result .getErrors ()).isEmpty ();
670+ assertThat (result .getValue ()).hasSize (1 );
671+ final BidderBid bidderBid = result .getValue ().getFirst ();
672+ assertThat (bidderBid .getBid ().getNurl ()).isEqualTo ("http://example.com/nurl" );
673+ assertThat (bidderBid .getBid ().getAdm ()).isEqualTo ("<div>No macro</div>" );
674+ }
675+
676+ @ Test
677+ public void makeBidsShouldHandleNullNurlAndAdm () throws JsonProcessingException {
678+ // given
679+ final BidderCall <BidRequest > httpCall = givenHttpCall (
680+ givenBidResponse (bidBuilder -> bidBuilder
681+ .mtype (1 )
682+ .impid ("123" )
683+ .price (BigDecimal .valueOf (15.00 ))
684+ .nurl (null )
685+ .adm (null )));
686+
687+ // when
688+ final Result <List <BidderBid >> result = target .makeBids (httpCall , null );
689+
690+ // then
691+ assertThat (result .getErrors ()).isEmpty ();
692+ assertThat (result .getValue ()).hasSize (1 );
693+ final BidderBid bidderBid = result .getValue ().getFirst ();
694+ assertThat (bidderBid .getBid ().getNurl ()).isNull ();
695+ assertThat (bidderBid .getBid ().getAdm ()).isNull ();
696+ }
697+
698+ @ Test
699+ public void makeBidsShouldReplaceMultiplePriceMacrosInSameField () throws JsonProcessingException {
700+ // given
701+ final BidderCall <BidRequest > httpCall = givenHttpCall (
702+ givenBidResponse (bidBuilder -> bidBuilder
703+ .mtype (1 )
704+ .impid ("123" )
705+ .price (BigDecimal .valueOf (9.99 ))
706+ .nurl ("http://example.com/nurl?price=${AUCTION_PRICE}&backup_price=${AUCTION_PRICE}" )
707+ .adm ("<div>Price: ${AUCTION_PRICE}, Fallback: ${AUCTION_PRICE}</div>" )));
708+
709+ // when
710+ final Result <List <BidderBid >> result = target .makeBids (httpCall , null );
711+
712+ // then
713+ assertThat (result .getErrors ()).isEmpty ();
714+ assertThat (result .getValue ()).hasSize (1 );
715+ final BidderBid bidderBid = result .getValue ().getFirst ();
716+ assertThat (bidderBid .getBid ().getNurl ()).isEqualTo ("http://example.com/nurl?price=9.99&backup_price=9.99" );
717+ assertThat (bidderBid .getBid ().getAdm ()).isEqualTo ("<div>Price: 9.99, Fallback: 9.99</div>" );
718+ }
719+
720+ @ Test
721+ public void makeBidsShouldHandleLargeDecimalPrices () throws JsonProcessingException {
722+ // given
723+ final BidderCall <BidRequest > httpCall = givenHttpCall (
724+ givenBidResponse (bidBuilder -> bidBuilder
725+ .mtype (1 )
726+ .impid ("123" )
727+ .price (new BigDecimal ("123456789.123456789" ))
728+ .nurl ("http://example.com/nurl?price=${AUCTION_PRICE}" )
729+ .adm ("<div>Price: ${AUCTION_PRICE}</div>" )));
730+
731+ // when
732+ final Result <List <BidderBid >> result = target .makeBids (httpCall , null );
733+
734+ // then
735+ assertThat (result .getErrors ()).isEmpty ();
736+ assertThat (result .getValue ()).hasSize (1 );
737+ final BidderBid bidderBid = result .getValue ().getFirst ();
738+ assertThat (bidderBid .getBid ().getNurl ()).isEqualTo ("http://example.com/nurl?price=123456789.123456789" );
739+ assertThat (bidderBid .getBid ().getAdm ()).isEqualTo ("<div>Price: 123456789.123456789</div>" );
740+ }
741+
512742}
0 commit comments