Skip to content

Commit

Permalink
StroeerCore Bid Adapter: add price floor support (#9962)
Browse files Browse the repository at this point in the history
  • Loading branch information
philipwatson authored Jun 7, 2023
1 parent 6fc73a3 commit a262b64
Show file tree
Hide file tree
Showing 2 changed files with 206 additions and 12 deletions.
61 changes: 55 additions & 6 deletions modules/stroeerCoreBidAdapter.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {buildUrl, deepAccess, getWindowSelf, getWindowTop, isEmpty, isStr, logWarn} from '../src/utils.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {BANNER, VIDEO} from '../src/mediaTypes.js';
import {find} from '../src/polyfill.js';

const GVL_ID = 136;
const BIDDER_CODE = 'stroeerCore';
Expand Down Expand Up @@ -211,12 +212,16 @@ const mapToPayloadBaseBid = (bidRequest) => ({
viz: elementInView(bidRequest.adUnitCode),
});

const mapToPayloadBannerBid = (bidRequest) => ({
ban: {
siz: deepAccess(bidRequest, 'mediaTypes.banner.sizes') || [],
},
...mapToPayloadBaseBid(bidRequest)
});
const mapToPayloadBannerBid = (bidRequest) => {
const sizes = deepAccess(bidRequest, 'mediaTypes.banner.sizes') || [];
return ({
ban: {
siz: sizes,
fp: createFloorPriceObject(BANNER, sizes, bidRequest)
},
...mapToPayloadBaseBid(bidRequest)
});
};

const mapToPayloadVideoBid = (bidRequest) => {
const video = deepAccess(bidRequest, 'mediaTypes.video') || {};
Expand All @@ -225,9 +230,53 @@ const mapToPayloadVideoBid = (bidRequest) => {
ctx: video.context,
siz: video.playerSize,
mim: video.mimes,
fp: createFloorPriceObject(VIDEO, [video.playerSize], bidRequest),
},
...mapToPayloadBaseBid(bidRequest)
};
};

const createFloorPriceObject = (mediaType, sizes, bidRequest) => {
if (!bidRequest.getFloor) {
return undefined;
}

const defaultFloor = bidRequest.getFloor({
currency: 'EUR',
mediaType: mediaType,
size: '*'
});

const sizeFloors = sizes.map(size => {
const floor = bidRequest.getFloor({
currency: 'EUR',
mediaType: mediaType,
size: [size[0], size[1]]
});
return {...floor, size};
});

const floorWithCurrency = find([defaultFloor].concat(sizeFloors), floor => floor.currency);

if (!floorWithCurrency) {
return undefined;
}

const currency = floorWithCurrency.currency;
const defaultFloorPrice = defaultFloor.currency === currency ? defaultFloor.floor : undefined;

return {
def: defaultFloorPrice,
cur: currency,
siz: sizeFloors
.filter(sizeFloor => sizeFloor.currency === currency)
.filter(sizeFloor => sizeFloor.floor !== defaultFloorPrice)
.map(sizeFloor => ({
w: sizeFloor.size[0],
h: sizeFloor.size[1],
p: sizeFloor.floor
}))
};
}

registerBidder(spec);
157 changes: 151 additions & 6 deletions test/spec/modules/stroeerCoreBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -527,14 +527,16 @@ describe('stroeerCore bid adapter', function () {
'bid': 'bid8',
'viz': true,
'ban': {
'siz': [[300, 600], [160, 60]]
}
'siz': [[300, 600], [160, 60]],
'fp': undefined
},
},
{
'sid': 'ABC=',
'bid': 'bid12',
'ban': {
'siz': [[100, 200], [300, 500]]
'siz': [[100, 200], [300, 500]],
'fp': undefined
},
'viz': undefined
}
Expand All @@ -548,7 +550,8 @@ describe('stroeerCore bid adapter', function () {
'vid': {
'ctx': 'instream',
'siz': [640, 480],
'mim': ['video/mp4', 'video/quicktime']
'mim': ['video/mp4', 'video/quicktime'],
'fp': undefined
}
}
];
Expand Down Expand Up @@ -589,7 +592,8 @@ describe('stroeerCore bid adapter', function () {
'bid': 'bid3',
'viz': true,
'ban': {
'siz': [[100, 200], [300, 500]]
'siz': [[100, 200], [300, 500]],
'fp': undefined
}
}
];
Expand All @@ -602,7 +606,8 @@ describe('stroeerCore bid adapter', function () {
'vid': {
'ctx': 'instream',
'siz': [640, 480],
'mim': ['video/mp4', 'video/quicktime']
'mim': ['video/mp4', 'video/quicktime'],
'fp': undefined
}
}
];
Expand Down Expand Up @@ -696,6 +701,146 @@ describe('stroeerCore bid adapter', function () {
const serverRequestInfo = spec.buildRequests(bidReq.bids, bidReq);
assert.deepEqual(serverRequestInfo.data.schain, schain);
});

