Skip to content

Commit

Permalink
Core: fix native render when adUnits defines mediaTypes.native.ortb
Browse files Browse the repository at this point in the history
… but adapter replies with "legacy" native bid (#9638)

* Fix conversion to ortb native

* Add natvie ortb  response to message payload when the adUnit uses native ortb
  • Loading branch information
dgirardi authored Mar 9, 2023
1 parent 7785060 commit 9de8066
Show file tree
Hide file tree
Showing 2 changed files with 186 additions and 141 deletions.
11 changes: 7 additions & 4 deletions src/native.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import {
isNumber,
isPlainObject,
logError,
triggerPixel,
pick
pick,
triggerPixel
} from './utils.js';
import {includes} from './polyfill.js';
import {auctionManager} from './auctionManager.js';
Expand Down Expand Up @@ -385,16 +385,19 @@ export function getNativeTargeting(bid, {index = auctionManager.index} = {}) {
return keyValues;
}

function assetsMessage(data, adObject, keys) {
function assetsMessage(data, adObject, keys, {index = auctionManager.index} = {}) {
const message = {
message: 'assetResponse',
adId: data.adId,
};

const adUnit = index.getAdUnit(adObject);
let nativeResp = adObject.native;

if (adObject.native.ortb) {
message.ortb = adObject.native.ortb;
} else if (adUnit.mediaTypes?.native?.ortb) {
message.ortb = toOrtbNativeResponse(adObject.native, adUnit.nativeOrtbRequest);
}
message.assets = [];

Expand Down Expand Up @@ -698,7 +701,7 @@ export function toOrtbNativeResponse(legacyResponse, ortbRequest) {
}

Object.keys(legacyResponse).filter(key => !!legacyResponse[key]).forEach(key => {
const value = legacyResponse[key];
const value = getAssetValue(legacyResponse[key]);
switch (key) {
// process titles
case 'title':
Expand Down
316 changes: 179 additions & 137 deletions test/spec/native_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
import CONSTANTS from 'src/constants.json';
import { stubAuctionIndex } from '../helpers/indexStub.js';
import { convertOrtbRequestToProprietaryNative, fromOrtbNativeRequest } from '../../src/native.js';
import {auctionManager} from '../../src/auctionManager.js';
const utils = require('src/utils');

const bid = {
Expand Down Expand Up @@ -430,158 +431,180 @@ describe('native.js', function () {
sinon.assert.calledWith(triggerPixelStub, bid.native.clickTrackers[0]);
});

it('creates native asset message', function () {
const messageRequest = {
message: 'Prebid Native',
action: 'assetRequest',
adId: '123',
assets: ['hb_native_body', 'hb_native_image', 'hb_native_linkurl'],
};
describe('native postMessages', () => {
let adUnit;
beforeEach(() => {
adUnit = {};
sinon.stub(auctionManager, 'index').get(() => ({
getAdUnit: () => adUnit
}))
});

it('creates native asset message', function () {
const messageRequest = {
message: 'Prebid Native',
action: 'assetRequest',
adId: '123',
assets: ['hb_native_body', 'hb_native_image', 'hb_native_linkurl'],
};

const message = getAssetMessage(messageRequest, bid);
const message = getAssetMessage(messageRequest, bid);

expect(message.assets.length).to.equal(3);
expect(message.assets).to.deep.include({
key: 'body',
value: bid.native.body,
});
expect(message.assets).to.deep.include({
key: 'image',
value: bid.native.image.url,
});
expect(message.assets).to.deep.include({
key: 'clickUrl',
value: bid.native.clickUrl,
expect(message.assets.length).to.equal(3);
expect(message.assets).to.deep.include({
key: 'body',
value: bid.native.body,
});
expect(message.assets).to.deep.include({
key: 'image',
value: bid.native.image.url,
});
expect(message.assets).to.deep.include({
key: 'clickUrl',
value: bid.native.clickUrl,
});
});
});

it('creates native all asset message', function () {
const messageRequest = {
message: 'Prebid Native',
action: 'allAssetRequest',
adId: '123',
};
it('creates native all asset message', function () {
const messageRequest = {
message: 'Prebid Native',
action: 'allAssetRequest',
adId: '123',
};

const message = getAllAssetsMessage(messageRequest, bid);
const message = getAllAssetsMessage(messageRequest, bid);

expect(message.assets.length).to.equal(10);
expect(message.assets).to.deep.include({
key: 'body',
value: bid.native.body,
});
expect(message.assets).to.deep.include({
key: 'image',
value: bid.native.image.url,
});
expect(message.assets).to.deep.include({
key: 'clickUrl',
value: bid.native.clickUrl,
});
expect(message.assets).to.deep.include({
key: 'title',
value: bid.native.title,
});
expect(message.assets).to.deep.include({
key: 'icon',
value: bid.native.icon.url,
});
expect(message.assets).to.deep.include({
key: 'cta',
value: bid.native.cta,
});
expect(message.assets).to.deep.include({
key: 'sponsoredBy',
value: bid.native.sponsoredBy,
});
expect(message.assets).to.deep.include({
key: 'foo',
value: bid.native.ext.foo,
});
expect(message.assets).to.deep.include({
key: 'baz',
value: bid.native.ext.baz,
expect(message.assets.length).to.equal(10);
expect(message.assets).to.deep.include({
key: 'body',
value: bid.native.body,
});
expect(message.assets).to.deep.include({
key: 'image',
value: bid.native.image.url,
});
expect(message.assets).to.deep.include({
key: 'clickUrl',
value: bid.native.clickUrl,
});
expect(message.assets).to.deep.include({
key: 'title',
value: bid.native.title,
});
expect(message.assets).to.deep.include({
key: 'icon',
value: bid.native.icon.url,
});
expect(message.assets).to.deep.include({
key: 'cta',
value: bid.native.cta,
});
expect(message.assets).to.deep.include({
key: 'sponsoredBy',
value: bid.native.sponsoredBy,
});
expect(message.assets).to.deep.include({
key: 'foo',
value: bid.native.ext.foo,
});
expect(message.assets).to.deep.include({
key: 'baz',
value: bid.native.ext.baz,
});
});
});

it('creates native all asset message with only defined fields', function () {
const messageRequest = {
message: 'Prebid Native',
action: 'allAssetRequest',
adId: '123',
};
it('creates native all asset message with only defined fields', function () {
const messageRequest = {
message: 'Prebid Native',
action: 'allAssetRequest',
adId: '123',
};

const message = getAllAssetsMessage(messageRequest, bidWithUndefinedFields);
const message = getAllAssetsMessage(messageRequest, bidWithUndefinedFields);

expect(message.assets.length).to.equal(4);
expect(message.assets).to.deep.include({
key: 'clickUrl',
value: bid.native.clickUrl,
});
expect(message.assets).to.deep.include({
key: 'title',
value: bid.native.title,
});
expect(message.assets).to.deep.include({
key: 'sponsoredBy',
value: bid.native.sponsoredBy,
});
expect(message.assets).to.deep.include({
key: 'foo',
value: bid.native.ext.foo,
expect(message.assets.length).to.equal(4);
expect(message.assets).to.deep.include({
key: 'clickUrl',
value: bid.native.clickUrl,
});
expect(message.assets).to.deep.include({
key: 'title',
value: bid.native.title,
});
expect(message.assets).to.deep.include({
key: 'sponsoredBy',
value: bid.native.sponsoredBy,
});
expect(message.assets).to.deep.include({
key: 'foo',
value: bid.native.ext.foo,
});
});
});

it('creates native all asset message with complete format', function () {
const messageRequest = {
message: 'Prebid Native',
action: 'allAssetRequest',
adId: '123',
};
it('creates native all asset message with complete format', function () {
const messageRequest = {
message: 'Prebid Native',
action: 'allAssetRequest',
adId: '123',
};

const message = getAllAssetsMessage(messageRequest, completeNativeBid);
const message = getAllAssetsMessage(messageRequest, completeNativeBid);

expect(message.assets.length).to.equal(10);
expect(message.assets).to.deep.include({
key: 'body',
value: bid.native.body,
});
expect(message.assets).to.deep.include({
key: 'image',
value: bid.native.image.url,
});
expect(message.assets).to.deep.include({
key: 'clickUrl',
value: bid.native.clickUrl,
});
expect(message.assets).to.deep.include({
key: 'title',
value: bid.native.title,
});
expect(message.assets).to.deep.include({
key: 'icon',
value: bid.native.icon.url,
});
expect(message.assets).to.deep.include({
key: 'cta',
value: bid.native.cta,
});
expect(message.assets).to.deep.include({
key: 'sponsoredBy',
value: bid.native.sponsoredBy,
});
expect(message.assets).to.deep.include({
key: 'privacyLink',
value: ortbBid.native.ortb.privacy,
});
expect(message.assets).to.deep.include({
key: 'foo',
value: bid.native.ext.foo,
});
expect(message.assets).to.deep.include({
key: 'baz',
value: bid.native.ext.baz,
expect(message.assets.length).to.equal(10);
expect(message.assets).to.deep.include({
key: 'body',
value: bid.native.body,
});
expect(message.assets).to.deep.include({
key: 'image',
value: bid.native.image.url,
});
expect(message.assets).to.deep.include({
key: 'clickUrl',
value: bid.native.clickUrl,
});
expect(message.assets).to.deep.include({
key: 'title',
value: bid.native.title,
});
expect(message.assets).to.deep.include({
key: 'icon',
value: bid.native.icon.url,
});
expect(message.assets).to.deep.include({
key: 'cta',
value: bid.native.cta,
});
expect(message.assets).to.deep.include({
key: 'sponsoredBy',
value: bid.native.sponsoredBy,
});
expect(message.assets).to.deep.include({
key: 'privacyLink',
value: ortbBid.native.ortb.privacy,
});
expect(message.assets).to.deep.include({
key: 'foo',
value: bid.native.ext.foo,
});
expect(message.assets).to.deep.include({
key: 'baz',
value: bid.native.ext.baz,
});
});
});

it('if necessary, adds ortb response when the request was in ortb', () => {
const messageRequest = {
message: 'Prebid Native',
action: 'allAssetRequest',
adId: '123',
};
adUnit = {mediaTypes: {native: {ortb: ortbRequest}}, nativeOrtbRequest: ortbRequest}
const message = getAllAssetsMessage(messageRequest, bid);
const expected = toOrtbNativeResponse(bid.native, ortbRequest)
expect(message.ortb).to.eql(expected);
})
})

const SAMPLE_ORTB_REQUEST = toOrtbNativeRequest({
title: 'vtitle',
Expand Down Expand Up @@ -1303,5 +1326,24 @@ describe('toOrtbNativeResponse', () => {
text: 'vtitle'
}
})
});

it('should accept objects as legacy assets', () => {
const legacyResponse = {
icon: {
url: 'image-url'
}
}
const request = toOrtbNativeRequest({
icon: {
required: true
}
});
const response = toOrtbNativeResponse(legacyResponse, request);
sinon.assert.match(response.assets[0], {
img: {
url: 'image-url'
}
})
})
})

0 comments on commit 9de8066

Please sign in to comment.