Skip to content

Commit

Permalink
YieldlabBidAdapter updated native asset mapping (#9989)
Browse files Browse the repository at this point in the history
* YieldlabBidAdapter updated native asset mapping for adserver responses for icons

* YieldlabBidAdapter removed magic numbers and improved image asset filtering
  • Loading branch information
nkloeber authored Jun 7, 2023
1 parent c6c9321 commit 6fc73a3
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 16 deletions.
37 changes: 23 additions & 14 deletions modules/yieldlabBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ const CURRENCY_CODE = 'EUR';
const OUTSTREAMPLAYER_URL = 'https://ad.adition.com/dynamic.ad?a=o193092&ma_loadEvent=ma-start-event';
const GVLID = 70;
const DIMENSION_SIGN = 'x';
const IMG_TYPE_ICON = 1;
const IMG_TYPE_MAIN = 3;

export const spec = {
code: BIDDER_CODE,
Expand Down Expand Up @@ -183,24 +185,33 @@ export const spec = {
}

if (isNative(bidRequest, adType)) {
// there may be publishers still rely on it
const { native } = matchedBid;
const { assets } = native;
bidResponse.adUrl = `${ENDPOINT}/d/${matchedBid.id}/${bidRequest.params.supplyId}/?ts=${timestamp}${extId}${gdprApplies}${gdprConsent}${pvId}`;
bidResponse.mediaType = NATIVE;
const nativeImageAssetObj = find(matchedBid.native.assets, asset => isMainImage(asset));
const nativeIconAssetObj = find(assets, isImageAssetOfType(IMG_TYPE_ICON));
const nativeImageAssetObj = find(assets, isImageAssetOfType(IMG_TYPE_MAIN));
const nativeImageAsset = nativeImageAssetObj ? nativeImageAssetObj.img : { url: '', w: 0, h: 0 };
const nativeTitleAsset = find(matchedBid.native.assets, asset => hasValidProperty(asset, 'title'));
const nativeBodyAsset = find(matchedBid.native.assets, asset => hasValidProperty(asset, 'data'));
const nativeTitleAsset = find(assets, asset => hasValidProperty(asset, 'title'));
const nativeBodyAsset = find(assets, asset => hasValidProperty(asset, 'data'));
bidResponse.native = {
title: nativeTitleAsset ? nativeTitleAsset.title.text : '',
body: nativeBodyAsset ? nativeBodyAsset.data.value : '',
...nativeIconAssetObj?.img && {
icon: {
url: nativeIconAssetObj.img.url,
width: nativeIconAssetObj.img.w,
height: nativeIconAssetObj.img.h,
},
},
image: {
url: nativeImageAsset.url,
width: nativeImageAsset.w,
height: nativeImageAsset.h,
},
clickUrl: matchedBid.native.link.url,
impressionTrackers: matchedBid.native.imptrackers,
assets: matchedBid.native.assets,
clickUrl: native.link.url,
impressionTrackers: native.imptrackers,
assets: assets,
};
}

Expand Down Expand Up @@ -517,14 +528,12 @@ function hasValidProperty(obj, propName) {
}

/**
* Checks if an asset object is a main image.
* A main image is defined as an image asset whose type value is 3.
*
* @param {Object} asset - The asset object to check.
* @returns {boolean} Returns true if the object has a property img.type with a value of 3, otherwise false.
* Returns a filtering function for image assets based on type.
* @param {number} type - The desired asset type to filter for i.e. IMG_TYPE_ICON = 1, IMG_TYPE_MAIN = 3
* @returns {function} - A filtering function that accepts an asset and checks if its img.type matches the desired type.
*/
function isMainImage(asset) {
return asset?.img?.type === 3
function isImageAssetOfType(type) {
return asset => asset?.img?.type === type;
}

registerBidder(spec);
44 changes: 42 additions & 2 deletions test/spec/modules/yieldlabBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,15 @@ const NATIVE_RESPONSE = Object.assign({}, RESPONSE, {
value: 'Native body value',
},
},
{
id: 4,
img: {
url: 'https://localhost:8080/assets/favicon/favicon-16x16.png',
w: 16,
h: 16,
type: 1,
},
},
],
imptrackers: [
'http://localhost:8080/ve?d=ODE9ZSY2MTI1MjAzNjMzMzYxPXN0JjA0NWUwZDk0NTY5Yi05M2FiLWUwZTQtOWFjNy1hYWY0MzFiZj1kaXQmMj12',
Expand Down Expand Up @@ -567,15 +576,24 @@ describe('yieldlabBidAdapter', () => {
expect(result[0].native.image.url).to.equal('https://localhost:8080/yl-logo100x100.jpg');
expect(result[0].native.image.width).to.equal(100);
expect(result[0].native.image.height).to.equal(100);
expect(result[0].native.icon.url).to.equal('https://localhost:8080/assets/favicon/favicon-16x16.png');
expect(result[0].native.icon.width).to.equal(16);
expect(result[0].native.icon.height).to.equal(16);
expect(result[0].native.clickUrl).to.equal('https://www.yieldlab.de');
expect(result[0].native.impressionTrackers.length).to.equal(3);
expect(result[0].native.assets.length).to.equal(3);
expect(result[0].native.assets.length).to.equal(4);
const titleAsset = result[0].native.assets.find(asset => 'title' in asset);
const imageAsset = result[0].native.assets.find(asset => 'img' in asset);
const imageAsset = result[0].native.assets.find((asset) => {
return asset?.img?.type === 3;
});
const iconAsset = result[0].native.assets.find((asset) => {
return asset?.img?.type === 1;
});
const bodyAsset = result[0].native.assets.find(asset => 'data' in asset);
expect(titleAsset).to.exist.and.to.have.nested.property('id', 1)
expect(imageAsset).to.exist.and.to.have.nested.property('id', 2)
expect(bodyAsset).to.exist.and.to.have.nested.property('id', 3)
expect(iconAsset).to.exist.and.to.have.nested.property('id', 4)
});

it('should add adUrl and default native assets when type is Native', () => {
Expand All @@ -601,6 +619,28 @@ describe('yieldlabBidAdapter', () => {
expect(result[0].native.image.height).to.equal(0);
});

it('should not add icon if not present in the native response', () => {
const NATIVE_RESPONSE_WITHOUT_ICON = Object.assign({}, NATIVE_RESPONSE, {
native: {
link: {
url: 'https://www.yieldlab.de',
},
assets: [
{
id: 1,
title: {
text: 'This is a great headline',
}
}
],
imptrackers: [],
},
});
const result = spec.interpretResponse({body: [NATIVE_RESPONSE_WITHOUT_ICON]}, {validBidRequests: [NATIVE_REQUEST()], queryParams: REQPARAMS});
expect(result[0].native.hasOwnProperty('icon')).to.be.false;
expect(result[0].native.title).to.equal('This is a great headline');
});

it('should append gdpr parameters to vastUrl', () => {
const result = spec.interpretResponse({body: [VIDEO_RESPONSE]}, {validBidRequests: [VIDEO_REQUEST()], queryParams: REQPARAMS_GDPR});

Expand Down

0 comments on commit 6fc73a3

Please sign in to comment.