From 8dc51334c9305d2c90ef52b58353272c39537535 Mon Sep 17 00:00:00 2001 From: Saurabh Narkhede <108730956+pm-saurabh-narkhede@users.noreply.github.com> Date: Wed, 18 Dec 2024 17:04:21 +0530 Subject: [PATCH 1/5] UOE-11060: Forward ClickTrackers for Banner only (#983) --- modules/pubmatic/openwrap/auctionresponsehook.go | 3 +++ modules/pubmatic/openwrap/auctionresponsehook_test.go | 6 +++--- modules/pubmatic/openwrap/models/response.go | 1 + 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/modules/pubmatic/openwrap/auctionresponsehook.go b/modules/pubmatic/openwrap/auctionresponsehook.go index 2d7ecc2a406..700af49c8b1 100644 --- a/modules/pubmatic/openwrap/auctionresponsehook.go +++ b/modules/pubmatic/openwrap/auctionresponsehook.go @@ -167,6 +167,9 @@ func (m OpenWrap) handleAuctionResponseHook( bidExt.CreativeType = models.GetCreativeType(&bid, bidExt, &impCtx) } + if bidExt.CreativeType != string(openrtb_ext.BidTypeBanner) { + bidExt.ClickTrackers = nil + } // set response netecpm and logger/tracker en revShare := models.GetRevenueShare(rctx.PartnerConfigMap[partnerID]) bidExt.NetECPM = models.ToFixed(bid.Price, models.BID_PRECISION) diff --git a/modules/pubmatic/openwrap/auctionresponsehook_test.go b/modules/pubmatic/openwrap/auctionresponsehook_test.go index 4346dc5033b..68fd47b2020 100644 --- a/modules/pubmatic/openwrap/auctionresponsehook_test.go +++ b/modules/pubmatic/openwrap/auctionresponsehook_test.go @@ -1664,7 +1664,7 @@ func TestOpenWrapHandleAuctionResponseHook(t *testing.T) { ImpID: "Div1", Price: 5, AdM: "
", - Ext: json.RawMessage(`{"bidtype":0,"deal_channel":1,"dspid":6,"origbidcpm":8,"origbidcur":"USD","ibv":true,"prebid":{"bidid":"bb57a9e3-fdc2-4772-8071-112dd7f50a6a","meta":{"adaptercode":"pubmatic","advertiserId":4098,"agencyId":4098,"demandSource":"6","mediaType":"banner","networkId":6},"targeting":{"hb_bidder_pubmatic":"pubmatic","hb_deal_pubmatic":"PUBDEAL1","hb_pb_pubmatic":"8.00","hb_size_pubmatic":"728x90"},"type":"banner","video":{"duration":0,"primary_category":"","vasttagid":""}}}`), + Ext: json.RawMessage(`{"bidtype":0,"deal_channel":1,"dspid":6,"origbidcpm":8,"origbidcur":"USD","ibv":true,"prebid":{"bidid":"bb57a9e3-fdc2-4772-8071-112dd7f50a6a","meta":{"adaptercode":"pubmatic","advertiserId":4098,"agencyId":4098,"demandSource":"6","mediaType":"banner","networkId":6},"targeting":{"hb_bidder_pubmatic":"pubmatic","hb_deal_pubmatic":"PUBDEAL1","hb_pb_pubmatic":"8.00","hb_size_pubmatic":"728x90"},"type":"banner","video":{"duration":0,"primary_category":"","vasttagid":""}},"clicktrackers":["http://clicktracker1.com","http://clicktracker2.com"]}`), }, }, Seat: "pubmatic", @@ -1691,7 +1691,7 @@ func TestOpenWrapHandleAuctionResponseHook(t *testing.T) { DebugMessages: []string{`[{"PubID":5890,"ProfileID":0,"DisplayID":0,"VersionID":0,"DisplayVersionID":0,"SSAuction":0,"SummaryDisable":0,"SSAI":"","PartnerConfigMap":{"-1":{"displayVersionId":"1","refreshInterval":"30","rev_share":"0.5"},"123":{"bidderCode":"pubmatic","kgp":"_AU_@_W_x_H_","partnerId":"123","prebidPartnerName":"pubmatic","serverSideEnabled":"1","timeout":"200"}},"SupportDeals":false,"Platform":"web","LoggerImpressionID":"","ClientConfigFlag":1,"IP":"","TMax":0,"IsTestRequest":0,"ABTestConfig":0,"ABTestConfigApplied":0,"IsCTVRequest":false,"TrackerEndpoint":"","VideoErrorTrackerEndpoint":"","UA":"","Cookies":"","UidCookie":null,"KADUSERCookie":null,"ParsedUidCookie":null,"OriginCookie":"","Debug":true,"Trace":false,"PageURL":"","StartTime":0,"DevicePlatform":0,"Trackers":{"bid-id-1":{"Tracker":{"PubID":5890,"PageURL":"","Timestamp":0,"IID":"","ProfileID":"0","VersionID":"0","SlotID":"","Adunit":"","PartnerInfo":{"PartnerID":"pubmatic","BidderCode":"pubmatic","KGPV":"","GrossECPM":0,"NetECPM":0,"BidID":"bb57a9e3-fdc2-4772-8071-112dd7f50a6a","OrigBidID":"bid-id-1","AdSize":"0x0","AdDuration":0,"Adformat":"banner","ServerSide":1,"Advertiser":"","FloorValue":0,"FloorRuleValue":0,"DealID":"-1"},"RewardedInventory":0,"SURL":"","Platform":0,"SSAI":"","AdPodSlot":0,"TestGroup":0,"Origin":"","FloorSkippedFlag":null,"FloorModelVersion":"","FloorSource":null,"FloorType":0,"CustomDimensions":"","LoggerData":{"KGPSV":"","FloorProvider":"","FloorFetchStatus":null}},"TrackerURL":"https:?adv=\u0026af=banner\u0026aps=0\u0026au=\u0026bc=pubmatic\u0026bidid=bb57a9e3-fdc2-4772-8071-112dd7f50a6a\u0026di=-1\u0026eg=0\u0026en=0\u0026ft=0\u0026iid=\u0026kgpv=\u0026orig=\u0026origbidid=bid-id-1\u0026pdvid=0\u0026pid=0\u0026plt=0\u0026pn=pubmatic\u0026psz=0x0\u0026pubid=5890\u0026purl=\u0026sl=1\u0026slot=\u0026ss=1\u0026tgid=0\u0026tst=0","ErrorURL":"","Price":5,"PriceModel":"CPM","PriceCurrency":""}},"PrebidBidderCode":null,"ImpBidCtx":{"Div1":{"ImpID":"","TagID":"","Div":"","SlotName":"","AdUnitName":"","Secure":0,"BidFloor":0,"BidFloorCur":"","IsRewardInventory":null,"Banner":true,"Video":{"mimes":null},"Native":null,"IncomingSlots":null,"Type":"video","Bidders":{"pubmatic":{"PartnerID":123,"PrebidBidderCode":"pubmatic","MatchedSlot":"","KGP":"","KGPV":"","IsRegex":false,"Params":null,"VASTTagFlag":false,"VASTTagFlags":null}},"NonMapped":null,"NewExt":null,"BidCtx":{"bid-id-1":{"prebid":{"meta":{"adaptercode":"pubmatic","advertiserId":4098,"agencyId":4098,"demandSource":"6","mediaType":"banner","networkId":6},"type":"banner","bidid":"bb57a9e3-fdc2-4772-8071-112dd7f50a6a"},"refreshInterval":30,"crtype":"banner","dspid":6,"netecpm":5,"origbidcpm":8,"origbidcur":"USD","EG":0,"EN":0}},"BannerAdUnitCtx":{"MatchedSlot":"","IsRegex":false,"MatchedRegex":"","SelectedSlotAdUnitConfig":null,"AppliedSlotAdUnitConfig":null,"UsingDefaultConfig":false,"AllowedConnectionTypes":null},"VideoAdUnitCtx":{"MatchedSlot":"","IsRegex":false,"MatchedRegex":"","SelectedSlotAdUnitConfig":null,"AppliedSlotAdUnitConfig":null,"UsingDefaultConfig":false,"AllowedConnectionTypes":null},"BidderError":"","IsAdPodRequest":false}},"Aliases":null,"NewReqExt":null,"ResponseExt":{"responsetimemillis":{"pubmatic":8}},"MarketPlaceBidders":null,"AdapterThrottleMap":null,"AdUnitConfig":null,"Source":"","Origin":"","SendAllBids":false,"WinningBids":{"Div1":{"ID":"bid-id-1","NetEcpm":5,"BidDealTierSatisfied":false,"Nbr":null}},"DroppedBids":null,"DefaultBids":{},"SeatNonBids":{},"BidderResponseTimeMillis":{"pubmatic":8},"Endpoint":"","PubIDStr":"5890","ProfileIDStr":"","MetricsEngine":{},"ReturnAllBidStatus":true,"Sshb":"","DCName":"","CachePutMiss":0,"MatchedImpression":{"pubmatic":0},"CustomDimensions":null}]`}, }, err: nil, - bidResponse: json.RawMessage(`{"id":"12345","seatbid":[{"bid":[{"id":"bid-id-1","impid":"Div1","price":5,"adm":"\u003cimg src=\"http://ads.pubmatic.com/AdTag/728x90.png\"\u003e\u003c/img\u003e\u003cdiv style=\"position:absolute;left:0px;top:0px;visibility:hidden;\"\u003e\u003cimg src=\"https://t.pubmatic.com/wt?adv=\u0026af=banner\u0026aps=0\u0026au=%2F43743431%2FDMDemo\u0026bc=appnexus\u0026bidid=4033c510-6d67-4af6-b53f-682ff1a580c3\u0026di=-1\u0026eg=14\u0026en=14\u0026frv=1.57\u0026ft=0\u0026fv=1.57\u0026iid=429d469d-8cfb-495a-9f0c-5f48aa0ede40\u0026kgpv=\u0026orig=ebay.com\u0026origbidid=718825584\u0026pdvid=1\u0026pid=22503\u0026plt=1\u0026pn=appnexus\u0026psz=728x90\u0026pubid=5890\u0026purl=http%3A%2F%2Febay.com%2Finte%2Fautomation%2Fs2s_activation%2Fbanner-with-gdpr-pubmatic-denied-defaultbidder.html%3Fprofileid%3D22503%26pwtv%3D1%26pwtvc%3D1%26appnexus_banner_fixedbid%3D14%26fixedbid%3D1%26debug%3D1\u0026sl=1\u0026slot=%2F43743431%2FDMDemo\u0026ss=1\u0026tgid=0\u0026tst=1704357774\"\u003e\u003c/div\u003e\u003cdiv style=\"position:absolute;left:0px;top:0px;visibility:hidden;\"\u003e\u003cimg src=\"https:?adv=\u0026af=banner\u0026aps=0\u0026au=\u0026bc=pubmatic\u0026bidid=bb57a9e3-fdc2-4772-8071-112dd7f50a6a\u0026di=-1\u0026eg=0\u0026en=0\u0026ft=0\u0026iid=\u0026kgpv=\u0026orig=\u0026origbidid=bid-id-1\u0026pdvid=0\u0026pid=0\u0026plt=0\u0026pn=pubmatic\u0026psz=0x0\u0026pubid=5890\u0026purl=\u0026sl=1\u0026slot=\u0026ss=1\u0026tgid=0\u0026tst=0\"\u003e\u003c/div\u003e","ext":{"prebid":{"meta":{"adaptercode":"pubmatic","advertiserId":4098,"agencyId":4098,"demandSource":"6","mediaType":"banner","networkId":6},"type":"banner","bidid":"bb57a9e3-fdc2-4772-8071-112dd7f50a6a"},"refreshInterval":30,"crtype":"banner","dspid":6,"netecpm":5,"origbidcpm":8,"origbidcur":"USD","ibv":true}}],"seat":"pubmatic"}],"ext":{"responsetimemillis":{"pubmatic":8},"matchedimpression":{"pubmatic":0}}}`), + bidResponse: json.RawMessage(`{"id":"12345","seatbid":[{"bid":[{"id":"bid-id-1","impid":"Div1","price":5,"adm":"\u003cimg src=\"http://ads.pubmatic.com/AdTag/728x90.png\"\u003e\u003c/img\u003e\u003cdiv style=\"position:absolute;left:0px;top:0px;visibility:hidden;\"\u003e\u003cimg src=\"https://t.pubmatic.com/wt?adv=\u0026af=banner\u0026aps=0\u0026au=%2F43743431%2FDMDemo\u0026bc=appnexus\u0026bidid=4033c510-6d67-4af6-b53f-682ff1a580c3\u0026di=-1\u0026eg=14\u0026en=14\u0026frv=1.57\u0026ft=0\u0026fv=1.57\u0026iid=429d469d-8cfb-495a-9f0c-5f48aa0ede40\u0026kgpv=\u0026orig=ebay.com\u0026origbidid=718825584\u0026pdvid=1\u0026pid=22503\u0026plt=1\u0026pn=appnexus\u0026psz=728x90\u0026pubid=5890\u0026purl=http%3A%2F%2Febay.com%2Finte%2Fautomation%2Fs2s_activation%2Fbanner-with-gdpr-pubmatic-denied-defaultbidder.html%3Fprofileid%3D22503%26pwtv%3D1%26pwtvc%3D1%26appnexus_banner_fixedbid%3D14%26fixedbid%3D1%26debug%3D1\u0026sl=1\u0026slot=%2F43743431%2FDMDemo\u0026ss=1\u0026tgid=0\u0026tst=1704357774\"\u003e\u003c/div\u003e\u003cdiv style=\"position:absolute;left:0px;top:0px;visibility:hidden;\"\u003e\u003cimg src=\"https:?adv=\u0026af=banner\u0026aps=0\u0026au=\u0026bc=pubmatic\u0026bidid=bb57a9e3-fdc2-4772-8071-112dd7f50a6a\u0026di=-1\u0026eg=0\u0026en=0\u0026ft=0\u0026iid=\u0026kgpv=\u0026orig=\u0026origbidid=bid-id-1\u0026pdvid=0\u0026pid=0\u0026plt=0\u0026pn=pubmatic\u0026psz=0x0\u0026pubid=5890\u0026purl=\u0026sl=1\u0026slot=\u0026ss=1\u0026tgid=0\u0026tst=0\"\u003e\u003c/div\u003e","ext":{"prebid":{"meta":{"adaptercode":"pubmatic","advertiserId":4098,"agencyId":4098,"demandSource":"6","mediaType":"banner","networkId":6},"type":"banner","bidid":"bb57a9e3-fdc2-4772-8071-112dd7f50a6a"},"refreshInterval":30,"crtype":"banner","dspid":6,"netecpm":5,"origbidcpm":8,"origbidcur":"USD","ibv":true,"clicktrackers":["http://clicktracker1.com","http://clicktracker2.com"]}}],"seat":"pubmatic"}],"ext":{"responsetimemillis":{"pubmatic":8},"matchedimpression":{"pubmatic":0}}}`), }, }, { @@ -1761,7 +1761,7 @@ func TestOpenWrapHandleAuctionResponseHook(t *testing.T) { ImpID: "Div1", Price: 5, AdM: "", - Ext: json.RawMessage(`{"bidtype":0,"deal_channel":1,"dspid":6,"mbmfv":4,"origbidcpm":8,"origbidcur":"USD","prebid":{"bidid":"bb57a9e3-fdc2-4772-8071-112dd7f50a6a","meta":{"adaptercode":"pubmatic","advertiserId":4098,"agencyId":4098,"demandSource":"6","mediaType":"banner","networkId":6},"targeting":{"hb_bidder_pubmatic":"pubmatic","hb_deal_pubmatic":"PUBDEAL1","hb_pb_pubmatic":"8.00","hb_size_pubmatic":"728x90"},"type":"video","video":{"duration":0,"primary_category":"","vasttagid":""}}}`), + Ext: json.RawMessage(`{"bidtype":0,"deal_channel":1,"dspid":6,"mbmfv":4,"origbidcpm":8,"origbidcur":"USD","prebid":{"bidid":"bb57a9e3-fdc2-4772-8071-112dd7f50a6a","meta":{"adaptercode":"pubmatic","advertiserId":4098,"agencyId":4098,"demandSource":"6","mediaType":"banner","networkId":6},"targeting":{"hb_bidder_pubmatic":"pubmatic","hb_deal_pubmatic":"PUBDEAL1","hb_pb_pubmatic":"8.00","hb_size_pubmatic":"728x90"},"type":"video","video":{"duration":0,"primary_category":"","vasttagid":""}},"clicktrackers":["http://clicktracker1.com","http://clicktracker2.com"]}`), }, }, Seat: "pubmatic", diff --git a/modules/pubmatic/openwrap/models/response.go b/modules/pubmatic/openwrap/models/response.go index c6b0ff4acaf..60a6fdf6fcd 100644 --- a/modules/pubmatic/openwrap/models/response.go +++ b/modules/pubmatic/openwrap/models/response.go @@ -30,6 +30,7 @@ type BidExt struct { AdPod *AdpodBidExt `json:"adpod,omitempty"` MultiBidMultiFloorValue float64 `json:"-"` InBannerVideo bool `json:"ibv,omitempty"` + ClickTrackers []string `json:"clicktrackers,omitempty"` } type AdpodBidExt struct { From 15dd2c5b9c2f16193211a6e7af4a4bd0d7d89d86 Mon Sep 17 00:00:00 2001 From: Saurabh Narkhede <108730956+pm-saurabh-narkhede@users.noreply.github.com> Date: Wed, 18 Dec 2024 17:13:39 +0530 Subject: [PATCH 2/5] UOE-11303: Add MultiBid-MultiFloor Enabled Flag in Logger and Tracker (#982) --- analytics/pubmatic/logger.go | 43 ++-- analytics/pubmatic/logger_test.go | 55 ++--- analytics/pubmatic/record.go | 9 +- .../openwrap/auctionresponsehook_test.go | 2 +- modules/pubmatic/openwrap/models/tracker.go | 33 +-- modules/pubmatic/openwrap/models/tracking.go | 95 ++++----- modules/pubmatic/openwrap/tracker/create.go | 38 ++-- .../pubmatic/openwrap/tracker/create_test.go | 190 ++++++++++++++++++ 8 files changed, 337 insertions(+), 128 deletions(-) diff --git a/analytics/pubmatic/logger.go b/analytics/pubmatic/logger.go index 569740069c0..979a9612aa6 100644 --- a/analytics/pubmatic/logger.go +++ b/analytics/pubmatic/logger.go @@ -414,25 +414,30 @@ func getPartnerRecordsByImp(ao analytics.AuctionObject, rCtx *models.RequestCtx) } pr := PartnerRecord{ - PartnerID: partnerID, // prebid biddercode - BidderCode: seat, // pubmatic biddercode: pubmatic2 - Latency1: rCtx.BidderResponseTimeMillis[seat], // it is set inside auctionresponsehook for all bidders - KGPV: kgpv, - KGPSV: kgpsv, - BidID: utils.GetOriginalBidId(bid.ID), - OrigBidID: utils.GetOriginalBidId(bid.ID), - DefaultBidStatus: 0, // this will be always 0 , decide whether to drop this field in future - ServerSide: 1, - MatchedImpression: rCtx.MatchedImpression[seat], - OriginalCPM: models.GetGrossEcpm(bidExt.OriginalBidCPM), - OriginalCur: bidExt.OriginalBidCur, - DealID: bid.DealID, - Nbr: nbr, - Adformat: adFormat, - NetECPM: tracker.Tracker.PartnerInfo.NetECPM, - GrossECPM: tracker.Tracker.PartnerInfo.GrossECPM, - PartnerSize: tracker.Tracker.PartnerInfo.AdSize, - ADomain: tracker.Tracker.PartnerInfo.Advertiser, + PartnerID: partnerID, // prebid biddercode + BidderCode: seat, // pubmatic biddercode: pubmatic2 + Latency1: rCtx.BidderResponseTimeMillis[seat], // it is set inside auctionresponsehook for all bidders + KGPV: kgpv, + KGPSV: kgpsv, + BidID: utils.GetOriginalBidId(bid.ID), + OrigBidID: utils.GetOriginalBidId(bid.ID), + DefaultBidStatus: 0, // this will be always 0 , decide whether to drop this field in future + ServerSide: 1, + MatchedImpression: rCtx.MatchedImpression[seat], + OriginalCPM: models.GetGrossEcpm(bidExt.OriginalBidCPM), + OriginalCur: bidExt.OriginalBidCur, + DealID: bid.DealID, + Nbr: nbr, + Adformat: adFormat, + NetECPM: tracker.Tracker.PartnerInfo.NetECPM, + GrossECPM: tracker.Tracker.PartnerInfo.GrossECPM, + PartnerSize: tracker.Tracker.PartnerInfo.AdSize, + ADomain: tracker.Tracker.PartnerInfo.Advertiser, + MultiBidMultiFloorFlag: tracker.Tracker.PartnerInfo.MultiBidMultiFloorFlag, + } + + if pr.MultiBidMultiFloorFlag == 0 && bidExt.MultiBidMultiFloorValue > 0 { + pr.MultiBidMultiFloorFlag = 1 } if pr.NetECPM == 0 { diff --git a/analytics/pubmatic/logger_test.go b/analytics/pubmatic/logger_test.go index 65d2e6d048e..72001e92346 100644 --- a/analytics/pubmatic/logger_test.go +++ b/analytics/pubmatic/logger_test.go @@ -695,15 +695,16 @@ func TestGetPartnerRecordsByImpForTracker(t *testing.T) { "bid-id-1": { Tracker: models.Tracker{ PartnerInfo: models.Partner{ - Adformat: models.Native, - KGPV: "kgpv", - NetECPM: 10, - GrossECPM: 12, - AdSize: "15x15", - FloorValue: 1, - FloorRuleValue: 2, - Advertiser: "sony.com", - PriceBucket: "10.00", + Adformat: models.Native, + KGPV: "kgpv", + NetECPM: 10, + GrossECPM: 12, + AdSize: "15x15", + FloorValue: 1, + FloorRuleValue: 2, + Advertiser: "sony.com", + PriceBucket: "10.00", + MultiBidMultiFloorFlag: 1, }, LoggerData: models.LoggerData{ KGPSV: "kgpsv", @@ -728,23 +729,24 @@ func TestGetPartnerRecordsByImpForTracker(t *testing.T) { partners: map[string][]PartnerRecord{ "imp1": { { - PartnerID: "pubmatic", - BidderCode: "pubmatic", - PartnerSize: "15x15", - BidID: "bid-id-1", - OrigBidID: "bid-id-1", - DealID: "-1", - ServerSide: 1, - OriginalCur: "USD", - Adformat: models.Native, - NetECPM: 10, - GrossECPM: 12, - FloorValue: 1, - FloorRuleValue: 2, - ADomain: "sony.com", - KGPV: "kgpv", - KGPSV: "kgpsv", - PriceBucket: "10.00", + PartnerID: "pubmatic", + BidderCode: "pubmatic", + PartnerSize: "15x15", + BidID: "bid-id-1", + OrigBidID: "bid-id-1", + DealID: "-1", + ServerSide: 1, + OriginalCur: "USD", + Adformat: models.Native, + NetECPM: 10, + GrossECPM: 12, + FloorValue: 1, + FloorRuleValue: 2, + ADomain: "sony.com", + KGPV: "kgpv", + KGPSV: "kgpsv", + PriceBucket: "10.00", + MultiBidMultiFloorFlag: 1, }, }, }, @@ -1029,6 +1031,7 @@ func TestGetPartnerRecordsByImpForDefaultBids(t *testing.T) { }, }, }, + TagID: "adunit_1234", }, }, }, diff --git a/analytics/pubmatic/record.go b/analytics/pubmatic/record.go index ebdd1a5f9d3..0f8e2692f6d 100644 --- a/analytics/pubmatic/record.go +++ b/analytics/pubmatic/record.go @@ -144,10 +144,11 @@ type PartnerRecord struct { OriginalCur string `json:"ocry"` MetaData *MetaData `json:"md,omitempty"` - FloorValue float64 `json:"fv,omitempty"` - FloorRuleValue float64 `json:"frv,omitempty"` - Nbr *openrtb3.NoBidReason `json:"nbr,omitempty"` // NonBR reason code - PriceBucket string `json:"pb,omitempty"` + FloorValue float64 `json:"fv,omitempty"` + FloorRuleValue float64 `json:"frv,omitempty"` + Nbr *openrtb3.NoBidReason `json:"nbr,omitempty"` // NonBR reason code + PriceBucket string `json:"pb,omitempty"` + MultiBidMultiFloorFlag int `json:"mbmf,omitempty"` } type MetaData struct { diff --git a/modules/pubmatic/openwrap/auctionresponsehook_test.go b/modules/pubmatic/openwrap/auctionresponsehook_test.go index 68fd47b2020..4201a4e8a59 100644 --- a/modules/pubmatic/openwrap/auctionresponsehook_test.go +++ b/modules/pubmatic/openwrap/auctionresponsehook_test.go @@ -1785,7 +1785,7 @@ func TestOpenWrapHandleAuctionResponseHook(t *testing.T) { want: want{ result: hookstage.HookResult[hookstage.AuctionResponsePayload]{}, err: nil, - bidResponse: json.RawMessage(`{"id":"12345","seatbid":[{"bid":[{"id":"bid-id-1","impid":"Div1","price":5,"adm":"\u003cVAST version=\"3.0\"\u003e\u003cAd\u003e\u003cWrapper\u003e\u003cImpression\u003e\u003c![CDATA[https:?adv=\u0026af=video\u0026aps=0\u0026au=\u0026bc=pubmatic\u0026bidid=bb57a9e3-fdc2-4772-8071-112dd7f50a6a\u0026di=-1\u0026dur=20\u0026eg=0\u0026en=0\u0026frv=4\u0026ft=0\u0026fv=4\u0026iid=\u0026kgpv=\u0026orig=\u0026origbidid=bid-id-1\u0026pdvid=0\u0026pid=0\u0026plt=0\u0026pn=pubmatic\u0026psz=0x0\u0026pubid=5890\u0026purl=\u0026sl=1\u0026slot=\u0026ss=1\u0026tgid=0\u0026tst=0]]\u003e\u003c/Impression\u003e\u003cExtensions\u003e\u003cExtension\u003e\u003cPricing model=\"CPM\" currency=\"USD\"\u003e\u003c![CDATA[5]]\u003e\u003c/Pricing\u003e\u003c/Extension\u003e\u003c/Extensions\u003e\u003c/Wrapper\u003e\u003c/Ad\u003e\u003c/VAST\u003e","ext":{"prebid":{"meta":{"adaptercode":"pubmatic","advertiserId":4098,"agencyId":4098,"demandSource":"6","mediaType":"banner","networkId":6},"type":"video","video":{"duration":20,"primary_category":"","vasttagid":""},"bidid":"bb57a9e3-fdc2-4772-8071-112dd7f50a6a"},"refreshInterval":30,"crtype":"video","video":{"minduration":10,"maxduration":20,"skip":1,"skipmin":1,"skipafter":2,"battr":[1],"playbackmethod":[1]},"dspid":6,"netecpm":5,"origbidcpm":8,"origbidcur":"USD"}}],"seat":"pubmatic"}],"ext":{"responsetimemillis":{"pubmatic":8},"matchedimpression":{"pubmatic":0}}}`), + bidResponse: json.RawMessage(`{"id":"12345","seatbid":[{"bid":[{"id":"bid-id-1","impid":"Div1","price":5,"adm":"\u003cVAST version=\"3.0\"\u003e\u003cAd\u003e\u003cWrapper\u003e\u003cImpression\u003e\u003c![CDATA[https:?adv=\u0026af=video\u0026aps=0\u0026au=\u0026bc=pubmatic\u0026bidid=bb57a9e3-fdc2-4772-8071-112dd7f50a6a\u0026di=-1\u0026dur=20\u0026eg=0\u0026en=0\u0026frv=4\u0026ft=0\u0026fv=4\u0026iid=\u0026kgpv=\u0026mbmf=1\u0026orig=\u0026origbidid=bid-id-1\u0026pdvid=0\u0026pid=0\u0026plt=0\u0026pn=pubmatic\u0026psz=0x0\u0026pubid=5890\u0026purl=\u0026sl=1\u0026slot=\u0026ss=1\u0026tgid=0\u0026tst=0]]\u003e\u003c/Impression\u003e\u003cExtensions\u003e\u003cExtension\u003e\u003cPricing model=\"CPM\" currency=\"USD\"\u003e\u003c![CDATA[5]]\u003e\u003c/Pricing\u003e\u003c/Extension\u003e\u003c/Extensions\u003e\u003c/Wrapper\u003e\u003c/Ad\u003e\u003c/VAST\u003e","ext":{"prebid":{"meta":{"adaptercode":"pubmatic","advertiserId":4098,"agencyId":4098,"demandSource":"6","mediaType":"banner","networkId":6},"type":"video","video":{"duration":20,"primary_category":"","vasttagid":""},"bidid":"bb57a9e3-fdc2-4772-8071-112dd7f50a6a"},"refreshInterval":30,"crtype":"video","video":{"minduration":10,"maxduration":20,"skip":1,"skipmin":1,"skipafter":2,"battr":[1],"playbackmethod":[1]},"dspid":6,"netecpm":5,"origbidcpm":8,"origbidcur":"USD"}}],"seat":"pubmatic"}],"ext":{"responsetimemillis":{"pubmatic":8},"matchedimpression":{"pubmatic":0}}}`), }, }, } diff --git a/modules/pubmatic/openwrap/models/tracker.go b/modules/pubmatic/openwrap/models/tracker.go index 74822a37cb3..54c0eaaed89 100644 --- a/modules/pubmatic/openwrap/models/tracker.go +++ b/modules/pubmatic/openwrap/models/tracker.go @@ -46,22 +46,23 @@ type Tracker struct { // Partner partner information to be logged in tracker object type Partner struct { - PartnerID string - BidderCode string - KGPV string - GrossECPM float64 - NetECPM float64 - BidID string - OrigBidID string - AdSize string - AdDuration int - Adformat string - ServerSide int - Advertiser string - FloorValue float64 - FloorRuleValue float64 - DealID string - PriceBucket string + PartnerID string + BidderCode string + KGPV string + GrossECPM float64 + NetECPM float64 + BidID string + OrigBidID string + AdSize string + AdDuration int + Adformat string + ServerSide int + Advertiser string + FloorValue float64 + FloorRuleValue float64 + DealID string + PriceBucket string + MultiBidMultiFloorFlag int } // LoggerData: this data to be needed in logger diff --git a/modules/pubmatic/openwrap/models/tracking.go b/modules/pubmatic/openwrap/models/tracking.go index 0c202f5d613..104552b9c3d 100644 --- a/modules/pubmatic/openwrap/models/tracking.go +++ b/modules/pubmatic/openwrap/models/tracking.go @@ -5,53 +5,54 @@ import "github.com/prebid/prebid-server/v2/openrtb_ext" // impression tracker url parameters const ( // constants for query parameter names for tracker call - TRKPubID = "pubid" - TRKPageURL = "purl" - TRKTimestamp = "tst" - TRKIID = "iid" - TRKProfileID = "pid" - TRKVersionID = "pdvid" - TRKIP = "ip" - TRKUserAgent = "ua" - TRKSlotID = "slot" - TRKAdunit = "au" - TRKRewardedInventory = "rwrd" - TRKPartnerID = "pn" - TRKBidderCode = "bc" - TRKKGPV = "kgpv" - TRKGrossECPM = "eg" - TRKNetECPM = "en" - TRKBidID = "bidid" - TRKOrigBidID = "origbidid" - TRKQMARK = "?" - TRKAmpersand = "&" - TRKSSAI = "ssai" - TRKPlatform = "plt" - TRKAdSize = "psz" - TRKTestGroup = "tgid" - TRKAdvertiser = "adv" - TRKPubDomain = "orig" - TRKServerSide = "ss" - TRKAdformat = "af" - TRKAdDuration = "dur" - TRKAdPodExist = "aps" - TRKFloorType = "ft" - TRKFloorModelVersion = "fmv" - TRKFloorProvider = "fp" - TRKFloorSkippedFlag = "fskp" - TRKFloorSource = "fsrc" - TRKFloorValue = "fv" - TRKFloorRuleValue = "frv" - TRKServerLogger = "sl" - TRKDealID = "di" - TRKCustomDimensions = "cds" - TRKATTS = "atts" - TRKProfileType = "pt" - TRKProfileTypePlatform = "ptp" - TRKAppPlatform = "ap" - TRKAppIntegrationPath = "aip" - TRKAppSubIntegrationPath = "asip" - TRKPriceBucket = "pb" + TRKPubID = "pubid" + TRKPageURL = "purl" + TRKTimestamp = "tst" + TRKIID = "iid" + TRKProfileID = "pid" + TRKVersionID = "pdvid" + TRKIP = "ip" + TRKUserAgent = "ua" + TRKSlotID = "slot" + TRKAdunit = "au" + TRKRewardedInventory = "rwrd" + TRKPartnerID = "pn" + TRKBidderCode = "bc" + TRKKGPV = "kgpv" + TRKGrossECPM = "eg" + TRKNetECPM = "en" + TRKBidID = "bidid" + TRKOrigBidID = "origbidid" + TRKQMARK = "?" + TRKAmpersand = "&" + TRKSSAI = "ssai" + TRKPlatform = "plt" + TRKAdSize = "psz" + TRKTestGroup = "tgid" + TRKAdvertiser = "adv" + TRKPubDomain = "orig" + TRKServerSide = "ss" + TRKAdformat = "af" + TRKAdDuration = "dur" + TRKAdPodExist = "aps" + TRKFloorType = "ft" + TRKFloorModelVersion = "fmv" + TRKFloorProvider = "fp" + TRKFloorSkippedFlag = "fskp" + TRKFloorSource = "fsrc" + TRKFloorValue = "fv" + TRKFloorRuleValue = "frv" + TRKServerLogger = "sl" + TRKDealID = "di" + TRKCustomDimensions = "cds" + TRKATTS = "atts" + TRKProfileType = "pt" + TRKProfileTypePlatform = "ptp" + TRKAppPlatform = "ap" + TRKAppIntegrationPath = "aip" + TRKAppSubIntegrationPath = "asip" + TRKPriceBucket = "pb" + TRKMultiBidMultiFloorFlag = "mbmf" ) // video error tracker url parameters diff --git a/modules/pubmatic/openwrap/tracker/create.go b/modules/pubmatic/openwrap/tracker/create.go index 8354fd7030a..5537b8c6a31 100644 --- a/modules/pubmatic/openwrap/tracker/create.go +++ b/modules/pubmatic/openwrap/tracker/create.go @@ -88,7 +88,7 @@ func createTrackers(rctx models.RequestCtx, trackers map[string]models.OWTracker floorValue, floorRuleValue = float64(0), float64(0) partnerID = seatBid.Seat isRewardInventory, adduration = 0, 0 - dspId int + dspId, mbmfFlag int eg, en float64 ) @@ -107,6 +107,10 @@ func createTrackers(rctx models.RequestCtx, trackers map[string]models.OWTracker // TODO do most calculation in wt // marketplace/alternatebiddercodes feature bidExt := bidCtx.BidExt + if bidExt.MultiBidMultiFloorValue > 0 { + mbmfFlag = 1 + } + if bidExt.Prebid != nil { if bidExt.Prebid.Video != nil && bidExt.Prebid.Video.Duration > 0 { adduration = bidExt.Prebid.Video.Duration @@ -167,20 +171,21 @@ func createTrackers(rctx models.RequestCtx, trackers map[string]models.OWTracker tracker.RewardedInventory = isRewardInventory tracker.PartnerInfo = models.Partner{ - PartnerID: partnerID, - BidderCode: seatBid.Seat, - BidID: utils.GetOriginalBidId(bid.ID), - OrigBidID: utils.GetOriginalBidId(bid.ID), - KGPV: kgpv, - NetECPM: en, - GrossECPM: eg, - AdSize: models.GetSizeForPlatform(bid.W, bid.H, rctx.Platform), - AdDuration: adduration, - Adformat: adformat, - ServerSide: 1, - FloorValue: floorValue, - FloorRuleValue: floorRuleValue, - DealID: "-1", + PartnerID: partnerID, + BidderCode: seatBid.Seat, + BidID: utils.GetOriginalBidId(bid.ID), + OrigBidID: utils.GetOriginalBidId(bid.ID), + KGPV: kgpv, + NetECPM: en, + GrossECPM: eg, + AdSize: models.GetSizeForPlatform(bid.W, bid.H, rctx.Platform), + AdDuration: adduration, + Adformat: adformat, + ServerSide: 1, + FloorValue: floorValue, + FloorRuleValue: floorRuleValue, + DealID: "-1", + MultiBidMultiFloorFlag: mbmfFlag, } if rctx.PriceGranularity != nil { tracker.PartnerInfo.PriceBucket = exchange.GetPriceBucketOW(bid.Price, *rctx.PriceGranularity) @@ -293,6 +298,9 @@ func constructTrackerURL(rctx models.RequestCtx, tracker models.Tracker) string if tracker.PartnerInfo.PriceBucket != "" { v.Set(models.TRKPriceBucket, tracker.PartnerInfo.PriceBucket) } + if tracker.PartnerInfo.MultiBidMultiFloorFlag == 1 { + v.Set(models.TRKMultiBidMultiFloorFlag, strconv.Itoa(tracker.PartnerInfo.MultiBidMultiFloorFlag)) + } //ProfileMetadata parameters if rctx.ProfileType > 0 { diff --git a/modules/pubmatic/openwrap/tracker/create_test.go b/modules/pubmatic/openwrap/tracker/create_test.go index 6b899335acd..3e5f7c89086 100644 --- a/modules/pubmatic/openwrap/tracker/create_test.go +++ b/modules/pubmatic/openwrap/tracker/create_test.go @@ -267,6 +267,149 @@ func Test_createTrackers(t *testing.T) { }, }, }, + { + name: "response with all details and multibid-multifloor feature enabled", + args: args{ + trackers: map[string]models.OWTracker{}, + rctx: func() models.RequestCtx { + testRctx := rctx + testRctx.StartTime = startTime + pg, _ := openrtb_ext.NewPriceGranularityFromLegacyID("med") + testRctx.PriceGranularity = &pg + testRctx.AppLovinMax = models.AppLovinMax{ + MultiFloorsConfig: models.MultiFloorsConfig{ + Enabled: true, + Config: models.ApplovinAdUnitFloors{ + "adunit-1": []float64{1.2, 1.3, 1.4}, + }, + }, + } + testRctx.ImpBidCtx = map[string]models.ImpCtx{ + "impID-1": { + TagID: "adunit-1", + AdUnitName: "adunit-1", + SlotName: "impID-1_adunit-1", + Bidders: map[string]models.PartnerData{ + "pubmatic": { + MatchedSlot: "matchedSlot", + PrebidBidderCode: "prebidBidderCode", + KGP: "_AU_@_W_x_H_", + }, + "pubmatic2": { + MatchedSlot: "matchedSlot2", + PrebidBidderCode: "prebidBidderCode2", + KGP: "_AU_@_W_x_H_", + }, + }, + BidFloor: 5.5, + BidFloorCur: "EUR", + BidCtx: map[string]models.BidCtx{ + "bidID-1": { + EG: 8.7, + EN: 8.7, + BidExt: models.BidExt{ + OriginalBidCPMUSD: 0, + ExtBid: openrtb_ext.ExtBid{ + Prebid: &openrtb_ext.ExtBidPrebid{ + BidId: "bidID-1", + Video: &openrtb_ext.ExtBidPrebidVideo{ + Duration: 20, + }, + Meta: &openrtb_ext.ExtBidPrebidMeta{ + AdapterCode: "pubmatic", + }, + Floors: &openrtb_ext.ExtBidPrebidFloors{ + FloorRule: "rule1", + FloorValue: 6.4, + FloorRuleValue: 4.4, + }, + Type: models.Banner, + }, + }, + MultiBidMultiFloorValue: 4.5, + }, + }, + }, + }, + } + testRctx.DeviceCtx.Ext = func() *models.ExtDevice { + extDevice := models.ExtDevice{} + extDevice.UnmarshalJSON([]byte(`{"atts":1}`)) + return &extDevice + }() + return testRctx + }(), + bidResponse: &openrtb2.BidResponse{ + SeatBid: []openrtb2.SeatBid{ + { + Bid: []openrtb2.Bid{ + { + ID: "bidID-1", + ImpID: "impID-1", + Price: 8.7, + W: 250, + H: 300, + ADomain: []string{"domain.com"}, + DealID: "deal-id-1", + }, + }, + Seat: "pubmatic", + }, + }, + Cur: models.USD, + }, + pmMkt: map[string]pubmaticMarketplaceMeta{}, + }, + want: map[string]models.OWTracker{ + "bidID-1": { + Tracker: models.Tracker{ + PubID: 5890, + PageURL: "abc.com", + Timestamp: startTime, + IID: "loggerIID", + ProfileID: "1234", + VersionID: "1", + Adunit: "adunit-1", + SlotID: "impID-1_adunit-1", + PartnerInfo: models.Partner{ + PartnerID: "prebidBidderCode", + BidderCode: "pubmatic", + KGPV: "adunit-1@250x300", + GrossECPM: 8.7, + NetECPM: 8.7, + BidID: "bidID-1", + OrigBidID: "bidID-1", + AdSize: "250x300", + AdDuration: 20, + Adformat: "banner", + ServerSide: 1, + Advertiser: "domain.com", + FloorValue: 4.5, + FloorRuleValue: 4.5, + DealID: "deal-id-1", + PriceBucket: "8.60", + MultiBidMultiFloorFlag: 1, + }, + Platform: 5, + SSAI: "mediatailor", + AdPodSlot: 0, + TestGroup: 1, + Origin: "publisher.com", + ImpID: "impID-1", + LoggerData: models.LoggerData{ + KGPSV: "adunit-1@250x300", + }, + CustomDimensions: "author=henry", + ATTS: ptrutil.ToPtr(float64(openrtb_ext.IOSAppTrackingStatusRestricted)), + }, + TrackerURL: "https:?adv=domain.com&af=banner&aps=0&atts=1&au=adunit-1&bc=pubmatic&bidid=bidID-1&cds=author%3Dhenry&di=deal-id-1&dur=20&eg=8.7&en=8.7&frv=4.5&ft=0&fv=4.5&iid=loggerIID&kgpv=adunit-1%40250x300&mbmf=1&orig=publisher.com&origbidid=bidID-1&pb=8.60&pdvid=1&pid=1234&plt=5&pn=prebidBidderCode&psz=250x300&pubid=5890&purl=abc.com&sl=1&slot=impID-1_adunit-1&ss=1&ssai=mediatailor&tgid=1&tst=" + strconv.FormatInt(startTime, 10), + Price: 8.7, + PriceModel: "CPM", + PriceCurrency: "USD", + BidType: "banner", + }, + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -559,6 +702,53 @@ func TestConstructTrackerURL(t *testing.T) { }, want: "//t.pubmatic.com/wt?adv=&af=&aip=3&ap=5&aps=0&asip=8&au=&bc=&bidid=&di=&eg=0&en=0&ft=0&iid=&kgpv=&orig=&origbidid=&pdvid=&pid=&plt=0&pn=&psz=&pt=1&ptp=4&pubid=0&purl=&sl=1&slot=&ss=0&tgid=0&tst=0", }, + { + name: "all_floors_details_in_tracker_multiBidMultiFloor_enabled", + args: args{ + rctx: models.RequestCtx{ + TrackerEndpoint: "//t.pubmatic.com/wt", + Platform: models.PLATFORM_APP, + }, + tracker: models.Tracker{ + PubID: 12345, + PageURL: "www.abc.com", + IID: "98765", + ProfileID: "123", + VersionID: "1", + SlotID: "1234_1234", + Adunit: "adunit", + Platform: 1, + Origin: "www.publisher.com", + TestGroup: 1, + AdPodSlot: 0, + FloorSkippedFlag: ptrutil.ToPtr(0), + FloorModelVersion: "test version", + FloorSource: ptrutil.ToPtr(1), + FloorType: 1, + CustomDimensions: "traffic=media;age=23", + PartnerInfo: models.Partner{ + PartnerID: "AppNexus", + BidderCode: "AppNexus1", + BidID: "6521", + OrigBidID: "6521", + GrossECPM: 4.3, + NetECPM: 2.5, + KGPV: "adunit@300x250", + AdDuration: 10, + Adformat: models.Banner, + AdSize: "300x250", + ServerSide: 1, + Advertiser: "fb.com", + DealID: "420", + FloorValue: 4.5, + FloorRuleValue: 4.5, + PriceBucket: "2.50", + MultiBidMultiFloorFlag: 1, + }, + }, + }, + want: "//t.pubmatic.com/wt?adv=fb.com&af=banner&aps=0&au=adunit&bc=AppNexus1&bidid=6521&cds=traffic=media;age=23&di=420&dur=10&eg=4.3&en=2.5&fmv=test version&frv=4.5&fskp=0&fsrc=1&ft=1&fv=4.5&iid=98765&kgpv=adunit@300x250&mbmf=1&orig=www.publisher.com&origbidid=6521&pb=2.50&pdvid=1&pid=123&plt=1&pn=AppNexus&psz=300x250&pubid=12345&purl=www.abc.com&sl=1&slot=1234_1234&ss=1&tgid=1&tst=0", + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { From f6320a8e99fb200861d4b28826be1fe6f62892bf Mon Sep 17 00:00:00 2001 From: Saurabh Narkhede <108730956+pm-saurabh-narkhede@users.noreply.github.com> Date: Mon, 30 Dec 2024 16:57:21 +0530 Subject: [PATCH 3/5] UOE-11650: Add Builder for Compass Bidder (#989) --- modules/pubmatic/openwrap/adapters/bidders.go | 19 ++++++++ .../openwrap/adapters/bidders_test.go | 47 +++++++++++++++++++ modules/pubmatic/openwrap/adapters/builder.go | 1 + .../openwrap/adapters/tests/s2s_bidders.json | 15 ++++++ 4 files changed, 82 insertions(+) diff --git a/modules/pubmatic/openwrap/adapters/bidders.go b/modules/pubmatic/openwrap/adapters/bidders.go index 678dc601ec8..d8feb482c81 100644 --- a/modules/pubmatic/openwrap/adapters/bidders.go +++ b/modules/pubmatic/openwrap/adapters/bidders.go @@ -730,3 +730,22 @@ func builderAidem(params BidderParameters) (json.RawMessage, error) { return jsonStr.Bytes(), nil } + +func builderCompass(params BidderParameters) (json.RawMessage, error) { + jsonStr := bytes.Buffer{} + jsonStr.WriteByte('{') + oneOf := []string{"placementId", "endpointId"} + for _, param := range oneOf { + if key, ok := getString(params.FieldMap[param]); ok { + fmt.Fprintf(&jsonStr, `"%s":"%s"`, param, key) + break + } + } + // len=0 (no mandatory params present) + if jsonStr.Len() == 1 { + return nil, fmt.Errorf(errMandatoryParameterMissingFormat, params.AdapterName, oneOf) + } + + jsonStr.WriteByte('}') + return jsonStr.Bytes(), nil +} diff --git a/modules/pubmatic/openwrap/adapters/bidders_test.go b/modules/pubmatic/openwrap/adapters/bidders_test.go index 08c01d55a5c..52783889c68 100644 --- a/modules/pubmatic/openwrap/adapters/bidders_test.go +++ b/modules/pubmatic/openwrap/adapters/bidders_test.go @@ -3119,3 +3119,50 @@ func Test_builderAidem(t *testing.T) { }) } } + +func TestBuilderCompass(t *testing.T) { + type args struct { + params BidderParameters + } + tests := []struct { + name string + args args + want json.RawMessage + wantErr bool + }{ + { + name: "Valid Scenerio (oneOf placementId or endpointId) is present-placementId", + args: args{params: BidderParameters{FieldMap: JSONObject{"placementId": "dbdsfh"}}}, + want: json.RawMessage(`{"placementId": "dbdsfh"}`), + wantErr: false, + }, + { + name: "Valid Scenerio (oneOf placementId or endpointId) is present-endpointId", + args: args{params: BidderParameters{FieldMap: JSONObject{"endpointId": "dbdsfh"}}}, + want: json.RawMessage(`{"endpointId": "dbdsfh"}`), + wantErr: false, + }, + { + name: "Valid Scenerio (oneOf placementId or endpointId), Both are present", + args: args{params: BidderParameters{FieldMap: JSONObject{"placementId": "sdhks", "endpointId": "sdjksd"}}}, + want: json.RawMessage(`{"placementId": "sdhks"}`), + wantErr: false, + }, + { + name: "Invalid Scenerio (None Of placementId or endpointId) is present", + args: args{params: BidderParameters{FieldMap: JSONObject{}}}, + want: json.RawMessage(``), + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := builderCompass(tt.args.params) + if (err != nil) != tt.wantErr { + t.Errorf("builderCompass() error = %v, wantErr %v", err, tt.wantErr) + return + } + AssertJSON(t, tt.want, got) + }) + } +} diff --git a/modules/pubmatic/openwrap/adapters/builder.go b/modules/pubmatic/openwrap/adapters/builder.go index 23ce21b68b7..c2996005017 100644 --- a/modules/pubmatic/openwrap/adapters/builder.go +++ b/modules/pubmatic/openwrap/adapters/builder.go @@ -59,6 +59,7 @@ func initBidderBuilderFactory() { string(openrtb_ext.BidderKargo): builderKargo, string(openrtb_ext.BidderPGAMSsp): builderPGAMSSP, string(openrtb_ext.BidderAidem): builderAidem, + string(openrtb_ext.BidderCompass): builderCompass, } } diff --git a/modules/pubmatic/openwrap/adapters/tests/s2s_bidders.json b/modules/pubmatic/openwrap/adapters/tests/s2s_bidders.json index 12cefbbf095..9a0d55a1bbe 100644 --- a/modules/pubmatic/openwrap/adapters/tests/s2s_bidders.json +++ b/modules/pubmatic/openwrap/adapters/tests/s2s_bidders.json @@ -136,5 +136,20 @@ "siteId":"abcdefg" } } + }, + { + "name": "compass_json_OneOf - placementId/endpointId", + "args" : { + "adapterName": "compass", + "requestJSON": { + "placementId": "123456", + "endpointId": "abcdefg" + } + }, + "want": { + "expectedJSON": { + "placementId": "123456" + } + } } ] \ No newline at end of file From 51785f4607d9d2a7bfe9b020e30b9d87e293173e Mon Sep 17 00:00:00 2001 From: Pubmatic-Supriya-Patil <131644110+Pubmatic-Supriya-Patil@users.noreply.github.com> Date: Tue, 7 Jan 2025 17:32:28 +0530 Subject: [PATCH 4/5] UOE-11749: AdbreakId support for smaato bidder (#986) --- go.mod | 2 +- go.sum | 1 + modules/pubmatic/openwrap/adapters/bidders.go | 16 ++-- .../openwrap/adapters/bidders_test.go | 79 +++++++++++++++++-- 4 files changed, 82 insertions(+), 16 deletions(-) diff --git a/go.mod b/go.mod index 95df10bfc77..0480d5e46cf 100644 --- a/go.mod +++ b/go.mod @@ -52,7 +52,6 @@ require ( git.pubmatic.com/PubMatic/go-netacuity-client v0.0.0-20240104092757-5d6f15e25fe3 git.pubmatic.com/vastunwrap v0.0.0-00010101000000-000000000000 github.com/PubMatic-OpenWrap/fastxml v0.0.0-20241125102315-0d8f851a6e52 - github.com/beevik/etree/110 v0.0.0-00010101000000-000000000000 github.com/diegoholiveira/jsonlogic/v3 v3.5.3 github.com/go-sql-driver/mysql v1.7.1 github.com/golang/mock v1.6.0 @@ -89,6 +88,7 @@ require ( github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect + github.com/yudai/pp v2.0.1+incompatible // indirect golang.org/x/crypto v0.21.0 // indirect golang.org/x/sys v0.18.0 // indirect google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect diff --git a/go.sum b/go.sum index b5d85f1ecb8..9dd291e2969 100644 --- a/go.sum +++ b/go.sum @@ -519,6 +519,7 @@ github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FB github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3IfnEUduWvb9is428/nNb5L3U01M= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= github.com/yudai/pp v2.0.1+incompatible h1:Q4//iY4pNF6yPLZIigmvcl7k/bPgrcTPIFIcmawg5bI= +github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= diff --git a/modules/pubmatic/openwrap/adapters/bidders.go b/modules/pubmatic/openwrap/adapters/bidders.go index d8feb482c81..293870fa026 100644 --- a/modules/pubmatic/openwrap/adapters/bidders.go +++ b/modules/pubmatic/openwrap/adapters/bidders.go @@ -381,16 +381,18 @@ func builderSmaato(params BidderParameters) (json.RawMessage, error) { jsonStr := bytes.Buffer{} jsonStr.WriteByte('{') - if publisherID, ok := getString(params.FieldMap["publisherId"]); !ok { + publisherID, ok := getString(params.FieldMap["publisherId"]) + if !ok { return nil, fmt.Errorf(errMandatoryParameterMissingFormat, params.AdapterName, "publisherId") - } else { - fmt.Fprintf(&jsonStr, `"publisherId":"%s",`, publisherID) + } + fmt.Fprintf(&jsonStr, `"publisherId":"%s"`, publisherID) + + if adspaceID, ok := getString(params.FieldMap["adspaceId"]); ok { + fmt.Fprintf(&jsonStr, `,"adspaceId":"%s"`, adspaceID) } - if adspaceID, ok := getString(params.FieldMap["adspaceId"]); !ok { - return nil, fmt.Errorf(errMandatoryParameterMissingFormat, params.AdapterName, "adspaceId") - } else { - fmt.Fprintf(&jsonStr, `"adspaceId":"%s"`, adspaceID) + if adbreakID, ok := getString(params.FieldMap["adbreakId"]); ok { + fmt.Fprintf(&jsonStr, `,"adbreakId":"%s"`, adbreakID) } jsonStr.WriteByte('}') diff --git a/modules/pubmatic/openwrap/adapters/bidders_test.go b/modules/pubmatic/openwrap/adapters/bidders_test.go index 52783889c68..74ed8f9c77a 100644 --- a/modules/pubmatic/openwrap/adapters/bidders_test.go +++ b/modules/pubmatic/openwrap/adapters/bidders_test.go @@ -2001,6 +2001,19 @@ func TestPrepareBidParamJSONForPartnerSmaato(t *testing.T) { args args want json.RawMessage }{ + { + name: "all_missing", + args: args{ + reqID: "", + width: nil, + height: nil, + fieldMap: map[string]interface{}{}, + slotKey: "", + adapterName: string(openrtb_ext.BidderSmaato), + bidderCode: string(openrtb_ext.BidderSmaato), + }, + want: nil, + }, { name: "publisherId missing", args: args{ @@ -2009,6 +2022,7 @@ func TestPrepareBidParamJSONForPartnerSmaato(t *testing.T) { height: nil, fieldMap: map[string]interface{}{ "adspaceId": "1234", + "adbreakId": "4567", }, slotKey: "", adapterName: string(openrtb_ext.BidderSmaato), @@ -2029,23 +2043,25 @@ func TestPrepareBidParamJSONForPartnerSmaato(t *testing.T) { adapterName: string(openrtb_ext.BidderSmaato), bidderCode: string(openrtb_ext.BidderSmaato), }, - want: nil, + want: json.RawMessage(`{"publisherId": "1234"}`), }, { - name: "publisherId & adspaceId both are missing", + name: "adbreakId missing", args: args{ - reqID: "", - width: nil, - height: nil, - fieldMap: map[string]interface{}{}, + + width: nil, + height: nil, + fieldMap: map[string]interface{}{ + "publisherId": "1234", + }, slotKey: "", adapterName: string(openrtb_ext.BidderSmaato), bidderCode: string(openrtb_ext.BidderSmaato), }, - want: nil, + want: json.RawMessage(`{"publisherId": "1234"}`), }, { - name: "All params are present", + name: "publisherId_adspaceId__present", args: args{ width: nil, @@ -2060,6 +2076,53 @@ func TestPrepareBidParamJSONForPartnerSmaato(t *testing.T) { }, want: json.RawMessage(`{"publisherId": "1234","adspaceId": "3456"}`), }, + { + name: "publisherId_adbreakId__present", + args: args{ + + width: nil, + height: nil, + fieldMap: map[string]interface{}{ + "publisherId": "1234", + "adbreakId": "3456", + }, + slotKey: "", + adapterName: string(openrtb_ext.BidderSmaato), + bidderCode: string(openrtb_ext.BidderSmaato), + }, + want: json.RawMessage(`{"publisherId": "1234","adbreakId": "3456"}`), + }, + { + name: "adspaceId_and_adbreakId_present", + args: args{ + width: nil, + height: nil, + fieldMap: map[string]interface{}{ + "adspaceId": "1234", + "adbreakId": "7899", + }, + slotKey: "", + adapterName: string(openrtb_ext.BidderSmaato), + bidderCode: string(openrtb_ext.BidderSmaato), + }, + want: nil, + }, + { + name: "all_params_are_present", + args: args{ + width: nil, + height: nil, + fieldMap: map[string]interface{}{ + "publisherId": "1234", + "adspaceId": "3456", + "adbreakId": "7899", + }, + slotKey: "", + adapterName: string(openrtb_ext.BidderSmaato), + bidderCode: string(openrtb_ext.BidderSmaato), + }, + want: json.RawMessage(`{"publisherId": "1234","adspaceId": "3456","adbreakId": "7899"}`), + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { From 6098152c9862736b1296604cc6b02d7bce1c580b Mon Sep 17 00:00:00 2001 From: Viral Vala <63396712+pm-viral-vala@users.noreply.github.com> Date: Tue, 7 Jan 2025 18:10:21 +0530 Subject: [PATCH 5/5] UOE-11702: setting video.plcmt from video.placement for modules (#991) --- .../pubmatic/openwrap/beforevalidationhook.go | 51 +++- .../openwrap/beforevalidationhook_test.go | 227 +++++++++++++++++- 2 files changed, 263 insertions(+), 15 deletions(-) diff --git a/modules/pubmatic/openwrap/beforevalidationhook.go b/modules/pubmatic/openwrap/beforevalidationhook.go index fa2a971cd94..c7b046fd7e1 100644 --- a/modules/pubmatic/openwrap/beforevalidationhook.go +++ b/modules/pubmatic/openwrap/beforevalidationhook.go @@ -720,11 +720,6 @@ func (m *OpenWrap) applyProfileChanges(rctx models.RequestCtx, bidRequest *openr rctx.NewReqExt = &models.RequestExt{} } rctx.NewReqExt.Prebid.StrictVastMode = strictVastMode - for i := 0; i < len(bidRequest.Imp); i++ { - if bidRequest.Imp[i].Video != nil { - bidRequest.Imp[i].Video.Protocols = UpdateImpProtocols(bidRequest.Imp[i].Video.Protocols) - } - } } if cur, ok := rctx.PartnerConfigMap[models.VersionLevelConfigID][models.AdServerCurrency]; ok { bidRequest.Cur = append(bidRequest.Cur, cur) @@ -739,18 +734,11 @@ func (m *OpenWrap) applyProfileChanges(rctx models.RequestCtx, bidRequest *openr bidRequest.Source.TID = bidRequest.ID for i := 0; i < len(bidRequest.Imp); i++ { - // TODO: move this to PBS-Core - if bidRequest.Imp[i].BidFloor == 0 { - bidRequest.Imp[i].BidFloorCur = "" - } else if bidRequest.Imp[i].BidFloorCur == "" { - bidRequest.Imp[i].BidFloorCur = "USD" - } - if rctx.Endpoint != models.EndpointAMP { m.applyBannerAdUnitConfig(rctx, &bidRequest.Imp[i]) } m.applyVideoAdUnitConfig(rctx, &bidRequest.Imp[i]) - bidRequest.Imp[i].Ext = rctx.ImpBidCtx[bidRequest.Imp[i].ID].NewExt + m.applyImpChanges(rctx, &bidRequest.Imp[i]) } setSChainInSourceObject(bidRequest.Source, rctx.PartnerConfigMap) @@ -839,6 +827,43 @@ func (m *OpenWrap) applyVideoAdUnitConfig(rCtx models.RequestCtx, imp *openrtb2. updateImpVideoWithVideoConfig(imp, adUnitCfg.Video.Config) } } + +func (m *OpenWrap) applyImpChanges(rCtx models.RequestCtx, imp *openrtb2.Imp) { + // TODO: move this to PBS-Core + if imp.BidFloor == 0 { + imp.BidFloorCur = "" + } else if imp.BidFloorCur == "" { + imp.BidFloorCur = "USD" + } + + if imp.Video != nil { + m.applyImpVideoChanges(rCtx, imp.Video) + } + + //update impression extensions + imp.Ext = rCtx.ImpBidCtx[imp.ID].NewExt +} + +func (m *OpenWrap) applyImpVideoChanges(rCtx models.RequestCtx, video *openrtb2.Video) { + //update protocols + if rCtx.NewReqExt != nil && rCtx.NewReqExt.Prebid.StrictVastMode { + video.Protocols = UpdateImpProtocols(video.Protocols) + } + + //update video.plcmt from video.placements + if video.Placement > 0 && video.Plcmt == 0 { + //TODO: move to ConvertUpTo26 once upgraded to prebid3.x version + switch video.Placement { + case adcom1.VideoPlacementInStream: + video.Plcmt = adcom1.VideoPlcmtInstream + case adcom1.VideoPlacementInBanner: + video.Plcmt = adcom1.VideoPlcmtNoContent + case adcom1.VideoPlacementAlwaysVisible: + video.Plcmt = adcom1.VideoPlcmtInterstitial + } + } +} + func setImpBidFloorParams(rCtx models.RequestCtx, adUnitCfg *modelsAdunitConfig.AdConfig, imp *openrtb2.Imp, conversions currency.Conversions) (float64, string) { bidfloor := imp.BidFloor bidfloorcur := imp.BidFloorCur diff --git a/modules/pubmatic/openwrap/beforevalidationhook_test.go b/modules/pubmatic/openwrap/beforevalidationhook_test.go index 42939e037dc..c54523ae55d 100644 --- a/modules/pubmatic/openwrap/beforevalidationhook_test.go +++ b/modules/pubmatic/openwrap/beforevalidationhook_test.go @@ -2375,6 +2375,229 @@ func TestOpenWrapApplyProfileChanges(t *testing.T) { } } +func TestOpenWrap_applyImpChanges(t *testing.T) { + tests := []struct { + name string + inputImp *openrtb2.Imp + rCtx models.RequestCtx + expectedImp *openrtb2.Imp + }{ + { + name: "empty_bidfloor", + inputImp: &openrtb2.Imp{ + ID: "imp1", + BidFloor: 0, + BidFloorCur: "USD", + }, + rCtx: models.RequestCtx{}, + expectedImp: &openrtb2.Imp{ + ID: "imp1", + BidFloor: 0, + BidFloorCur: "", + }, + }, + { + name: "empty_bidfloorcur", + inputImp: &openrtb2.Imp{ + ID: "imp1", + BidFloor: 1.0, + BidFloorCur: "", + }, + rCtx: models.RequestCtx{}, + expectedImp: &openrtb2.Imp{ + ID: "imp1", + BidFloor: 1.0, + BidFloorCur: "USD", + }, + }, + { + name: "apply_imp_video_changes", + inputImp: &openrtb2.Imp{ + ID: "imp3", + Video: &openrtb2.Video{ + Protocols: []adcom1.MediaCreativeSubtype{ + adcom1.CreativeVAST10, + adcom1.CreativeVAST20}, + Placement: adcom1.VideoPlacementInStream, + }, + }, + rCtx: models.RequestCtx{ + NewReqExt: &models.RequestExt{ + ExtRequest: openrtb_ext.ExtRequest{ + Prebid: openrtb_ext.ExtRequestPrebid{ + ExtOWRequestPrebid: openrtb_ext.ExtOWRequestPrebid{ + StrictVastMode: true, + }, + }, + }, + }, + }, + expectedImp: &openrtb2.Imp{ + ID: "imp3", + Video: &openrtb2.Video{ + Protocols: []adcom1.MediaCreativeSubtype{ + adcom1.CreativeVAST10, + adcom1.CreativeVAST20, + adcom1.CreativeVAST30, + adcom1.CreativeVAST30Wrapper, + adcom1.CreativeVAST40, + adcom1.CreativeVAST40Wrapper}, + Placement: adcom1.VideoPlacementInStream, + Plcmt: adcom1.VideoPlcmtInstream, + }, + }, + }, + { + name: "Impression extensions updated", + inputImp: &openrtb2.Imp{ + ID: "imp5", + }, + rCtx: models.RequestCtx{ + ImpBidCtx: map[string]models.ImpCtx{ + "imp5": { + NewExt: []byte(`{"key":"value"}`), + }, + }, + }, + expectedImp: &openrtb2.Imp{ + ID: "imp5", + Ext: []byte(`{"key":"value"}`), + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + m := &OpenWrap{} + m.applyImpChanges(test.rCtx, test.inputImp) + assert.Equal(t, test.expectedImp, test.inputImp) + }) + } +} + +func TestOpenWrap_applyImpVideoChanges(t *testing.T) { + tests := []struct { + name string + inputVideo *openrtb2.Video + rCtx models.RequestCtx + expectedVideo *openrtb2.Video + }{ + { + name: "strictvastmode_enabled", + inputVideo: &openrtb2.Video{ + Protocols: []adcom1.MediaCreativeSubtype{ + adcom1.CreativeVAST10, + adcom1.CreativeVAST20}, + }, + rCtx: models.RequestCtx{ + NewReqExt: &models.RequestExt{ + ExtRequest: openrtb_ext.ExtRequest{ + Prebid: openrtb_ext.ExtRequestPrebid{ + ExtOWRequestPrebid: openrtb_ext.ExtOWRequestPrebid{ + StrictVastMode: true, + }, + }, + }, + }, + }, + expectedVideo: &openrtb2.Video{ + Protocols: []adcom1.MediaCreativeSubtype{ + adcom1.CreativeVAST10, + adcom1.CreativeVAST20, + adcom1.CreativeVAST30, + adcom1.CreativeVAST30Wrapper, + adcom1.CreativeVAST40, + adcom1.CreativeVAST40Wrapper}, + }, + }, + { + name: "video.plcmt_present", + inputVideo: &openrtb2.Video{ + Placement: 0, + Plcmt: adcom1.VideoPlcmtInterstitial, + }, + rCtx: models.RequestCtx{}, + expectedVideo: &openrtb2.Video{ + Placement: 0, + Plcmt: adcom1.VideoPlcmtInterstitial, + }, + }, + { + name: "video.placement_video.plcmt_present", + inputVideo: &openrtb2.Video{ + Placement: adcom1.VideoPlacementAlwaysVisible, + Plcmt: adcom1.VideoPlcmtInterstitial, + }, + rCtx: models.RequestCtx{}, + expectedVideo: &openrtb2.Video{ + Placement: adcom1.VideoPlacementAlwaysVisible, + Plcmt: adcom1.VideoPlcmtInterstitial, + }, + }, + { + name: "video.placement=instream", + inputVideo: &openrtb2.Video{ + Placement: adcom1.VideoPlacementInStream, + }, + rCtx: models.RequestCtx{}, + expectedVideo: &openrtb2.Video{ + Placement: adcom1.VideoPlacementInStream, + Plcmt: adcom1.VideoPlcmtInstream, + }, + }, + { + name: "video.placement=interstitial", + inputVideo: &openrtb2.Video{ + Placement: adcom1.VideoPlacementAlwaysVisible, + }, + rCtx: models.RequestCtx{}, + expectedVideo: &openrtb2.Video{ + Placement: adcom1.VideoPlacementAlwaysVisible, + Plcmt: adcom1.VideoPlcmtInterstitial, + }, + }, + { + name: "video.placement=inbanner", + inputVideo: &openrtb2.Video{ + Placement: adcom1.VideoPlacementInBanner, + }, + rCtx: models.RequestCtx{}, + expectedVideo: &openrtb2.Video{ + Placement: adcom1.VideoPlacementInBanner, + Plcmt: adcom1.VideoPlcmtNoContent, + }, + }, + { + name: "video.placement=inarticle", + inputVideo: &openrtb2.Video{ + Placement: adcom1.VideoPlacementInArticle, + }, + rCtx: models.RequestCtx{}, + expectedVideo: &openrtb2.Video{ + Placement: adcom1.VideoPlacementInArticle, + }, + }, + { + name: "video.placement=infeed", + inputVideo: &openrtb2.Video{ + Placement: adcom1.VideoPlacementInFeed, + }, + rCtx: models.RequestCtx{}, + expectedVideo: &openrtb2.Video{ + Placement: adcom1.VideoPlacementInFeed, + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + m := &OpenWrap{} + m.applyImpVideoChanges(test.rCtx, test.inputVideo) + assert.Equal(t, test.expectedVideo, test.inputVideo) + }) + } +} + func TestOpenWrap_applyVideoAdUnitConfig(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() @@ -5041,7 +5264,7 @@ func TestOpenWrapHandleBeforeValidationHook(t *testing.T) { DebugMessages: []string{`new imp: {"28635736ddc2bb2":{"ImpID":"28635736ddc2bb2","TagID":"adunit","Div":"","SlotName":"adunit","AdUnitName":"adunit","Secure":0,"BidFloor":1,"BidFloorCur":"USD","IsRewardInventory":null,"Banner":false,"Video":{"mimes":["video/3gpp","video/mp4"],"minduration":10,"maxduration":40,"startdelay":1,"protocols":[2,3,5,6],"w":280,"h":360,"placement":5,"linearity":1,"skip":1,"skipmin":5,"skipafter":10,"sequence":1,"battr":[5,6,7],"maxextended":10,"minbitrate":1000,"maxbitrate":2000,"playbackmethod":[1],"playbackend":1,"delivery":[2],"pos":7,"api":[1,2],"companiontype":[1,2,3]},"Native":null,"IncomingSlots":["280x360"],"Type":"video","Bidders":{"appnexus":{"PartnerID":2,"PrebidBidderCode":"appnexus","MatchedSlot":"adunit@0x0","KGP":"_AU_@_W_x_H_","KGPV":"","IsRegex":false,"Params":{"placementId":0,"site":"12313","adtag":"45343"},"VASTTagFlags":null}},"NonMapped":{},"NewExt":{"data":{"pbadslot":"adunit"},"prebid":{"bidder":{"appnexus":{"placementId":0,"site":"12313","adtag":"45343"}}}},"BidCtx":{},"BannerAdUnitCtx":{"MatchedSlot":"adunit","IsRegex":false,"MatchedRegex":"","SelectedSlotAdUnitConfig":{"video":{"enabled":true,"config":{"mimes":["video/mp4","video/mpeg"],"w":640,"h":480},"usepodconfig":true}},"AppliedSlotAdUnitConfig":{"video":{"enabled":true,"config":{"mimes":["video/mp4","video/mpeg"],"w":640,"h":480},"usepodconfig":true}},"UsingDefaultConfig":false,"AllowedConnectionTypes":null},"VideoAdUnitCtx":{"MatchedSlot":"adunit","IsRegex":false,"MatchedRegex":"","SelectedSlotAdUnitConfig":{"video":{"enabled":true,"config":{"mimes":["video/mp4","video/mpeg"],"w":640,"h":480},"usepodconfig":true}},"AppliedSlotAdUnitConfig":{"video":{"enabled":true,"config":{"mimes":["video/mp4","video/mpeg"],"w":640,"h":480},"usepodconfig":true}},"UsingDefaultConfig":false,"AllowedConnectionTypes":null},"BidderError":"","IsAdPodRequest":false,"AdpodConfig":null,"ImpAdPodCfg":null,"BidIDToAPRC":null,"AdserverURL":"","BidIDToDur":null}}`, `new request.ext: {"prebid":{"bidadjustmentfactors":{"appnexus":1},"bidderparams":{"pubmatic":{"wiid":""}},"debug":true,"floors":{"enforcement":{"enforcepbs":true},"enabled":true},"targeting":{"pricegranularity":{"precision":2,"ranges":[{"min":0,"max":5,"increment":0.05},{"min":5,"max":10,"increment":0.1},{"min":10,"max":20,"increment":0.5}]},"mediatypepricegranularity":{},"includewinners":true,"includebidderkeys":true,"includebrandcategory":{"primaryadserver":0,"publisher":"","withcategory":false,"translatecategories":false,"skipdedup":true}},"macros":{"[PLATFORM]":"2","[PROFILE_ID]":"4444","[PROFILE_VERSION]":"1","[UNIX_TIMESTAMP]":"0","[WRAPPER_IMPRESSION_ID]":""}}}`}, AnalyticsTags: hookanalytics.Analytics{}, }, - bidRequest: json.RawMessage(`{"id":"1559039248176","imp":[{"id":"28635736ddc2bb2-dynamic-1-0","video":{"mimes":["video/3gpp","video/mp4"],"minduration":20,"maxduration":30,"startdelay":1,"maxseq":3,"poddur":60,"protocols":[2,3,5,6],"w":280,"h":360,"podid":"dynamic-1","placement":5,"linearity":1,"skip":1,"skipmin":5,"skipafter":10,"sequence":1,"battr":[5,6,7],"maxextended":10,"minbitrate":1000,"maxbitrate":2000,"playbackmethod":[1],"playbackend":1,"delivery":[2],"pos":7,"api":[1,2],"companiontype":[1,2,3]},"displaymanager":"PubMaticSDK","displaymanagerver":"PubMaticSDK-1.0","instl":1,"tagid":"adunit","bidfloor":1,"bidfloorcur":"USD","secure":0,"iframebuster":["1"],"exp":1,"ext":{"data":{"pbadslot":"adunit"},"prebid":{"bidder":{"appnexus":{"placementId":0,"site":"12313","adtag":"45343"}}}}},{"id":"28635736ddc2bb2-structured-1-1","video":{"mimes":["video/3gpp","video/mp4"],"minduration":15,"maxduration":15,"startdelay":1,"protocols":[2,3,5,6],"w":280,"h":360,"podid":"structured-1","placement":5,"linearity":1,"skip":1,"skipmin":5,"skipafter":10,"sequence":1,"battr":[5,6,7],"maxextended":10,"minbitrate":1000,"maxbitrate":2000,"playbackmethod":[1],"playbackend":1,"delivery":[2],"pos":7,"api":[1,2],"companiontype":[1,2,3]},"displaymanager":"PubMaticSDK","displaymanagerver":"PubMaticSDK-1.0","instl":1,"tagid":"adunit","bidfloor":1,"bidfloorcur":"USD","secure":0,"iframebuster":["1"],"exp":1,"ext":{"data":{"pbadslot":"adunit"},"prebid":{"bidder":{"appnexus":{"placementId":0,"site":"12313","adtag":"45343"}}}}}],"site":{"id":"123","name":"EbayShopping","domain":"ebay.com","cat":["IAB1-5"],"sectioncat":["IAB1-5"],"pagecat":["IAB1-5"],"page":"http://ebay.com/inte/automation/s2s/pwt_parameter_validation_muti_slot_multi_size.html?appnexus_deal_priority=6\u0026appnexus_video_fixedbid=10\u0026videobid=4\u0026cat=IAB20-3","ref":"http://ebay.com/home","search":"NewCloths","mobile":1,"privacypolicy":1,"publisher":{"id":"5890","name":"Test Publisher","cat":["IAB1-5"],"domain":"publisher.com"},"content":{"id":"381d2e0b-548d-4f27-bfdd-e6e66f43557e","episode":1,"title":"StarWars","series":"StarWars","season":"Season3","artist":"GeorgeLucas","genre":"Action","album":"Action","isrc":"2","producer":{"id":"123","name":"GaryKurtz","cat":["IAB1-5","IAB1-6"],"domain":"producer.com"},"url":"http://www.pubmatic.com/test/","cat":["IAB1-1","IAB1-2"],"prodq":1,"videoquality":1,"context":1,"contentrating":"MPAA","userrating":"9-Stars","qagmediarating":1,"keywords":"ActionMovies","livestream":1,"sourcerelationship":1,"len":12000,"language":"en","embeddable":1},"keywords":"Cloths"},"device":{"dnt":0,"lmt":0,"ua":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36","ip":"172.16.8.74","ipv6":"2001:db8::8a2e:370:7334","devicetype":1,"make":"Apple","model":"iPhone X","os":"iOS","osv":"10","hwv":"10x","h":768,"w":1366,"ppi":4096,"pxratio":1.3,"js":1,"flashver":"1.1","language":"en","carrier":"VERIZON","mccmnc":"310-005","connectiontype":2,"ifa":"EA7583CD-A667-48BC-B806-42ECB2B48606","didsha1":"EA7583CD-A667-48BC-B806-42ECB2B48606","didmd5":"EA7583CD-A667-48BC-B806-42ECB2B48606","dpidsha1":"EA7583CD-A667-48BC-B806-42ECB2B48606","dpidmd5":"EA7583CD-A667-48BC-B806-42ECB2B48606","macsha1":"EA7583CD-A667-48BC-B806-42ECB2B48606","macmd5":"EA7583CD-A667-48BC-B806-42ECB2B48606"},"user":{"id":"45067fec-eab7-4ca0-ad3a-87b01f21846a","buyeruid":"45067fec-eab7-4ca0-ad3a-87b01f21846a","yob":1990,"gender":"M","keywords":"Movies","customdata":"StarWars"},"at":1,"tmax":500,"source":{"fd":1,"tid":"1559039248176","pchain":"pchaintagid"},"regs":{"ext":{"gdpr":1,"us_privacy":"1YNN"}},"ext":{"prebid":{"bidadjustmentfactors":{"appnexus":1},"bidderparams":{"pubmatic":{"wiid":""}},"debug":true,"floors":{"enforcement":{"enforcepbs":true},"enabled":true},"targeting":{"pricegranularity":{"precision":2,"ranges":[{"min":0,"max":5,"increment":0.05},{"min":5,"max":10,"increment":0.1},{"min":10,"max":20,"increment":0.5}]},"mediatypepricegranularity":{},"includewinners":true,"includebidderkeys":true,"includebrandcategory":{"primaryadserver":0,"publisher":"","withcategory":false,"translatecategories":false,"skipdedup":true}},"macros":{"[PLATFORM]":"2","[PROFILE_ID]":"4444","[PROFILE_VERSION]":"1","[UNIX_TIMESTAMP]":"0","[WRAPPER_IMPRESSION_ID]":""}}}}`), + bidRequest: json.RawMessage(`{"id":"1559039248176","imp":[{"id":"28635736ddc2bb2-dynamic-1-0","video":{"mimes":["video/3gpp","video/mp4"],"minduration":20,"maxduration":30,"startdelay":1,"maxseq":3,"poddur":60,"protocols":[2,3,5,6],"w":280,"h":360,"podid":"dynamic-1","placement":5,"plcmt":3,"linearity":1,"skip":1,"skipmin":5,"skipafter":10,"sequence":1,"battr":[5,6,7],"maxextended":10,"minbitrate":1000,"maxbitrate":2000,"playbackmethod":[1],"playbackend":1,"delivery":[2],"pos":7,"api":[1,2],"companiontype":[1,2,3]},"displaymanager":"PubMaticSDK","displaymanagerver":"PubMaticSDK-1.0","instl":1,"tagid":"adunit","bidfloor":1,"bidfloorcur":"USD","secure":0,"iframebuster":["1"],"exp":1,"ext":{"data":{"pbadslot":"adunit"},"prebid":{"bidder":{"appnexus":{"placementId":0,"site":"12313","adtag":"45343"}}}}},{"id":"28635736ddc2bb2-structured-1-1","video":{"mimes":["video/3gpp","video/mp4"],"minduration":15,"maxduration":15,"startdelay":1,"protocols":[2,3,5,6],"w":280,"h":360,"podid":"structured-1","placement":5,"plcmt":3,"linearity":1,"skip":1,"skipmin":5,"skipafter":10,"sequence":1,"battr":[5,6,7],"maxextended":10,"minbitrate":1000,"maxbitrate":2000,"playbackmethod":[1],"playbackend":1,"delivery":[2],"pos":7,"api":[1,2],"companiontype":[1,2,3]},"displaymanager":"PubMaticSDK","displaymanagerver":"PubMaticSDK-1.0","instl":1,"tagid":"adunit","bidfloor":1,"bidfloorcur":"USD","secure":0,"iframebuster":["1"],"exp":1,"ext":{"data":{"pbadslot":"adunit"},"prebid":{"bidder":{"appnexus":{"placementId":0,"site":"12313","adtag":"45343"}}}}}],"site":{"id":"123","name":"EbayShopping","domain":"ebay.com","cat":["IAB1-5"],"sectioncat":["IAB1-5"],"pagecat":["IAB1-5"],"page":"http://ebay.com/inte/automation/s2s/pwt_parameter_validation_muti_slot_multi_size.html?appnexus_deal_priority=6\u0026appnexus_video_fixedbid=10\u0026videobid=4\u0026cat=IAB20-3","ref":"http://ebay.com/home","search":"NewCloths","mobile":1,"privacypolicy":1,"publisher":{"id":"5890","name":"Test Publisher","cat":["IAB1-5"],"domain":"publisher.com"},"content":{"id":"381d2e0b-548d-4f27-bfdd-e6e66f43557e","episode":1,"title":"StarWars","series":"StarWars","season":"Season3","artist":"GeorgeLucas","genre":"Action","album":"Action","isrc":"2","producer":{"id":"123","name":"GaryKurtz","cat":["IAB1-5","IAB1-6"],"domain":"producer.com"},"url":"http://www.pubmatic.com/test/","cat":["IAB1-1","IAB1-2"],"prodq":1,"videoquality":1,"context":1,"contentrating":"MPAA","userrating":"9-Stars","qagmediarating":1,"keywords":"ActionMovies","livestream":1,"sourcerelationship":1,"len":12000,"language":"en","embeddable":1},"keywords":"Cloths"},"device":{"dnt":0,"lmt":0,"ua":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36","ip":"172.16.8.74","ipv6":"2001:db8::8a2e:370:7334","devicetype":1,"make":"Apple","model":"iPhone X","os":"iOS","osv":"10","hwv":"10x","h":768,"w":1366,"ppi":4096,"pxratio":1.3,"js":1,"flashver":"1.1","language":"en","carrier":"VERIZON","mccmnc":"310-005","connectiontype":2,"ifa":"EA7583CD-A667-48BC-B806-42ECB2B48606","didsha1":"EA7583CD-A667-48BC-B806-42ECB2B48606","didmd5":"EA7583CD-A667-48BC-B806-42ECB2B48606","dpidsha1":"EA7583CD-A667-48BC-B806-42ECB2B48606","dpidmd5":"EA7583CD-A667-48BC-B806-42ECB2B48606","macsha1":"EA7583CD-A667-48BC-B806-42ECB2B48606","macmd5":"EA7583CD-A667-48BC-B806-42ECB2B48606"},"user":{"id":"45067fec-eab7-4ca0-ad3a-87b01f21846a","buyeruid":"45067fec-eab7-4ca0-ad3a-87b01f21846a","yob":1990,"gender":"M","keywords":"Movies","customdata":"StarWars"},"at":1,"tmax":500,"source":{"fd":1,"tid":"1559039248176","pchain":"pchaintagid"},"regs":{"ext":{"gdpr":1,"us_privacy":"1YNN"}},"ext":{"prebid":{"bidadjustmentfactors":{"appnexus":1},"bidderparams":{"pubmatic":{"wiid":""}},"debug":true,"floors":{"enforcement":{"enforcepbs":true},"enabled":true},"targeting":{"pricegranularity":{"precision":2,"ranges":[{"min":0,"max":5,"increment":0.05},{"min":5,"max":10,"increment":0.1},{"min":10,"max":20,"increment":0.5}]},"mediatypepricegranularity":{},"includewinners":true,"includebidderkeys":true,"includebrandcategory":{"primaryadserver":0,"publisher":"","withcategory":false,"translatecategories":false,"skipdedup":true}},"macros":{"[PLATFORM]":"2","[PROFILE_ID]":"4444","[PROFILE_VERSION]":"1","[UNIX_TIMESTAMP]":"0","[WRAPPER_IMPRESSION_ID]":""}}}}`), error: false, nilCurrencyConversion: false, doMutate: true, @@ -5176,7 +5399,7 @@ func TestOpenWrapHandleBeforeValidationHook(t *testing.T) { DebugMessages: []string{`new imp: {"28635736ddc2bb2":{"AdpodConfig":null,"AdserverURL":"","AdUnitName":"adunit","Banner":false,"BannerAdUnitCtx":{"AllowedConnectionTypes":null,"AppliedSlotAdUnitConfig":{"adrule":[{"maxduration":30,"maxseq":3,"mimes":null,"minduration":20,"poddur":60,"podid":"dynamic-1"},{"maxduration":15,"mimes":null,"minduration":15,"podid":"structured-1"}],"video":{"config":{"h":480,"mimes":["video/mp4","video/mpeg"],"w":640},"enabled":true}},"IsRegex":false,"MatchedRegex":"","MatchedSlot":"adunit","SelectedSlotAdUnitConfig":{"adrule":[{"maxduration":30,"maxseq":3,"mimes":null,"minduration":20,"poddur":60,"podid":"dynamic-1"},{"maxduration":15,"mimes":null,"minduration":15,"podid":"structured-1"}],"video":{"config":{"h":480,"mimes":["video/mp4","video/mpeg"],"w":640},"enabled":true}},"UsingDefaultConfig":false},"BidCtx":{},"BidderError":"","Bidders":{"appnexus":{"IsRegex":false,"KGP":"_AU_@_W_x_H_","KGPV":"","MatchedSlot":"adunit@0x0","Params":{"adtag":"45343","placementId":0,"site":"12313"},"PartnerID":2,"PrebidBidderCode":"appnexus","VASTTagFlags":null}},"BidFloor":1,"BidFloorCur":"USD","BidIDToAPRC":null,"BidIDToDur":null,"Div":"","ImpAdPodCfg":null,"ImpID":"28635736ddc2bb2","IncomingSlots":["280x360"],"IsAdPodRequest":false,"IsRewardInventory":null,"Native":null,"NewExt":{"data":{"pbadslot":"adunit"},"prebid":{"bidder":{"appnexus":{"adtag":"45343","placementId":0,"site":"12313"}}}},"NonMapped":{},"Secure":0,"SlotName":"adunit","TagID":"adunit","Type":"video","Video":{"api":[1,2],"battr":[5,6,7],"companiontype":[1,2,3],"delivery":[2],"h":360,"linearity":1,"maxbitrate":2000,"maxduration":40,"maxextended":10,"mimes":["video/3gpp","video/mp4"],"minbitrate":1000,"minduration":10,"placement":5,"playbackend":1,"playbackmethod":[1],"pos":7,"protocols":[2,3,5,6],"sequence":1,"skip":1,"skipafter":10,"skipmin":5,"startdelay":1,"w":280},"VideoAdUnitCtx":{"AllowedConnectionTypes":null,"AppliedSlotAdUnitConfig":{"adrule":[{"maxduration":30,"maxseq":3,"mimes":null,"minduration":20,"poddur":60,"podid":"dynamic-1"},{"maxduration":15,"mimes":null,"minduration":15,"podid":"structured-1"}],"video":{"config":{"h":480,"mimes":["video/mp4","video/mpeg"],"w":640},"enabled":true}},"IsRegex":false,"MatchedRegex":"","MatchedSlot":"adunit","SelectedSlotAdUnitConfig":{"adrule":[{"maxduration":30,"maxseq":3,"mimes":null,"minduration":20,"poddur":60,"podid":"dynamic-1"},{"maxduration":15,"mimes":null,"minduration":15,"podid":"structured-1"}],"video":{"config":{"h":480,"mimes":["video/mp4","video/mpeg"],"w":640},"enabled":true}},"UsingDefaultConfig":false}}}`, `new request.ext: {"prebid":{"bidadjustmentfactors":{"appnexus":1},"bidderparams":{"pubmatic":{"wiid":""}},"debug":true,"floors":{"enforcement":{"enforcepbs":true},"enabled":true},"targeting":{"pricegranularity":{"precision":2,"ranges":[{"min":0,"max":5,"increment":0.05},{"min":5,"max":10,"increment":0.1},{"min":10,"max":20,"increment":0.5}]},"mediatypepricegranularity":{},"includewinners":true,"includebidderkeys":true,"includebrandcategory":{"primaryadserver":0,"publisher":"","withcategory":false,"translatecategories":false,"skipdedup":true}},"macros":{"[PLATFORM]":"2","[PROFILE_ID]":"4444","[PROFILE_VERSION]":"1","[UNIX_TIMESTAMP]":"0","[WRAPPER_IMPRESSION_ID]":""}}}`}, AnalyticsTags: hookanalytics.Analytics{}, }, - bidRequest: json.RawMessage(`{"id":"1559039248176","imp":[{"id":"28635736ddc2bb2-dynamic-1-0","video":{"mimes":["video/3gpp","video/mp4"],"minduration":20,"maxduration":30,"startdelay":1,"maxseq":3,"poddur":60,"protocols":[2,3,5,6],"w":280,"h":360,"podid":"dynamic-1","placement":5,"linearity":1,"skip":1,"skipmin":5,"skipafter":10,"sequence":1,"battr":[5,6,7],"maxextended":10,"minbitrate":1000,"maxbitrate":2000,"playbackmethod":[1],"playbackend":1,"delivery":[2],"pos":7,"api":[1,2],"companiontype":[1,2,3]},"displaymanager":"PubMaticSDK","displaymanagerver":"PubMaticSDK-1.0","instl":1,"tagid":"adunit","bidfloor":1,"bidfloorcur":"USD","secure":0,"iframebuster":["1"],"exp":1,"ext":{"data":{"pbadslot":"adunit"},"prebid":{"bidder":{"appnexus":{"placementId":0,"site":"12313","adtag":"45343"}}}}},{"id":"28635736ddc2bb2-structured-1-1","video":{"mimes":["video/3gpp","video/mp4"],"minduration":15,"maxduration":15,"startdelay":1,"protocols":[2,3,5,6],"w":280,"h":360,"podid":"structured-1","placement":5,"linearity":1,"skip":1,"skipmin":5,"skipafter":10,"sequence":1,"battr":[5,6,7],"maxextended":10,"minbitrate":1000,"maxbitrate":2000,"playbackmethod":[1],"playbackend":1,"delivery":[2],"pos":7,"api":[1,2],"companiontype":[1,2,3]},"displaymanager":"PubMaticSDK","displaymanagerver":"PubMaticSDK-1.0","instl":1,"tagid":"adunit","bidfloor":1,"bidfloorcur":"USD","secure":0,"iframebuster":["1"],"exp":1,"ext":{"data":{"pbadslot":"adunit"},"prebid":{"bidder":{"appnexus":{"placementId":0,"site":"12313","adtag":"45343"}}}}}],"site":{"id":"123","name":"EbayShopping","domain":"ebay.com","cat":["IAB1-5"],"sectioncat":["IAB1-5"],"pagecat":["IAB1-5"],"page":"http://ebay.com/inte/automation/s2s/pwt_parameter_validation_muti_slot_multi_size.html?appnexus_deal_priority=6\u0026appnexus_video_fixedbid=10\u0026videobid=4\u0026cat=IAB20-3","ref":"http://ebay.com/home","search":"NewCloths","mobile":1,"privacypolicy":1,"publisher":{"id":"5890","name":"Test Publisher","cat":["IAB1-5"],"domain":"publisher.com"},"content":{"id":"381d2e0b-548d-4f27-bfdd-e6e66f43557e","episode":1,"title":"StarWars","series":"StarWars","season":"Season3","artist":"GeorgeLucas","genre":"Action","album":"Action","isrc":"2","producer":{"id":"123","name":"GaryKurtz","cat":["IAB1-5","IAB1-6"],"domain":"producer.com"},"url":"http://www.pubmatic.com/test/","cat":["IAB1-1","IAB1-2"],"prodq":1,"videoquality":1,"context":1,"contentrating":"MPAA","userrating":"9-Stars","qagmediarating":1,"keywords":"ActionMovies","livestream":1,"sourcerelationship":1,"len":12000,"language":"en","embeddable":1},"keywords":"Cloths"},"device":{"dnt":0,"lmt":0,"ua":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36","ip":"172.16.8.74","ipv6":"2001:db8::8a2e:370:7334","devicetype":1,"make":"Apple","model":"iPhone X","os":"iOS","osv":"10","hwv":"10x","h":768,"w":1366,"ppi":4096,"pxratio":1.3,"js":1,"flashver":"1.1","language":"en","carrier":"VERIZON","mccmnc":"310-005","connectiontype":2,"ifa":"EA7583CD-A667-48BC-B806-42ECB2B48606","didsha1":"EA7583CD-A667-48BC-B806-42ECB2B48606","didmd5":"EA7583CD-A667-48BC-B806-42ECB2B48606","dpidsha1":"EA7583CD-A667-48BC-B806-42ECB2B48606","dpidmd5":"EA7583CD-A667-48BC-B806-42ECB2B48606","macsha1":"EA7583CD-A667-48BC-B806-42ECB2B48606","macmd5":"EA7583CD-A667-48BC-B806-42ECB2B48606"},"user":{"id":"45067fec-eab7-4ca0-ad3a-87b01f21846a","buyeruid":"45067fec-eab7-4ca0-ad3a-87b01f21846a","yob":1990,"gender":"M","keywords":"Movies","customdata":"StarWars"},"at":1,"tmax":500,"source":{"fd":1,"tid":"1559039248176","pchain":"pchaintagid"},"regs":{"ext":{"gdpr":1,"us_privacy":"1YNN"}},"ext":{"prebid":{"bidadjustmentfactors":{"appnexus":1},"bidderparams":{"pubmatic":{"wiid":""}},"debug":true,"floors":{"enforcement":{"enforcepbs":true},"enabled":true},"targeting":{"pricegranularity":{"precision":2,"ranges":[{"min":0,"max":5,"increment":0.05},{"min":5,"max":10,"increment":0.1},{"min":10,"max":20,"increment":0.5}]},"mediatypepricegranularity":{},"includewinners":true,"includebidderkeys":true,"includebrandcategory":{"primaryadserver":0,"publisher":"","withcategory":false,"translatecategories":false,"skipdedup":true}},"macros":{"[PLATFORM]":"2","[PROFILE_ID]":"4444","[PROFILE_VERSION]":"1","[UNIX_TIMESTAMP]":"0","[WRAPPER_IMPRESSION_ID]":""}}}}`), + bidRequest: json.RawMessage(`{"id":"1559039248176","imp":[{"id":"28635736ddc2bb2-dynamic-1-0","video":{"mimes":["video/3gpp","video/mp4"],"minduration":20,"maxduration":30,"startdelay":1,"maxseq":3,"poddur":60,"protocols":[2,3,5,6],"w":280,"h":360,"podid":"dynamic-1","placement":5,"plcmt":3,"linearity":1,"skip":1,"skipmin":5,"skipafter":10,"sequence":1,"battr":[5,6,7],"maxextended":10,"minbitrate":1000,"maxbitrate":2000,"playbackmethod":[1],"playbackend":1,"delivery":[2],"pos":7,"api":[1,2],"companiontype":[1,2,3]},"displaymanager":"PubMaticSDK","displaymanagerver":"PubMaticSDK-1.0","instl":1,"tagid":"adunit","bidfloor":1,"bidfloorcur":"USD","secure":0,"iframebuster":["1"],"exp":1,"ext":{"data":{"pbadslot":"adunit"},"prebid":{"bidder":{"appnexus":{"placementId":0,"site":"12313","adtag":"45343"}}}}},{"id":"28635736ddc2bb2-structured-1-1","video":{"mimes":["video/3gpp","video/mp4"],"minduration":15,"maxduration":15,"startdelay":1,"protocols":[2,3,5,6],"w":280,"h":360,"podid":"structured-1","placement":5,"plcmt":3,"linearity":1,"skip":1,"skipmin":5,"skipafter":10,"sequence":1,"battr":[5,6,7],"maxextended":10,"minbitrate":1000,"maxbitrate":2000,"playbackmethod":[1],"playbackend":1,"delivery":[2],"pos":7,"api":[1,2],"companiontype":[1,2,3]},"displaymanager":"PubMaticSDK","displaymanagerver":"PubMaticSDK-1.0","instl":1,"tagid":"adunit","bidfloor":1,"bidfloorcur":"USD","secure":0,"iframebuster":["1"],"exp":1,"ext":{"data":{"pbadslot":"adunit"},"prebid":{"bidder":{"appnexus":{"placementId":0,"site":"12313","adtag":"45343"}}}}}],"site":{"id":"123","name":"EbayShopping","domain":"ebay.com","cat":["IAB1-5"],"sectioncat":["IAB1-5"],"pagecat":["IAB1-5"],"page":"http://ebay.com/inte/automation/s2s/pwt_parameter_validation_muti_slot_multi_size.html?appnexus_deal_priority=6\u0026appnexus_video_fixedbid=10\u0026videobid=4\u0026cat=IAB20-3","ref":"http://ebay.com/home","search":"NewCloths","mobile":1,"privacypolicy":1,"publisher":{"id":"5890","name":"Test Publisher","cat":["IAB1-5"],"domain":"publisher.com"},"content":{"id":"381d2e0b-548d-4f27-bfdd-e6e66f43557e","episode":1,"title":"StarWars","series":"StarWars","season":"Season3","artist":"GeorgeLucas","genre":"Action","album":"Action","isrc":"2","producer":{"id":"123","name":"GaryKurtz","cat":["IAB1-5","IAB1-6"],"domain":"producer.com"},"url":"http://www.pubmatic.com/test/","cat":["IAB1-1","IAB1-2"],"prodq":1,"videoquality":1,"context":1,"contentrating":"MPAA","userrating":"9-Stars","qagmediarating":1,"keywords":"ActionMovies","livestream":1,"sourcerelationship":1,"len":12000,"language":"en","embeddable":1},"keywords":"Cloths"},"device":{"dnt":0,"lmt":0,"ua":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36","ip":"172.16.8.74","ipv6":"2001:db8::8a2e:370:7334","devicetype":1,"make":"Apple","model":"iPhone X","os":"iOS","osv":"10","hwv":"10x","h":768,"w":1366,"ppi":4096,"pxratio":1.3,"js":1,"flashver":"1.1","language":"en","carrier":"VERIZON","mccmnc":"310-005","connectiontype":2,"ifa":"EA7583CD-A667-48BC-B806-42ECB2B48606","didsha1":"EA7583CD-A667-48BC-B806-42ECB2B48606","didmd5":"EA7583CD-A667-48BC-B806-42ECB2B48606","dpidsha1":"EA7583CD-A667-48BC-B806-42ECB2B48606","dpidmd5":"EA7583CD-A667-48BC-B806-42ECB2B48606","macsha1":"EA7583CD-A667-48BC-B806-42ECB2B48606","macmd5":"EA7583CD-A667-48BC-B806-42ECB2B48606"},"user":{"id":"45067fec-eab7-4ca0-ad3a-87b01f21846a","buyeruid":"45067fec-eab7-4ca0-ad3a-87b01f21846a","yob":1990,"gender":"M","keywords":"Movies","customdata":"StarWars"},"at":1,"tmax":500,"source":{"fd":1,"tid":"1559039248176","pchain":"pchaintagid"},"regs":{"ext":{"gdpr":1,"us_privacy":"1YNN"}},"ext":{"prebid":{"bidadjustmentfactors":{"appnexus":1},"bidderparams":{"pubmatic":{"wiid":""}},"debug":true,"floors":{"enforcement":{"enforcepbs":true},"enabled":true},"targeting":{"pricegranularity":{"precision":2,"ranges":[{"min":0,"max":5,"increment":0.05},{"min":5,"max":10,"increment":0.1},{"min":10,"max":20,"increment":0.5}]},"mediatypepricegranularity":{},"includewinners":true,"includebidderkeys":true,"includebrandcategory":{"primaryadserver":0,"publisher":"","withcategory":false,"translatecategories":false,"skipdedup":true}},"macros":{"[PLATFORM]":"2","[PROFILE_ID]":"4444","[PROFILE_VERSION]":"1","[UNIX_TIMESTAMP]":"0","[WRAPPER_IMPRESSION_ID]":""}}}}`), error: false, nilCurrencyConversion: false, doMutate: true,