it('should add floor info to banner bid request if floor is available', () => {
const bidReq = buildBidderRequest();

const getFloorStub1 = sinon.stub();
const getFloorStub2 = sinon.stub();

getFloorStub1
.returns({})
.withArgs({currency: 'EUR', mediaType: BANNER, size: '*'})
.returns({currency: 'TRY', floor: 0.7})
.withArgs({currency: 'EUR', mediaType: 'banner', size: [300, 600]})
.returns({currency: 'TRY', floor: 1.3})
.withArgs({currency: 'EUR', mediaType: 'banner', size: [160, 60]})
.returns({currency: 'TRY', floor: 2.5})

getFloorStub2
.returns({})
.withArgs({currency: 'EUR', mediaType: 'banner', size: '*'})
.returns({currency: 'USD', floor: 1.2})
.withArgs({currency: 'EUR', mediaType: 'banner', size: [728, 90]})
.returns({currency: 'USD', floor: 1.85})

bidReq.bids[0].getFloor = getFloorStub1;
bidReq.bids[1].getFloor = getFloorStub2;

const serverRequestInfo = spec.buildRequests(bidReq.bids, bidReq);

const serverRequestBids = serverRequestInfo.data.bids;
const firstBid = serverRequestBids[0];
const secondBid = serverRequestBids[1];

assert.nestedPropertyVal(firstBid, 'ban.fp.def', 0.7);
assert.nestedPropertyVal(firstBid, 'ban.fp.cur', 'TRY');
assert.deepNestedPropertyVal(firstBid, 'ban.fp.siz', [{w: 300, h: 600, p: 1.3}, {w: 160, h: 60, p: 2.5}]);

assert.isTrue(getFloorStub1.calledThrice);

assert.nestedPropertyVal(secondBid, 'ban.fp.def', 1.2);
assert.nestedPropertyVal(secondBid, 'ban.fp.cur', 'USD');
assert.deepNestedPropertyVal(secondBid, 'ban.fp.siz', [{w: 728, h: 90, p: 1.85}]);

assert.isTrue(getFloorStub2.calledTwice);
});

it('should add floor info to video bid request if floor is available', () => {
const bidReq = buildBidderRequest();

const getFloorStub1 = sinon.stub();
const getFloorStub2 = sinon.stub();

getFloorStub1
.returns({})
.withArgs({currency: 'EUR', mediaType: 'video', size: '*'})
.returns({currency: 'NZD', floor: 3.25})
.withArgs({currency: 'EUR', mediaType: 'video', size: [640, 480]})
.returns({currency: 'NZD', floor: 4.10});

getFloorStub2
.returns({})
.withArgs({currency: 'EUR', mediaType: 'video', size: '*'})
.returns({currency: 'GBP', floor: 4.75})
.withArgs({currency: 'EUR', mediaType: 'video', size: [1280, 720]})
.returns({currency: 'GBP', floor: 6.50})

delete bidReq.bids[0].mediaTypes.banner;
bidReq.bids[0].mediaTypes.video = {
playerSize: [640, 480],
context: 'instream'
};

delete bidReq.bids[1].mediaTypes.banner;
bidReq.bids[1].mediaTypes.video = {
playerSize: [1280, 720],
context: 'outstream'
};

bidReq.bids[0].getFloor = getFloorStub1;
bidReq.bids[1].getFloor = getFloorStub2;

const serverRequestInfo = spec.buildRequests(bidReq.bids, bidReq);

const serverRequestBids = serverRequestInfo.data.bids;
const firstBid = serverRequestBids[0];
const secondBid = serverRequestBids[1];

assert.nestedPropertyVal(firstBid, 'vid.fp.def', 3.25);
assert.nestedPropertyVal(firstBid, 'vid.fp.cur', 'NZD');
assert.deepNestedPropertyVal(firstBid, 'vid.fp.siz', [{w: 640, h: 480, p: 4.10}]);

assert.isTrue(getFloorStub1.calledTwice);

assert.nestedPropertyVal(secondBid, 'vid.fp.def', 4.75);
assert.nestedPropertyVal(secondBid, 'vid.fp.cur', 'GBP');
assert.deepNestedPropertyVal(secondBid, 'vid.fp.siz', [{w: 1280, h: 720, p: 6.50}]);

assert.isTrue(getFloorStub2.calledTwice);
});

it('should not add floor info to bid request if floor is unavailable', () => {
const bidReq = buildBidderRequest();
const getFloorSpy = sinon.spy(() => ({}));

delete bidReq.bids[0].getFloor;
bidReq.bids[1].getFloor = getFloorSpy;

const serverRequestInfo = spec.buildRequests(bidReq.bids, bidReq);

const serverRequestBids = serverRequestInfo.data.bids;
const firstBid = serverRequestBids[0];
const secondBid = serverRequestBids[1];

assert.nestedPropertyVal(firstBid, 'ban.fp', undefined);
assert.nestedPropertyVal(secondBid, 'ban.fp', undefined);

assert.isTrue(getFloorSpy.calledWith({currency: 'EUR', mediaType: 'banner', size: '*'}));
assert.isTrue(getFloorSpy.calledWith({currency: 'EUR', mediaType: 'banner', size: [728, 90]}));
assert.isTrue(getFloorSpy.calledTwice);
});

it('should not add floor info for a size when it is the same as the default', () => {
const bidReq = buildBidderRequest();
const getFloorStub = sinon.stub();

getFloorStub
.returns({currency: 'EUR', floor: 1.9})
.withArgs({currency: 'EUR', mediaType: BANNER, size: [160, 60]})
.returns({currency: 'EUR', floor: 2.7});

bidReq.bids[0].getFloor = getFloorStub;

const serverRequestInfo = spec.buildRequests(bidReq.bids, bidReq);

const serverRequestBids = serverRequestInfo.data.bids;
const bid = serverRequestBids[0];

assert.nestedPropertyVal(bid, 'ban.fp.def', 1.9);
assert.nestedPropertyVal(bid, 'ban.fp.cur', 'EUR');
assert.deepNestedPropertyVal(bid, 'ban.fp.siz', [{w: 160, h: 60, p: 2.7}]);
});
});
});
});
Expand Down

0 comments on commit a262b64

Please sign in to comment.