prebid.js 9.53.2 → 9.53.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/33acrossAnalyticsAdapter.js +1 -1
- package/dist/33acrossBidAdapter.js +1 -1
- package/dist/33acrossIdSystem.js +1 -1
- package/dist/BTBidAdapter.js +1 -1
- package/dist/adagioAnalyticsAdapter.js +1 -1
- package/dist/adagioBidAdapter.js +1 -1
- package/dist/adagioRtdProvider.js +1 -1
- package/dist/adagioUtils.js +1 -1
- package/dist/addefendBidAdapter.js +1 -1
- package/dist/adgenerationBidAdapter.js +1 -1
- package/dist/adlooxRtdProvider.js +1 -1
- package/dist/adqueryBidAdapter.js +1 -1
- package/dist/adrelevantisBidAdapter.js +1 -1
- package/dist/adstirBidAdapter.js +1 -1
- package/dist/adtrgtmeBidAdapter.js +1 -1
- package/dist/adxcgAnalyticsAdapter.js +1 -1
- package/dist/adxcgBidAdapter.js +1 -1
- package/dist/adyoulikeBidAdapter.js +1 -1
- package/dist/agmaAnalyticsAdapter.js +1 -1
- package/dist/ajaBidAdapter.js +1 -1
- package/dist/amxBidAdapter.js +1 -1
- package/dist/amxIdSystem.js +1 -1
- package/dist/aniviewBidAdapter.js +1 -1
- package/dist/appierAnalyticsAdapter.js +1 -1
- package/dist/appnexusBidAdapter.js +1 -1
- package/dist/asoBidAdapter.js +1 -1
- package/dist/axonixBidAdapter.js +1 -1
- package/dist/beopBidAdapter.js +1 -1
- package/dist/bidglassBidAdapter.js +1 -1
- package/dist/big-richmediaBidAdapter.js +1 -1
- package/dist/bitmediaBidAdapter.js +1 -1
- package/dist/bridBidAdapter.js +1 -1
- package/dist/bridgeuppBidAdapter.js +1 -1
- package/dist/bridgewellBidAdapter.js +1 -1
- package/dist/brightMountainMediaBidAdapter.js +1 -1
- package/dist/carodaBidAdapter.js +1 -1
- package/dist/chtnwBidAdapter.js +1 -1
- package/dist/chunk-core.js +1 -1
- package/dist/concertBidAdapter.js +1 -1
- package/dist/connectadBidAdapter.js +1 -1
- package/dist/consumableBidAdapter.js +1 -1
- package/dist/contxtfulBidAdapter.js +1 -1
- package/dist/conversantAnalyticsAdapter.js +1 -1
- package/dist/conversantBidAdapter.js +1 -1
- package/dist/craftBidAdapter.js +1 -1
- package/dist/criteoBidAdapter.js +1 -1
- package/dist/cwireBidAdapter.js +1 -1
- package/dist/dailymotionBidAdapter.js +1 -1
- package/dist/debugging-standalone.js +1 -1
- package/dist/dspxBidAdapter.js +1 -1
- package/dist/dxkultureBidAdapter.js +1 -1
- package/dist/eplanningBidAdapter.js +1 -1
- package/dist/equativBidAdapter.js +1 -1
- package/dist/eskimiBidAdapter.js +1 -1
- package/dist/euidIdSystem.js +1 -1
- package/dist/exadsBidAdapter.js +1 -1
- package/dist/excoBidAdapter.js +1 -1
- package/dist/feedadBidAdapter.js +1 -1
- package/dist/finativeBidAdapter.js +1 -1
- package/dist/freewheel-sspBidAdapter.js +1 -1
- package/dist/gmosspBidAdapter.js +1 -1
- package/dist/greenbidsAnalyticsAdapter.js +1 -1
- package/dist/greenbidsBidAdapter.js +1 -1
- package/dist/greenbidsRtdProvider.js +1 -1
- package/dist/gridBidAdapter.js +1 -1
- package/dist/gumgumBidAdapter.js +1 -1
- package/dist/h12mediaBidAdapter.js +1 -1
- package/dist/hypelabBidAdapter.js +1 -1
- package/dist/id5AnalyticsAdapter.js +1 -1
- package/dist/id5IdSystem.js +1 -1
- package/dist/imdsBidAdapter.js +1 -1
- package/dist/improvedigitalBidAdapter.js +1 -1
- package/dist/inmobiBidAdapter.js +1 -1
- package/dist/insticatorBidAdapter.js +1 -1
- package/dist/intentIqAnalyticsAdapter.js +1 -1
- package/dist/ixBidAdapter.js +1 -1
- package/dist/jixieBidAdapter.js +1 -1
- package/dist/justpremiumBidAdapter.js +1 -1
- package/dist/kargoBidAdapter.js +1 -1
- package/dist/kimberliteBidAdapter.js +1 -1
- package/dist/konduitAnalyticsAdapter.js +1 -1
- package/dist/kueezBidAdapter.js +1 -1
- package/dist/lassoBidAdapter.js +1 -1
- package/dist/lifestreetBidAdapter.js +1 -1
- package/dist/liveIntentId.js +1 -1
- package/dist/logicadBidAdapter.js +1 -1
- package/dist/loglyliftBidAdapter.js +1 -1
- package/dist/luceadBidAdapter.js +1 -1
- package/dist/mabidderBidAdapter.js +1 -1
- package/dist/madsenseBidAdapter.js +1 -1
- package/dist/magniteAnalyticsAdapter.js +1 -1
- package/dist/malltvAnalyticsAdapter.js +1 -1
- package/dist/marsmediaBidAdapter.js +1 -1
- package/dist/mediafuseBidAdapter.js +1 -1
- package/dist/medianetBidAdapter.js +1 -1
- package/dist/medianetUtils.js +1 -1
- package/dist/mediasquareBidAdapter.js +1 -1
- package/dist/mgidBidAdapter.js +1 -1
- package/dist/missenaBidAdapter.js +1 -1
- package/dist/mobilefuseBidAdapter.js +1 -1
- package/dist/nextMillenniumBidAdapter.js +1 -1
- package/dist/nexx360Utils.js +1 -1
- package/dist/nobidAnalyticsAdapter.js +1 -1
- package/dist/nobidBidAdapter.js +1 -1
- package/dist/nodalsAiRtdProvider.js +1 -1
- package/dist/not-for-prod/prebid.js +172 -172
- package/dist/objectGuard.js +1 -1
- package/dist/oguryBidAdapter.js +1 -1
- package/dist/onetagBidAdapter.js +1 -1
- package/dist/ooloAnalyticsAdapter.js +1 -1
- package/dist/openxBidAdapter.js +1 -1
- package/dist/optidigitalBidAdapter.js +1 -1
- package/dist/orbidderBidAdapter.js +1 -1
- package/dist/outbrainBidAdapter.js +1 -1
- package/dist/pixfutureBidAdapter.js +1 -1
- package/dist/publinkIdSystem.js +1 -1
- package/dist/pubmaticAnalyticsAdapter.js +1 -1
- package/dist/pubmaticBidAdapter.js +1 -1
- package/dist/pubmaticIdSystem.js +1 -1
- package/dist/pubmaticRtdProvider.js +1 -1
- package/dist/pubwiseAnalyticsAdapter.js +1 -1
- package/dist/pubxaiAnalyticsAdapter.js +1 -1
- package/dist/pxyzBidAdapter.js +1 -1
- package/dist/quantcastBidAdapter.js +1 -1
- package/dist/readpeakBidAdapter.js +1 -1
- package/dist/relaidoBidAdapter.js +1 -1
- package/dist/retailspotBidAdapter.js +1 -1
- package/dist/rhythmoneBidAdapter.js +1 -1
- package/dist/riseUtils.js +1 -1
- package/dist/rtdModule.js +1 -1
- package/dist/rubiconBidAdapter.js +1 -1
- package/dist/seedingAllianceBidAdapter.js +1 -1
- package/dist/seedtagBidAdapter.js +1 -1
- package/dist/sharethroughAnalyticsAdapter.js +1 -1
- package/dist/sharethroughBidAdapter.js +1 -1
- package/dist/showheroes-bsBidAdapter.js +1 -1
- package/dist/smaatoBidAdapter.js +1 -1
- package/dist/smartadserverBidAdapter.js +1 -1
- package/dist/smartxBidAdapter.js +1 -1
- package/dist/smilewantedBidAdapter.js +1 -1
- package/dist/snigelBidAdapter.js +1 -1
- package/dist/sonobiBidAdapter.js +1 -1
- package/dist/sovrnBidAdapter.js +1 -1
- package/dist/sparteoBidAdapter.js +1 -1
- package/dist/sspBCBidAdapter.js +1 -1
- package/dist/stvBidAdapter.js +1 -1
- package/dist/sublimeBidAdapter.js +1 -1
- package/dist/taboolaBidAdapter.js +1 -1
- package/dist/tappxBidAdapter.js +1 -1
- package/dist/targetVideoBidAdapter.js +1 -1
- package/dist/teadsBidAdapter.js +1 -1
- package/dist/terceptAnalyticsAdapter.js +1 -1
- package/dist/themoneytizerBidAdapter.js +1 -1
- package/dist/trionBidAdapter.js +1 -1
- package/dist/tripleliftBidAdapter.js +1 -1
- package/dist/ttdBidAdapter.js +1 -1
- package/dist/ucfunnelAnalyticsAdapter.js +1 -1
- package/dist/uid2IdSystem.js +1 -1
- package/dist/underdogmediaBidAdapter.js +1 -1
- package/dist/undertoneBidAdapter.js +1 -1
- package/dist/unrulyBidAdapter.js +1 -1
- package/dist/userId.js +1 -1
- package/dist/vidazooUtils.js +1 -1
- package/dist/videobyteBidAdapter.js +1 -1
- package/dist/visxBidAdapter.js +1 -1
- package/dist/vuukleBidAdapter.js +1 -1
- package/dist/widespaceBidAdapter.js +1 -1
- package/dist/winrBidAdapter.js +1 -1
- package/dist/yahooAdsBidAdapter.js +1 -1
- package/dist/yandexBidAdapter.js +1 -1
- package/dist/yieldmoBidAdapter.js +1 -1
- package/dist/yieldoneAnalyticsAdapter.js +1 -1
- package/libraries/objectGuard/objectGuard.js +149 -48
- package/libraries/objectGuard/ortbGuard.js +33 -43
- package/modules/adagioAnalyticsAdapter.js +6 -1
- package/modules/adagioBidAdapter.js +12 -5
- package/modules/adagioRtdProvider.js +41 -35
- package/modules/pubmaticAnalyticsAdapter.js +311 -587
- package/modules/pubmaticBidAdapter.js +71 -8
- package/modules/pubmaticIdSystem.js +4 -4
- package/modules/pubmaticRtdProvider.js +12 -60
- package/modules/rtdModule/index.js +1 -5
- package/modules/ttdBidAdapter.js +0 -5
- package/modules/userId/eids.js +1 -1
- package/modules/userId/index.js +32 -1
- package/package.json +1 -1
- package/src/auction.js +3 -0
- package/test/spec/activities/objectGuard_spec.js +156 -32
- package/test/spec/activities/ortbGuard_spec.js +10 -15
- package/test/spec/modules/adagioAnalyticsAdapter_spec.js +94 -24
- package/test/spec/modules/adagioRtdProvider_spec.js +17 -17
- package/test/spec/modules/pubmaticAnalyticsAdapter_spec.js +634 -916
- package/test/spec/modules/pubmaticBidAdapter_spec.js +260 -1
- package/test/spec/modules/pubmaticRtdProvider_spec.js +78 -400
- package/test/spec/modules/ttdBidAdapter_spec.js +0 -33
- package/test/spec/modules/userId_spec.js +115 -1
|
@@ -88,24 +88,24 @@ describe('Pubmatic RTD Provider', () => {
|
|
|
88
88
|
expect(pubmaticSubmodule.init(config)).to.be.false;
|
|
89
89
|
});
|
|
90
90
|
|
|
91
|
-
it('should
|
|
91
|
+
it('should accept numeric publisherId and convert to string', () => {
|
|
92
92
|
const config = {
|
|
93
93
|
params: {
|
|
94
94
|
publisherId: 123,
|
|
95
95
|
profileId: 'test-profile-id'
|
|
96
96
|
}
|
|
97
97
|
};
|
|
98
|
-
expect(pubmaticSubmodule.init(config)).to.be.
|
|
98
|
+
expect(pubmaticSubmodule.init(config)).to.be.true;
|
|
99
99
|
});
|
|
100
100
|
|
|
101
|
-
it('should
|
|
101
|
+
it('should accept numeric profileId and convert to string', () => {
|
|
102
102
|
const config = {
|
|
103
103
|
params: {
|
|
104
104
|
publisherId: 'test-publisher-id',
|
|
105
105
|
profileId: 345
|
|
106
106
|
}
|
|
107
107
|
};
|
|
108
|
-
expect(pubmaticSubmodule.init(config)).to.be.
|
|
108
|
+
expect(pubmaticSubmodule.init(config)).to.be.true;
|
|
109
109
|
});
|
|
110
110
|
|
|
111
111
|
it('should initialize successfully with valid config', () => {
|
|
@@ -739,19 +739,11 @@ describe('Pubmatic RTD Provider', () => {
|
|
|
739
739
|
setProfileConfigs(originalProfileConfigs);
|
|
740
740
|
|
|
741
741
|
// Verify that for each ad unit code, only pm_ym_flrs is set to 0
|
|
742
|
-
expect(result).to.
|
|
743
|
-
|
|
744
|
-
'ad-unit-2': { 'pm_ym_flrs': 0 }
|
|
745
|
-
});
|
|
746
|
-
|
|
747
|
-
// Verify log message was not called since hasRtdFloorAppliedBid is false
|
|
748
|
-
expect(logInfoStub.calledWith(sinon.match('Setting targeting via getTargetingData'))).to.be.false;
|
|
742
|
+
expect(result['ad-unit-1']).to.have.property('pm_ym_flrs', 0);
|
|
743
|
+
expect(result['ad-unit-2']).to.have.property('pm_ym_flrs', 0);
|
|
749
744
|
});
|
|
750
745
|
|
|
751
|
-
it('should set
|
|
752
|
-
// Based on the actual behavior observed in the test results, this test case is for a floored bid situation
|
|
753
|
-
// Update our expectations to match the actual behavior
|
|
754
|
-
|
|
746
|
+
it('should set pm_ym_flrs to 1 when RTD floor is applied to a bid', function () {
|
|
755
747
|
// Create profileConfigs with pmTargetingKeys.enabled set to true
|
|
756
748
|
const profileConfigsMock = {
|
|
757
749
|
plugins: {
|
|
@@ -768,7 +760,7 @@ describe('Pubmatic RTD Provider', () => {
|
|
|
768
760
|
// Set profileConfigs to our mock
|
|
769
761
|
setProfileConfigs(profileConfigsMock);
|
|
770
762
|
|
|
771
|
-
// Create ad unit codes to test
|
|
763
|
+
// Create multiple ad unit codes to test
|
|
772
764
|
const adUnitCodes = ['ad-unit-1', 'ad-unit-2'];
|
|
773
765
|
const config = {};
|
|
774
766
|
const userConsent = {};
|
|
@@ -779,32 +771,23 @@ describe('Pubmatic RTD Provider', () => {
|
|
|
779
771
|
{
|
|
780
772
|
code: 'ad-unit-1',
|
|
781
773
|
bids: [
|
|
782
|
-
{
|
|
783
|
-
|
|
784
|
-
floorData: {
|
|
785
|
-
floorProvider: 'PM',
|
|
786
|
-
floorValue: 2.5,
|
|
787
|
-
skipped: false
|
|
788
|
-
}
|
|
789
|
-
}
|
|
774
|
+
{ bidder: 'bidderA', floorData: { floorProvider: 'PM', skipped: false } },
|
|
775
|
+
{ bidder: 'bidderB', floorData: { floorProvider: 'PM', skipped: false } }
|
|
790
776
|
]
|
|
791
777
|
},
|
|
792
778
|
{
|
|
793
779
|
code: 'ad-unit-2',
|
|
794
|
-
bids: [
|
|
780
|
+
bids: [
|
|
781
|
+
{ bidder: 'bidderC', floorData: { floorProvider: 'PM', skipped: false } },
|
|
782
|
+
{ bidder: 'bidderD', floorData: { floorProvider: 'PM', skipped: false } }
|
|
783
|
+
]
|
|
795
784
|
}
|
|
796
785
|
],
|
|
797
786
|
bidsReceived: [
|
|
798
|
-
{
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
floorData: {
|
|
803
|
-
floorProvider: 'PM',
|
|
804
|
-
floorValue: 2.5,
|
|
805
|
-
skipped: false
|
|
806
|
-
}
|
|
807
|
-
}
|
|
787
|
+
{ adUnitCode: 'ad-unit-1', bidder: 'bidderA', floorData: { floorProvider: 'PM', skipped: false } },
|
|
788
|
+
{ adUnitCode: 'ad-unit-1', bidder: 'bidderB', floorData: { floorProvider: 'PM', skipped: false } },
|
|
789
|
+
{ adUnitCode: 'ad-unit-2', bidder: 'bidderC', floorData: { floorProvider: 'PM', skipped: false } },
|
|
790
|
+
{ adUnitCode: 'ad-unit-2', bidder: 'bidderD', floorData: { floorProvider: 'PM', skipped: false } }
|
|
808
791
|
]
|
|
809
792
|
};
|
|
810
793
|
|
|
@@ -813,28 +796,13 @@ describe('Pubmatic RTD Provider', () => {
|
|
|
813
796
|
// Restore the original value
|
|
814
797
|
setProfileConfigs(originalProfileConfigs);
|
|
815
798
|
|
|
816
|
-
// Verify that
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
expect(result).to.deep.equal({
|
|
820
|
-
'ad-unit-1': {
|
|
821
|
-
'pm_ym_flrs': 1,
|
|
822
|
-
'pm_ym_flrv': '2.00', // floorValue * FLOORED multiplier as string with 2 decimal places
|
|
823
|
-
'pm_ym_bid_s': 2 // FLOORED status
|
|
824
|
-
},
|
|
825
|
-
'ad-unit-2': {
|
|
826
|
-
'pm_ym_flrs': 1,
|
|
827
|
-
'pm_ym_flrv': '0.00', // No bid value as string with 2 decimal places
|
|
828
|
-
'pm_ym_bid_s': 0 // NOBID status
|
|
829
|
-
}
|
|
830
|
-
});
|
|
831
|
-
|
|
832
|
-
// Verify log message is called when hasRtdFloorAppliedBid is true
|
|
833
|
-
// expect(logInfoStub.calledWith(sinon.match('Setting targeting via getTargetingData'))).to.be.true;
|
|
799
|
+
// Verify that for each ad unit code, pm_ym_flrs is set to 1
|
|
800
|
+
expect(result['ad-unit-1']).to.have.property('pm_ym_flrs', 1);
|
|
801
|
+
expect(result['ad-unit-2']).to.have.property('pm_ym_flrs', 1);
|
|
834
802
|
});
|
|
835
803
|
|
|
836
|
-
it('should
|
|
837
|
-
// Create profileConfigs with pmTargetingKeys
|
|
804
|
+
it('should set different targeting keys for winning bids (status 1) and floored bids (status 2)', function () {
|
|
805
|
+
// Create profileConfigs with pmTargetingKeys.enabled set to true
|
|
838
806
|
const profileConfigsMock = {
|
|
839
807
|
plugins: {
|
|
840
808
|
dynamicFloors: {
|
|
@@ -845,191 +813,81 @@ describe('Pubmatic RTD Provider', () => {
|
|
|
845
813
|
}
|
|
846
814
|
};
|
|
847
815
|
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
// Create a mock auction with a bid
|
|
859
|
-
const auction = {
|
|
860
|
-
adUnits: [{
|
|
861
|
-
code: 'ad-unit-1',
|
|
862
|
-
bids: [{
|
|
863
|
-
bidder: 'bidderA',
|
|
864
|
-
floorData: {
|
|
865
|
-
floorProvider: 'PM',
|
|
866
|
-
skipped: false
|
|
867
|
-
}
|
|
868
|
-
}]
|
|
869
|
-
}],
|
|
870
|
-
bidsReceived: [{
|
|
871
|
-
adUnitCode: 'ad-unit-1',
|
|
872
|
-
bidder: 'bidderA',
|
|
873
|
-
cpm: 5.0,
|
|
874
|
-
floorData: {
|
|
875
|
-
floorProvider: 'PM',
|
|
876
|
-
floorValue: 3.0,
|
|
877
|
-
skipped: false
|
|
878
|
-
}
|
|
879
|
-
}]
|
|
880
|
-
};
|
|
881
|
-
|
|
882
|
-
const result = getTargetingData(adUnitCodes, config, userConsent, auction);
|
|
883
|
-
|
|
884
|
-
// Restore the original value
|
|
885
|
-
setProfileConfigs(originalProfileConfigs);
|
|
886
|
-
|
|
887
|
-
// Verify that targeting keys are set when RTD floor is applied
|
|
888
|
-
expect(result['ad-unit-1']['pm_ym_flrs']).to.equal(1); // RTD floor was applied
|
|
889
|
-
|
|
890
|
-
// The function identifies bid status based on its internal logic
|
|
891
|
-
// We know it sets a bid status (either WON, FLOORED, or NOBID)
|
|
892
|
-
expect(result['ad-unit-1']['pm_ym_bid_s']).to.be.a('number');
|
|
893
|
-
|
|
894
|
-
// It also sets a floor value based on the bid status
|
|
895
|
-
expect(result['ad-unit-1']['pm_ym_flrv']).to.be.a('string');
|
|
896
|
-
|
|
897
|
-
// We can also verify that when a bid exists, the exact bid status is FLOORED (2)
|
|
898
|
-
// This matches the actual behavior of the function
|
|
899
|
-
expect(result['ad-unit-1']['pm_ym_bid_s']).to.equal(2);
|
|
900
|
-
});
|
|
901
|
-
|
|
902
|
-
// Test for multiplier extraction logic in fetchData
|
|
903
|
-
it('should correctly extract only existing multiplier keys from floors.json', function () {
|
|
904
|
-
// Reset sandbox for a clean test
|
|
905
|
-
sandbox.restore();
|
|
906
|
-
sandbox = sinon.createSandbox();
|
|
907
|
-
|
|
908
|
-
// Stub logInfo instead of console.info
|
|
909
|
-
sandbox.stub(utils, 'logInfo');
|
|
910
|
-
|
|
911
|
-
// Mock fetch with specific multiplier data where 'nobid' is intentionally missing
|
|
912
|
-
global.fetch = sandbox.stub().returns(Promise.resolve({
|
|
913
|
-
ok: true,
|
|
914
|
-
status: 200,
|
|
915
|
-
json: function() {
|
|
916
|
-
return Promise.resolve({
|
|
917
|
-
multiplier: {
|
|
918
|
-
win: 1.5, // present key
|
|
919
|
-
floored: 1.8 // present key
|
|
920
|
-
// nobid is deliberately missing to test selective extraction
|
|
921
|
-
}
|
|
922
|
-
});
|
|
923
|
-
},
|
|
924
|
-
headers: {
|
|
925
|
-
get: function() { return null; }
|
|
926
|
-
}
|
|
927
|
-
}));
|
|
928
|
-
|
|
929
|
-
// Call fetchData with FLOORS type
|
|
930
|
-
return fetchData('test-publisher', 'test-profile', 'FLOORS').then(() => {
|
|
931
|
-
// Verify the log message was generated
|
|
932
|
-
sinon.assert.called(utils.logInfo);
|
|
933
|
-
|
|
934
|
-
// Find the call with multiplier information
|
|
935
|
-
const logCalls = utils.logInfo.getCalls();
|
|
936
|
-
const multiplierLogCall = logCalls.find(call =>
|
|
937
|
-
call.args.some(arg =>
|
|
938
|
-
typeof arg === 'string' && arg.includes('multiplier')
|
|
939
|
-
)
|
|
940
|
-
);
|
|
941
|
-
|
|
942
|
-
// Verify we found the log message
|
|
943
|
-
expect(multiplierLogCall).to.exist;
|
|
944
|
-
|
|
945
|
-
if (multiplierLogCall) {
|
|
946
|
-
// For debugging: log the actual arguments
|
|
947
|
-
|
|
948
|
-
// Find the argument that contains our multiplier info
|
|
949
|
-
const logArg = multiplierLogCall.args.find(arg =>
|
|
950
|
-
typeof arg === 'string' && (arg.includes('WIN') || arg.includes('multiplier'))
|
|
951
|
-
);
|
|
952
|
-
|
|
953
|
-
// Verify the message contains the expected multiplier values
|
|
954
|
-
expect(logArg).to.include('WIN');
|
|
955
|
-
expect(logArg).to.include('1.5');
|
|
956
|
-
expect(logArg).to.include('FLOORED');
|
|
957
|
-
expect(logArg).to.include('1.8');
|
|
958
|
-
|
|
959
|
-
// Verify the log doesn't include NOBID (since it wasn't in the source)
|
|
960
|
-
expect(logArg).to.not.include('NOBID');
|
|
961
|
-
}
|
|
962
|
-
});
|
|
963
|
-
});
|
|
964
|
-
|
|
965
|
-
describe('should handle the floor rejected bid scenario correctly', function () {
|
|
966
|
-
// Create profileConfigs with pmTargetingKeys enabled
|
|
967
|
-
const profileConfigsMock = {
|
|
968
|
-
plugins: {
|
|
969
|
-
dynamicFloors: {
|
|
970
|
-
pmTargetingKeys: {
|
|
971
|
-
enabled: true,
|
|
972
|
-
multiplier: {
|
|
973
|
-
floored: 0.8 // Explicit floored multiplier
|
|
816
|
+
const mockPbjs = {
|
|
817
|
+
getHighestCpmBids: (adUnitCode) => {
|
|
818
|
+
// For div2, return a winning bid
|
|
819
|
+
if (adUnitCode === 'div2') {
|
|
820
|
+
return [{
|
|
821
|
+
adUnitCode: 'div2',
|
|
822
|
+
cpm: 5.5,
|
|
823
|
+
floorData: {
|
|
824
|
+
floorValue: 5.0,
|
|
825
|
+
floorProvider: 'PM'
|
|
974
826
|
}
|
|
975
|
-
}
|
|
827
|
+
}];
|
|
976
828
|
}
|
|
829
|
+
// For all other ad units, return empty array (no winning bids)
|
|
830
|
+
return [];
|
|
977
831
|
}
|
|
978
832
|
};
|
|
979
833
|
|
|
834
|
+
// Stub getGlobal to return our mock object
|
|
835
|
+
const getGlobalStub = sandbox.stub(prebidGlobal, 'getGlobal').returns(mockPbjs);
|
|
836
|
+
|
|
980
837
|
// Store the original value to restore it later
|
|
981
838
|
const originalProfileConfigs = getProfileConfigs();
|
|
982
839
|
// Set profileConfigs to our mock
|
|
983
840
|
setProfileConfigs(profileConfigsMock);
|
|
984
841
|
|
|
985
842
|
// Create ad unit codes to test
|
|
986
|
-
const adUnitCodes = ['
|
|
843
|
+
const adUnitCodes = ['div2', 'div3'];
|
|
987
844
|
const config = {};
|
|
988
845
|
const userConsent = {};
|
|
989
846
|
|
|
990
|
-
// Create a
|
|
991
|
-
const rejectedBid = {
|
|
992
|
-
adUnitCode: 'ad-unit-1',
|
|
993
|
-
bidder: 'bidderA',
|
|
994
|
-
cpm: 2.0,
|
|
995
|
-
statusMessage: 'Bid rejected due to price floor',
|
|
996
|
-
floorData: {
|
|
997
|
-
floorProvider: 'PM',
|
|
998
|
-
floorValue: 2.5,
|
|
999
|
-
skipped: false
|
|
1000
|
-
}
|
|
1001
|
-
};
|
|
1002
|
-
|
|
1003
|
-
// Create a mock auction with a rejected bid
|
|
847
|
+
// Create a mock auction object with bids that have RTD floors applied
|
|
1004
848
|
const auction = {
|
|
1005
|
-
adUnits: [
|
|
1006
|
-
code:
|
|
1007
|
-
bids: [{
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
849
|
+
adUnits: [
|
|
850
|
+
{ code: "div2", bids: [{ floorData: { floorProvider: "PM", skipped: false } }] },
|
|
851
|
+
{ code: "div3", bids: [{ floorData: { floorProvider: "PM", skipped: false } }] }
|
|
852
|
+
],
|
|
853
|
+
adUnitCodes: ["div2", "div3"],
|
|
854
|
+
bidsReceived: [[
|
|
855
|
+
{
|
|
856
|
+
"bidderCode": "appnexus",
|
|
857
|
+
"auctionId": "a262767c-5499-4e98-b694-af36dbcb50f6",
|
|
858
|
+
"mediaType": "banner",
|
|
859
|
+
"source": "client",
|
|
860
|
+
"cpm": 5.5,
|
|
861
|
+
"adUnitCode": "div2",
|
|
862
|
+
"adapterCode": "appnexus",
|
|
863
|
+
"originalCpm": 5.5,
|
|
864
|
+
"floorData": {
|
|
865
|
+
"floorValue": 5,
|
|
866
|
+
"floorRule": "banner|*|*|div2|*|*|*|*|*",
|
|
867
|
+
"floorRuleValue": 5,
|
|
868
|
+
"floorCurrency": "USD"
|
|
869
|
+
},
|
|
870
|
+
"bidder": "appnexus",
|
|
871
|
+
}
|
|
872
|
+
]],
|
|
873
|
+
bidsRejected: [
|
|
874
|
+
{adUnitCode: "div3", bidder: "pubmatic", cpm: 20, floorData: { floorValue: 40 }, rejectionReason: "Bid does not meet price floor" }]
|
|
1019
875
|
};
|
|
1020
876
|
|
|
1021
877
|
const result = getTargetingData(adUnitCodes, config, userConsent, auction);
|
|
1022
878
|
|
|
1023
879
|
// Restore the original value
|
|
1024
880
|
setProfileConfigs(originalProfileConfigs);
|
|
881
|
+
// Check the test results
|
|
882
|
+
expect(result['div2']).to.have.property('pm_ym_flrs', 1);
|
|
883
|
+
expect(result['div2']).to.have.property('pm_ym_flrv', '5.50');
|
|
884
|
+
expect(result['div2']).to.have.property('pm_ym_bid_s', 1);
|
|
1025
885
|
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
expect(result['
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
'pm_ym_flrv': (rejectedBid.floorData.floorValue * 0.8).toFixed(2) // floor value * FLOORED multiplier as string with 2 decimal places
|
|
1032
|
-
});
|
|
886
|
+
expect(result['div3']).to.have.property('pm_ym_flrs', 1);
|
|
887
|
+
expect(result['div3']).to.have.property('pm_ym_flrv', '32.00');
|
|
888
|
+
expect(result['div3']).to.have.property('pm_ym_bid_s', 2);
|
|
889
|
+
|
|
890
|
+
getGlobalStub.restore();
|
|
1033
891
|
});
|
|
1034
892
|
|
|
1035
893
|
describe('should handle the no bid scenario correctly', function () {
|
|
@@ -1199,7 +1057,7 @@ describe('Pubmatic RTD Provider', () => {
|
|
|
1199
1057
|
"mediaTypes": {
|
|
1200
1058
|
"banner": { "sizes": [[300, 250]] }
|
|
1201
1059
|
},
|
|
1202
|
-
"getFloor": () => { return { floor:
|
|
1060
|
+
"getFloor": () => { return { floor: 5, currency: 'USD' }; }
|
|
1203
1061
|
}
|
|
1204
1062
|
]
|
|
1205
1063
|
}
|
|
@@ -1231,6 +1089,7 @@ describe('Pubmatic RTD Provider', () => {
|
|
|
1231
1089
|
// Since finding floor values from bidder requests depends on implementation details
|
|
1232
1090
|
// we'll just verify the type rather than specific value
|
|
1233
1091
|
expect(result['Div2']['pm_ym_flrv']).to.be.a('string');
|
|
1092
|
+
expect(result['Div2']['pm_ym_flrv']).to.equal("6.00");
|
|
1234
1093
|
});
|
|
1235
1094
|
|
|
1236
1095
|
it('should handle no bid scenario correctly for multi-format ad unit with different floors', function () {
|
|
@@ -1378,186 +1237,5 @@ describe('Pubmatic RTD Provider', () => {
|
|
|
1378
1237
|
getFloorSpy.restore();
|
|
1379
1238
|
});
|
|
1380
1239
|
});
|
|
1381
|
-
|
|
1382
|
-
describe('should handle the winning bid scenario correctly', function () {
|
|
1383
|
-
it('should handle winning bid scenario correctly', function () {
|
|
1384
|
-
// Create profileConfigs with pmTargetingKeys enabled
|
|
1385
|
-
const profileConfigsMock = {
|
|
1386
|
-
plugins: {
|
|
1387
|
-
dynamicFloors: {
|
|
1388
|
-
pmTargetingKeys: {
|
|
1389
|
-
enabled: true,
|
|
1390
|
-
multiplier: {
|
|
1391
|
-
nobid: 1.2 // Explicit nobid multiplier
|
|
1392
|
-
}
|
|
1393
|
-
}
|
|
1394
|
-
}
|
|
1395
|
-
}
|
|
1396
|
-
};
|
|
1397
|
-
|
|
1398
|
-
// Store the original value to restore it later
|
|
1399
|
-
const originalProfileConfigs = getProfileConfigs();
|
|
1400
|
-
// Set profileConfigs to our mock
|
|
1401
|
-
setProfileConfigs(profileConfigsMock);
|
|
1402
|
-
|
|
1403
|
-
// Create ad unit codes to test
|
|
1404
|
-
const adUnitCodes = ['Div1'];
|
|
1405
|
-
const config = {};
|
|
1406
|
-
const userConsent = {};
|
|
1407
|
-
|
|
1408
|
-
const highestWinningBidResponse = [{
|
|
1409
|
-
"bidderCode": "pubmatic",
|
|
1410
|
-
"statusMessage": "Bid available",
|
|
1411
|
-
"cpm": 15,
|
|
1412
|
-
"currency": "USD",
|
|
1413
|
-
"bidder": "pubmatic",
|
|
1414
|
-
"adUnitCode": "Div1",
|
|
1415
|
-
}
|
|
1416
|
-
]
|
|
1417
|
-
|
|
1418
|
-
// Create a mock auction with no bids but with RTD floor applied
|
|
1419
|
-
// For this test, we'll observe what the function actually does rather than
|
|
1420
|
-
// try to match specific multiplier values
|
|
1421
|
-
const auction = {
|
|
1422
|
-
"auctionId": "faf0b7d0-3a12-4774-826a-3d56033d9a74",
|
|
1423
|
-
"timestamp": 1749410430351,
|
|
1424
|
-
"auctionEnd": 1749410432392,
|
|
1425
|
-
"auctionStatus": "completed",
|
|
1426
|
-
"adUnits": [
|
|
1427
|
-
{
|
|
1428
|
-
"code": "Div1",
|
|
1429
|
-
"sizes": [
|
|
1430
|
-
[
|
|
1431
|
-
160,
|
|
1432
|
-
600
|
|
1433
|
-
]
|
|
1434
|
-
],
|
|
1435
|
-
"mediaTypes": {
|
|
1436
|
-
"banner": {
|
|
1437
|
-
"sizes": [
|
|
1438
|
-
[
|
|
1439
|
-
160,
|
|
1440
|
-
600
|
|
1441
|
-
]
|
|
1442
|
-
]
|
|
1443
|
-
}
|
|
1444
|
-
},
|
|
1445
|
-
"bids": [
|
|
1446
|
-
{
|
|
1447
|
-
"bidder": "pubmatic",
|
|
1448
|
-
"params": {
|
|
1449
|
-
"publisherId": " 164392 ",
|
|
1450
|
-
"adSlot": " /43743431/DMDemo@320x250 ",
|
|
1451
|
-
"pmzoneid": "zone1",
|
|
1452
|
-
"yob": " 1982 ",
|
|
1453
|
-
"kadpageurl": "www.yahoo.com?secure=1&pubmatic_bannerbid=15",
|
|
1454
|
-
"gender": " M ",
|
|
1455
|
-
"dctr": " key1=v1,v11| key2=v2,v22 | key3=v3 | key4=v4 "
|
|
1456
|
-
},
|
|
1457
|
-
"auctionId": "faf0b7d0-3a12-4774-826a-3d56033d9a74",
|
|
1458
|
-
"floorData": {
|
|
1459
|
-
"noFloorSignaled": false,
|
|
1460
|
-
"skipped": false,
|
|
1461
|
-
"skipRate": 0,
|
|
1462
|
-
"floorMin": 0.05,
|
|
1463
|
-
"modelVersion": "RTD model version 1.0",
|
|
1464
|
-
"modelWeight": 100,
|
|
1465
|
-
"location": "setConfig",
|
|
1466
|
-
"floorProvider": "PM"
|
|
1467
|
-
}
|
|
1468
|
-
}
|
|
1469
|
-
],
|
|
1470
|
-
"adUnitId": "b94e39c9-ac0e-43db-b660-603700dc97dd",
|
|
1471
|
-
"transactionId": "36da4d88-9a7b-433f-adc1-878af8a8f0f1",
|
|
1472
|
-
"ortb2Imp": {
|
|
1473
|
-
"ext": {
|
|
1474
|
-
"tid": "36da4d88-9a7b-433f-adc1-878af8a8f0f1",
|
|
1475
|
-
"data": {
|
|
1476
|
-
"adserver": {
|
|
1477
|
-
"name": "gam",
|
|
1478
|
-
"adslot": "/43743431/DMDemo"
|
|
1479
|
-
},
|
|
1480
|
-
"pbadslot": "/43743431/DMDemo"
|
|
1481
|
-
},
|
|
1482
|
-
"gpid": "/43743431/DMDemo"
|
|
1483
|
-
}
|
|
1484
|
-
}
|
|
1485
|
-
}
|
|
1486
|
-
|
|
1487
|
-
],
|
|
1488
|
-
"adUnitCodes": [
|
|
1489
|
-
"Div1"
|
|
1490
|
-
],
|
|
1491
|
-
"bidderRequests": [
|
|
1492
|
-
{
|
|
1493
|
-
"bidderCode": "pubmatic",
|
|
1494
|
-
"auctionId": "faf0b7d0-3a12-4774-826a-3d56033d9a74",
|
|
1495
|
-
"bidderRequestId": "222b556be27f4c",
|
|
1496
|
-
"bids": [
|
|
1497
|
-
{
|
|
1498
|
-
"bidder": "pubmatic",
|
|
1499
|
-
"floorData": {
|
|
1500
|
-
"noFloorSignaled": false,
|
|
1501
|
-
"skipped": false,
|
|
1502
|
-
"skipRate": 0,
|
|
1503
|
-
"floorMin": 0.05,
|
|
1504
|
-
"modelVersion": "RTD model version 1.0",
|
|
1505
|
-
"modelWeight": 100,
|
|
1506
|
-
"location": "setConfig",
|
|
1507
|
-
"floorProvider": "PM"
|
|
1508
|
-
},
|
|
1509
|
-
"mediaTypes": {
|
|
1510
|
-
"banner": {
|
|
1511
|
-
"sizes": [
|
|
1512
|
-
[
|
|
1513
|
-
160,
|
|
1514
|
-
600
|
|
1515
|
-
]
|
|
1516
|
-
]
|
|
1517
|
-
}
|
|
1518
|
-
},
|
|
1519
|
-
"adUnitCode": "Div1",
|
|
1520
|
-
"transactionId": "36da4d88-9a7b-433f-adc1-878af8a8f0f1",
|
|
1521
|
-
"adUnitId": "b94e39c9-ac0e-43db-b660-603700dc97dd",
|
|
1522
|
-
"sizes": [
|
|
1523
|
-
[
|
|
1524
|
-
160,
|
|
1525
|
-
600
|
|
1526
|
-
]
|
|
1527
|
-
],
|
|
1528
|
-
"bidId": "30fce22fe473c28",
|
|
1529
|
-
"bidderRequestId": "222b556be27f4c",
|
|
1530
|
-
"src": "client",
|
|
1531
|
-
getFloor: () => {}
|
|
1532
|
-
},
|
|
1533
|
-
],
|
|
1534
|
-
"start": 1749410430354
|
|
1535
|
-
}
|
|
1536
|
-
],
|
|
1537
|
-
"bidsReceived": [],
|
|
1538
|
-
"bidsRejected": [],
|
|
1539
|
-
"winningBids": [],
|
|
1540
|
-
"timeout": 3000,
|
|
1541
|
-
"seatNonBids": []
|
|
1542
|
-
};
|
|
1543
|
-
|
|
1544
|
-
sandbox.stub(prebidGlobal, 'getGlobal').returns({
|
|
1545
|
-
getHighestCpmBids: () => [highestWinningBidResponse]
|
|
1546
|
-
});
|
|
1547
|
-
|
|
1548
|
-
const result = getTargetingData(adUnitCodes, config, userConsent, auction);
|
|
1549
|
-
|
|
1550
|
-
// Restore the original value
|
|
1551
|
-
setProfileConfigs(originalProfileConfigs);
|
|
1552
|
-
|
|
1553
|
-
// Verify correct values for no bid scenario
|
|
1554
|
-
expect(result['Div1']['pm_ym_flrs']).to.equal(1); // RTD floor was applied
|
|
1555
|
-
expect(result['Div1']['pm_ym_bid_s']).to.equal(1); // NOBID status
|
|
1556
|
-
|
|
1557
|
-
// Since finding floor values from bidder requests depends on implementation details
|
|
1558
|
-
// we'll just verify the type rather than specific value
|
|
1559
|
-
expect(result['Div1']['pm_ym_flrv']).to.be.a('string');
|
|
1560
|
-
});
|
|
1561
|
-
});
|
|
1562
1240
|
});
|
|
1563
1241
|
});
|
|
@@ -559,17 +559,6 @@ describe('ttdBidAdapter', function () {
|
|
|
559
559
|
expect(requestBody.source.ext.schain).to.deep.equal(schain);
|
|
560
560
|
});
|
|
561
561
|
|
|
562
|
-
it('no longer uses userId', function () {
|
|
563
|
-
const TDID = '00000000-0000-0000-0000-000000000000';
|
|
564
|
-
let clonedBannerRequests = deepClone(baseBannerBidRequests);
|
|
565
|
-
clonedBannerRequests[0].userId = {
|
|
566
|
-
tdid: TDID
|
|
567
|
-
};
|
|
568
|
-
|
|
569
|
-
const requestBody = testBuildRequests(clonedBannerRequests, baseBidderRequest).data;
|
|
570
|
-
expect(requestBody.user.buyeruid).to.be.undefined;
|
|
571
|
-
});
|
|
572
|
-
|
|
573
562
|
it('adds unified ID and UID2 info to user.ext.eids in the request', function () {
|
|
574
563
|
const TDID = '00000000-0000-0000-0000-000000000000';
|
|
575
564
|
const UID2 = '99999999-9999-9999-9999-999999999999';
|
|
@@ -601,28 +590,6 @@ describe('ttdBidAdapter', function () {
|
|
|
601
590
|
|
|
602
591
|
const requestBody = testBuildRequests(clonedBannerRequests, baseBidderRequest).data;
|
|
603
592
|
expect(requestBody.user.ext.eids).to.deep.equal(expectedEids);
|
|
604
|
-
expect(requestBody.user.buyeruid).to.equal(TDID);
|
|
605
|
-
});
|
|
606
|
-
|
|
607
|
-
it('has an empty buyeruid if tdid not found in userIdAsEids', function () {
|
|
608
|
-
const UID2 = '99999999-9999-9999-9999-999999999999';
|
|
609
|
-
let clonedBannerRequests = deepClone(baseBannerBidRequests);
|
|
610
|
-
clonedBannerRequests[0].userIdAsEids = [
|
|
611
|
-
{
|
|
612
|
-
source: 'uidapi.com',
|
|
613
|
-
uids: [
|
|
614
|
-
{
|
|
615
|
-
atype: 3,
|
|
616
|
-
id: UID2
|
|
617
|
-
}
|
|
618
|
-
]
|
|
619
|
-
}
|
|
620
|
-
];
|
|
621
|
-
const expectedEids = clonedBannerRequests[0].userIdAsEids;
|
|
622
|
-
|
|
623
|
-
const requestBody = testBuildRequests(clonedBannerRequests, baseBidderRequest).data;
|
|
624
|
-
expect(requestBody.user.ext.eids).to.deep.equal(expectedEids);
|
|
625
|
-
expect(requestBody.user.buyeruid).to.be.undefined;
|
|
626
593
|
});
|
|
627
594
|
|
|
628
595
|
it('adds first party site data to the request', function () {
|