Skip to content
7 changes: 6 additions & 1 deletion modules/allegroBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@
if (request.imp) {
request.imp.forEach(imp => {
if (imp.banner?.ext) {
moveExt(imp.banner, '[com.google.doubleclick.banner_ext]');

Check warning on line 26 in modules/allegroBidAdapter.js

View workflow job for this annotation

GitHub Actions / Coverage

26 line is not covered with tests
}
if (imp.ext) {
moveExt(imp, '[com.google.doubleclick.imp]');

Check warning on line 29 in modules/allegroBidAdapter.js

View workflow job for this annotation

GitHub Actions / Coverage

29 line is not covered with tests
}
});
}

if (request.app?.ext) {
moveExt(request.app, '[com.google.doubleclick.app]');

Check warning on line 35 in modules/allegroBidAdapter.js

View workflow job for this annotation

GitHub Actions / Coverage

35 line is not covered with tests
}

if (request.site?.ext) {
Expand Down Expand Up @@ -60,7 +60,7 @@
}

if (request.device?.geo?.ext) {
moveExt(request.device.geo, '[com.google.doubleclick.geo]');

Check warning on line 63 in modules/allegroBidAdapter.js

View workflow job for this annotation

GitHub Actions / Coverage

63 line is not covered with tests
}

if (request.regs?.ext) {
Expand Down Expand Up @@ -89,7 +89,7 @@
*/
function moveExt(obj, newKey) {
if (!obj || !obj.ext) {
return;

Check warning on line 92 in modules/allegroBidAdapter.js

View workflow job for this annotation

GitHub Actions / Coverage

92 line is not covered with tests
}
const extCopy = { ...obj.ext };
delete obj.ext;
Expand Down Expand Up @@ -140,6 +140,12 @@
request(buildRequest, imps, bidderRequest, context) {
const request = buildRequest(imps, bidderRequest, context);

const publisherId = bidderRequest.bids.find(bid => bid.params?.publisherId)?.params.publisherId;
if (publisherId) {
request.site = request.site || {};
request.site['[com.allegro.dsp.site.ext]'] = { inventory: { id: publisherId } };
}

if (request?.device?.dnt !== undefined) {
request.device.dnt = request.device.dnt === 1;
}
Expand All @@ -159,12 +165,11 @@
}

if (request?.source?.schain && !isSchainValid(request.source.schain)) {
delete request.source.schain;

Check warning on line 168 in modules/allegroBidAdapter.js

View workflow job for this annotation

GitHub Actions / Coverage

168 line is not covered with tests
}

return request;
},

/**
* Post-processes each Prebid bid response, mapping Allegro DSP extension
* fields onto the standard `meta` object so publishers can consume them.
Expand All @@ -180,7 +185,7 @@
bidResponse(buildBidResponse, bid, context) {
const bidResponse = buildBidResponse(bid, context);
if (bidResponse == null) {
return bidResponse;

Check warning on line 188 in modules/allegroBidAdapter.js

View workflow job for this annotation

GitHub Actions / Coverage

188 line is not covered with tests
}
bidResponse.meta = bidResponse.meta || {};

Expand All @@ -203,17 +208,17 @@
* @return {boolean} True if valid, false otherwise
*/
function isSchainValid(schain) {
try {
if (!schain || !schain.nodes || !Array.isArray(schain.nodes)) {
return false;

Check warning on line 213 in modules/allegroBidAdapter.js

View workflow job for this annotation

GitHub Actions / Coverage

211-213 lines are not covered with tests
}
const requiredFields = ['asi', 'sid', 'hp'];
return schain.nodes.every(node =>
requiredFields.every(field => node.hasOwnProperty(field))

Check warning on line 217 in modules/allegroBidAdapter.js

View workflow job for this annotation

GitHub Actions / Coverage

215-217 lines are not covered with tests
);
} catch (error) {
logError('Allegro: Error validating schain:', error);
return false;

Check warning on line 221 in modules/allegroBidAdapter.js

View workflow job for this annotation

GitHub Actions / Coverage

220-221 lines are not covered with tests
}
}

Expand Down
13 changes: 11 additions & 2 deletions modules/allegroBidAdapter.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,21 @@ var adUnits = [{
}
},
bids: [{
bidder: 'allegro'
bidder: 'allegro',
params: {
publisherId: 'gwp' // publisher identifier; maps to site.[com.allegro.dsp.site.ext].inventory.id in the outgoing OpenRTB request
}
}]
}];
```

## Bid Request Parameters

| Name | Scope | Type | Description |
|----------|----------|--------|-------------------------------------------------------------------------------------------------------------------------|
| `publisherId` | optional | String | Publisher identifier. When present, the value is written to the `[com.allegro.dsp.site.ext]` proto-JSON extension key on `site` as `inventory.id` in the outgoing OpenRTB bid request, enabling publisher-scoped bid entity filtering on the server side. |


# Features
## Impression Tracking

Expand Down Expand Up @@ -103,4 +113,3 @@ Example server bid response:
- **TTL**: 360 seconds
- **Net Revenue**: true
- **Content Type**: text/plain

20 changes: 19 additions & 1 deletion test/spec/modules/allegroBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ describe('Allegro Bid Adapter', () => {

it('converts extension fields by default', () => {
sinon.stub(config, 'getConfig').callsFake((key) => undefined);
const bidRequests = [buildBidRequest({})];
const bidRequests = [buildBidRequest({ params: { publisherId: 'gwp_pb' } })];
const ortb2 = {
site: { ext: { siteCustom: 'val' }, publisher: { ext: { pubCustom: 'pub' } } },
user: { ext: { userCustom: 'usr' }, data: [{ ext: { dataCustom: 'd1' } }] },
Expand All @@ -90,6 +90,7 @@ describe('Allegro Bid Adapter', () => {

expect(data.site.ext).to.equal(undefined);
expect(data.site['[com.google.doubleclick.site]'].siteCustom).to.equal('val');
expect(data.site['[com.allegro.dsp.site.ext]'].inventory.id).to.equal('gwp_pb');
expect(data.site.publisher['[com.google.doubleclick.publisher]'].pubCustom).to.equal('pub');
expect(data.user['[com.google.doubleclick.user]'].userCustom).to.equal('usr');
expect(data.user.data[0]['[com.google.doubleclick.data]'].dataCustom).to.equal('d1');
Expand All @@ -113,6 +114,23 @@ describe('Allegro Bid Adapter', () => {
expect(req.data.site['[com.google.doubleclick.site]']).to.equal(undefined);
});

it('does not add the inventory extension when publisherId is absent', () => {
sinon.stub(config, 'getConfig').callsFake((key) => undefined);
const bidRequests = [buildBidRequest({})];
const req = spec.buildRequests(bidRequests, buildBidderRequest(bidRequests));
expect(req.data.site?.['[com.allegro.dsp.site.ext]']).to.equal(undefined);
});

it('sets inventory.id even when allegro.convertExtensionFields = false', () => {
sinon.stub(config, 'getConfig').callsFake((key) => {
if (key === 'allegro.convertExtensionFields') return false;
return undefined;
});
const bidRequests = [buildBidRequest({ params: { publisherId: 'gwp_pb' } })];
const req = spec.buildRequests(bidRequests, buildBidderRequest(bidRequests));
expect(req.data.site['[com.allegro.dsp.site.ext]'].inventory.id).to.equal('gwp_pb');
});

it('converts numeric flags to booleans (topframe, secure, test) when present', () => {
sinon.stub(config, 'getConfig').callsFake((key) => undefined);
const bidRequests = [buildBidRequest({ mediaTypes: { banner: { sizes: [[300, 250]], topframe: 1 } }, params: { secure: 1 } })];
Expand Down
Loading