Skip to content

Commit

Permalink
Accept paapiAuctionConfigs from adapters
Browse files Browse the repository at this point in the history
  • Loading branch information
dgirardi committed Apr 2, 2024
1 parent bb4bdbb commit e6d2edd
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 35 deletions.
22 changes: 17 additions & 5 deletions src/adapters/bidderFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ import {ACTIVITY_TRANSMIT_TID, ACTIVITY_TRANSMIT_UFPD} from '../activities/activ
/**
* @typedef {object} BidderAuctionResponse An object encapsulating an adapter response for current Auction
*
* @property {Array<Bid>} bids Contextual bids returned by this adapter, if any
* @property {object|null} fledgeAuctionConfigs Optional FLEDGE response, as a map of impid -> auction_config
* @property {[Bid]} bids? Contextual bids returned by this adapter, if any
* @property {[{bidId: String, config: {}}]} paapiAuctionConfigs? Array of paapi auction configs, each scoped to a particular bidId
*/

/**
Expand Down Expand Up @@ -361,6 +361,18 @@ export function newBidder(spec) {
}
}

// Transition from 'fledge' to 'paapi'
// TODO: remove this in prebid 9
const PAAPI_RESPONSE_PROPS = ['paapiAuctionConfigs', 'fledgeAuctionConfigs'];
const RESPONSE_PROPS = ['bids'].concat(PAAPI_RESPONSE_PROPS);
function getPaapiConfigs(adapterResponse) {
const [paapi, fledge] = PAAPI_RESPONSE_PROPS.map(prop => adapterResponse[prop]);
if (paapi != null && fledge != null) {
throw new Error(`Adapter response should use ${PAAPI_RESPONSE_PROPS[0]} over ${PAAPI_RESPONSE_PROPS[1]}, not both`);
}
return paapi ?? fledge;
}

/**
* Run a set of bid requests - that entails converting them to HTTP requests, sending
* them over the network, and parsing the responses.
Expand Down Expand Up @@ -425,12 +437,12 @@ export const processBidderRequests = hook('sync', function (spec, bids, bidderRe
// adapters can reply with:
// a single bid
// an array of bids
// an object with {bids: [*], fledgeAuctionConfigs: [*]}
// a BidderAuctionResponse object ({bids: [*], paapiAuctionConfigs: [*]})

const RESPONSE_PROPS = ['bids', 'fledgeAuctionConfigs'];
let bids, paapiConfigs;
if (response && !Object.keys(response).some(key => !RESPONSE_PROPS.includes(key))) {
[bids, paapiConfigs] = RESPONSE_PROPS.map(k => response[k]);
bids = response.bids;
paapiConfigs = getPaapiConfigs(response);
} else {
bids = response;
}
Expand Down
69 changes: 39 additions & 30 deletions test/spec/unit/core/bidderFactory_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1456,7 +1456,7 @@ describe('bidderFactory', () => {
transactionId: 'au',
}]
};
const fledgeAuctionConfig = {
const paapiConfig = {
bidId: '1',
config: {
foo: 'bar'
Expand All @@ -1482,50 +1482,59 @@ describe('bidderFactory', () => {
sinon.assert.calledWith(addBidResponseStub, 'mock/placement', sinon.match(bid));
})

describe('when response has FLEDGE auction config', function() {
let fledgeStub;
describe('when response has PAAPI auction config', function() {
let paapiStub;

function fledgeHook(next, ...args) {
fledgeStub(...args);
function paapiHook(next, ...args) {
paapiStub(...args);
}

before(() => {
addComponentAuction.before(fledgeHook);
addComponentAuction.before(paapiHook);
});

after(() => {
addComponentAuction.getHooks({hook: fledgeHook}).remove();
addComponentAuction.getHooks({hook: paapiHook}).remove();
})

beforeEach(function () {
fledgeStub = sinon.stub();
paapiStub = sinon.stub();
});

it('should call fledgeManager with FLEDGE configs', function() {
const bidder = newBidder(spec);
spec.interpretResponse.returns({
bids: bids,
fledgeAuctionConfigs: [fledgeAuctionConfig]
});
bidder.callBids(bidRequest, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback);
['fledgeAuctionConfigs', 'paapiAuctionConfigs'].forEach(paapiProp => {
describe(`using ${paapiProp}`, () => {
it('should call paapi hook with PAAPI configs', function() {
const bidder = newBidder(spec);
spec.interpretResponse.returns({
bids: bids,
[paapiProp]: [paapiConfig]
});
bidder.callBids(bidRequest, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback);

expect(fledgeStub.calledOnce).to.equal(true);
sinon.assert.calledWith(fledgeStub, bidRequest.bids[0], fledgeAuctionConfig.config);
expect(addBidResponseStub.calledOnce).to.equal(true);
expect(addBidResponseStub.firstCall.args[0]).to.equal('mock/placement');
})
expect(paapiStub.calledOnce).to.equal(true);
sinon.assert.calledWith(paapiStub, bidRequest.bids[0], paapiConfig.config);
expect(addBidResponseStub.calledOnce).to.equal(true);
expect(addBidResponseStub.firstCall.args[0]).to.equal('mock/placement');
})

it('should call fledgeManager with FLEDGE configs even if no bids returned', function() {
const bidder = newBidder(spec);
spec.interpretResponse.returns({
bids: [],
fledgeAuctionConfigs: [fledgeAuctionConfig]
});
bidder.callBids(bidRequest, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback);
Object.entries({
'missing': undefined,
'an empty array': []
}).forEach(([t, bids]) => {
it(`should call paapi hook with PAAPI configs even bids is ${t}`, function() {
const bidder = newBidder(spec);
spec.interpretResponse.returns({
bids,
[paapiProp]: [paapiConfig]
});
bidder.callBids(bidRequest, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback);

expect(fledgeStub.calledOnce).to.be.true;
sinon.assert.calledWith(fledgeStub, bidRequest.bids[0], fledgeAuctionConfig.config);
expect(addBidResponseStub.calledOnce).to.equal(false);
expect(paapiStub.calledOnce).to.be.true;
sinon.assert.calledWith(paapiStub, bidRequest.bids[0], paapiConfig.config);
expect(addBidResponseStub.calledOnce).to.equal(false);
})
})
})
})
})
})
Expand Down

0 comments on commit e6d2edd

Please sign in to comment.