Skip to content

Commit

Permalink
RTB House Bid Adapter: paapi response interpreter uses additional con…
Browse files Browse the repository at this point in the history
…fig params (prebid#12197)

* RTB House Bid Adapter: paapi response interpreter uses additional config params

* RTB House Bid Adapter: fix lint errors
  • Loading branch information
piotrj-rtbh authored Sep 3, 2024
1 parent a8b7e98 commit fe190c3
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 18 deletions.
39 changes: 25 additions & 14 deletions modules/rtbhouseBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,11 @@ export const spec = {
let computedEndpointUrl = ENDPOINT_URL;

if (bidderRequest.paapi?.enabled) {
const fledgeConfig = config.getConfig('fledgeConfig') || {
const fromConfig = config.getConfig('paapiConfig') || config.getConfig('fledgeConfig') || { sellerTimeout: 500 };
const fledgeConfig = {
seller: FLEDGE_SELLER_URL,
decisionLogicUrl: FLEDGE_DECISION_LOGIC_URL,
sellerTimeout: 500
...fromConfig
};
mergeDeep(request, { ext: { fledge_config: fledgeConfig } });
computedEndpointUrl = FLEDGE_ENDPOINT_URL;
Expand Down Expand Up @@ -165,32 +166,42 @@ export const spec = {
interpretResponse: function (serverResponse, originalRequest) {
let bids;

const fledgeInterestGroupBuyers = config.getConfig('fledgeConfig.interestGroupBuyers') || [];
const responseBody = serverResponse.body;
let fledgeAuctionConfigs = null;

if (responseBody.bidid && isArray(responseBody?.ext?.igbid)) {
// we have fledge response
// mimic the original response ([{},...])
bids = this.interpretOrtbResponse({ body: responseBody.seatbid[0]?.bid }, originalRequest);

const seller = responseBody.ext.seller;
const decisionLogicUrl = responseBody.ext.decisionLogicUrl;
const sellerTimeout = 'sellerTimeout' in responseBody.ext ? { sellerTimeout: responseBody.ext.sellerTimeout } : {};
const paapiAdapterConfig = config.getConfig('paapiConfig') || config.getConfig('fledgeConfig') || {};
const fledgeInterestGroupBuyers = paapiAdapterConfig.interestGroupBuyers || [];
// values from the response.ext are the most important
const {
decisionLogicUrl = paapiAdapterConfig.decisionLogicUrl || paapiAdapterConfig.decisionLogicURL ||
FLEDGE_DECISION_LOGIC_URL,
seller = paapiAdapterConfig.seller || FLEDGE_SELLER_URL,
sellerTimeout = 500
} = responseBody.ext;

const fledgeConfig = {
seller,
decisionLogicUrl,
decisionLogicURL: decisionLogicUrl,
sellerTimeout
};
// fledgeConfig settings are more important; other paapiAdapterConfig settings are facultative
mergeDeep(fledgeConfig, paapiAdapterConfig, fledgeConfig);
responseBody.ext.igbid.forEach((igbid) => {
const perBuyerSignals = {};
const perBuyerSignals = {...fledgeConfig.perBuyerSignals}; // may come from paapiAdapterConfig
igbid.igbuyer.forEach(buyerItem => {
perBuyerSignals[buyerItem.igdomain] = buyerItem.buyersignal
});
fledgeAuctionConfigs = fledgeAuctionConfigs || {};
fledgeAuctionConfigs[igbid.impid] = mergeDeep(
fledgeAuctionConfigs[igbid.impid] = mergeDeep({}, fledgeConfig,
{
seller,
decisionLogicUrl,
interestGroupBuyers: [...fledgeInterestGroupBuyers, ...Object.keys(perBuyerSignals)],
interestGroupBuyers: [...new Set([...fledgeInterestGroupBuyers, ...Object.keys(perBuyerSignals)])],
perBuyerSignals,
},
sellerTimeout
}
);
});
} else {
Expand Down
81 changes: 77 additions & 4 deletions test/spec/modules/rtbhouseBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ describe('RTBHouseAdapter', () => {
let bidRequest = Object.assign([], bidRequests);
delete bidRequest[0].params.test;
config.setConfig({ fledgeConfig: true });
const request = spec.buildRequests(bidRequest, { ...bidderRequest, paapi: {enabled: true} });
const request = spec.buildRequests(bidRequest, { ...bidderRequest, paapi: { enabled: true } });
expect(request.url).to.equal('https://prebid-eu.creativecdn.com/bidder/prebidfledge/bids');
expect(request.method).to.equal('POST');
});
Expand All @@ -470,7 +470,7 @@ describe('RTBHouseAdapter', () => {
delete bidRequest[0].params.test;

config.setConfig({ fledgeConfig: false });
const request = spec.buildRequests(bidRequest, {...bidderRequest, paapi: {enabled: true}});
const request = spec.buildRequests(bidRequest, { ...bidderRequest, paapi: {enabled: true} });
const data = JSON.parse(request.data);
expect(data.ext).to.exist.and.to.be.a('object');
expect(data.ext.fledge_config).to.exist.and.to.be.a('object');
Expand All @@ -480,7 +480,7 @@ describe('RTBHouseAdapter', () => {
expect(data.ext.fledge_config.sellerTimeout).to.equal(500);
});

it('sets a fledgeConfig object values when available from config', function () {
it('sets request.ext.fledge_config object values when available from fledgeConfig', function () {
let bidRequest = Object.assign([], bidRequests);
delete bidRequest[0].params.test;

Expand All @@ -490,7 +490,7 @@ describe('RTBHouseAdapter', () => {
decisionLogicUrl: 'https://sellers.domain/decision.url'
}
});
const request = spec.buildRequests(bidRequest, {...bidderRequest, paapi: {enabled: true}});
const request = spec.buildRequests(bidRequest, { ...bidderRequest, paapi: {enabled: true} });
const data = JSON.parse(request.data);
expect(data.ext).to.exist.and.to.be.a('object');
expect(data.ext.fledge_config).to.exist.and.to.be.a('object');
Expand All @@ -500,6 +500,49 @@ describe('RTBHouseAdapter', () => {
expect(data.ext.fledge_config.sellerTimeout).to.not.exist;
});

it('sets request.ext.fledge_config object values when available from paapiConfig', function () {
let bidRequest = Object.assign([], bidRequests);
delete bidRequest[0].params.test;

config.setConfig({
paapiConfig: {
seller: 'https://sellers.domain',
decisionLogicUrl: 'https://sellers.domain/decision.url'
}
});
const request = spec.buildRequests(bidRequest, { ...bidderRequest, paapi: {enabled: true} });
const data = JSON.parse(request.data);
expect(data.ext).to.exist.and.to.be.a('object');
expect(data.ext.fledge_config).to.exist.and.to.be.a('object');
expect(data.ext.fledge_config).to.contain.keys('seller', 'decisionLogicUrl');
expect(data.ext.fledge_config.seller).to.equal('https://sellers.domain');
expect(data.ext.fledge_config.decisionLogicUrl).to.equal('https://sellers.domain/decision.url');
expect(data.ext.fledge_config.sellerTimeout).to.not.exist;
});

it('sets request.ext.fledge_config object values when available from paapiConfig rather than from fledgeConfig if both exist', function () {
let bidRequest = Object.assign([], bidRequests);
delete bidRequest[0].params.test;

config.setConfig({
paapiConfig: {
seller: 'https://paapiconfig.sellers.domain',
decisionLogicUrl: 'https://paapiconfig.sellers.domain/decision.url'
},
fledgeConfig: {
seller: 'https://fledgeconfig.sellers.domain',
decisionLogicUrl: 'https://fledgeconfig.sellers.domain/decision.url'
}
});
const request = spec.buildRequests(bidRequest, { ...bidderRequest, paapi: {enabled: true} });
const data = JSON.parse(request.data);
expect(data.ext).to.exist.and.to.be.a('object');
expect(data.ext.fledge_config).to.exist.and.to.be.a('object');
expect(data.ext.fledge_config).to.contain.keys('seller', 'decisionLogicUrl');
expect(data.ext.fledge_config.seller).to.equal('https://paapiconfig.sellers.domain');
expect(data.ext.fledge_config.decisionLogicUrl).to.equal('https://paapiconfig.sellers.domain/decision.url');
});

it('when FLEDGE is disabled, should not send imp.ext.ae', function () {
let bidRequest = Object.assign([], bidRequests);
delete bidRequest[0].params.test;
Expand Down Expand Up @@ -788,6 +831,36 @@ describe('RTBHouseAdapter', () => {
});
});

context('when the response contains FLEDGE auction config and bid request has additional signals in paapiConfig', function () {
let bidderRequest;
config.setConfig({
paapiConfig: {
interestGroupBuyers: ['https://buyer1.com'],
perBuyerSignals: {
'https://buyer1.com': { signal: 1 }
},
customSignal: 1
}
});
let response = spec.interpretResponse({body: fledgeResponse}, {bidderRequest});

it('should have 2 buyers in interestGroupBuyers', function () {
expect(response.paapi[0].config.interestGroupBuyers.length).to.equal(2);
expect(response.paapi[0].config.interestGroupBuyers).to.have.members(['https://buyer1.com', 'https://buyer-domain.com']);
});

it('should have 2 perBuyerSignals with proper values', function () {
expect(response.paapi[0].config.perBuyerSignals).to.contain.keys('https://buyer1.com', 'https://buyer-domain.com');
expect(response.paapi[0].config.perBuyerSignals['https://buyer1.com']).to.deep.equal({ signal: 1 });
expect(response.paapi[0].config.perBuyerSignals['https://buyer-domain.com']).to.deep.equal({});
});

it('should contain any custom signal passed via paapiConfig', function () {
expect(response.paapi[0].config).to.contain.keys('customSignal');
expect(response.paapi[0].config.customSignal).to.equal(1);
});
});

context('when the response contains DSA object', function () {
it('should get correct bid response', function () {
const dsa = {
Expand Down

0 comments on commit fe190c3

Please sign in to comment.