Skip to content

Commit

Permalink
Edge226 Bid Adapter : updates to use the teqblaze library (#12178)
Browse files Browse the repository at this point in the history
* New adapter Edge226

* upd to teqblaze style
  • Loading branch information
Edge226Ads authored Aug 28, 2024
1 parent 06ead4c commit dd35fd8
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 192 deletions.
180 changes: 4 additions & 176 deletions modules/edge226BidAdapter.js
Original file line number Diff line number Diff line change
@@ -1,189 +1,17 @@
import { isFn, deepAccess, logMessage, logError } from '../src/utils.js';
import { convertOrtbRequestToProprietaryNative } from '../src/native.js';

import { registerBidder } from '../src/adapters/bidderFactory.js';
import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js';
import { config } from '../src/config.js';
import { isBidRequestValid, buildRequests, interpretResponse } from '../libraries/teqblazeUtils/bidderUtils.js';

const BIDDER_CODE = 'edge226';
const AD_URL = 'https://ssp.dauup.com/pbjs';

function isBidResponseValid(bid) {
if (!bid.requestId || !bid.cpm || !bid.creativeId || !bid.ttl || !bid.currency) {
return false;
}

switch (bid.mediaType) {
case BANNER:
return Boolean(bid.width && bid.height && bid.ad);
case VIDEO:
return Boolean(bid.vastUrl || bid.vastXml);
case NATIVE:
return Boolean(bid.native && bid.native.impressionTrackers && bid.native.impressionTrackers.length);
default:
return false;
}
}

function getPlacementReqData(bid) {
const { params, bidId, mediaTypes } = bid;
const schain = bid.schain || {};
const { placementId, endpointId } = params;
const bidfloor = getBidFloor(bid);

const placement = {
bidId,
schain,
bidfloor
};

if (placementId) {
placement.placementId = placementId;
placement.type = 'publisher';
} else if (endpointId) {
placement.endpointId = endpointId;
placement.type = 'network';
}

if (mediaTypes && mediaTypes[BANNER]) {
placement.adFormat = BANNER;
placement.sizes = mediaTypes[BANNER].sizes;
} else if (mediaTypes && mediaTypes[VIDEO]) {
placement.adFormat = VIDEO;
placement.playerSize = mediaTypes[VIDEO].playerSize;
placement.minduration = mediaTypes[VIDEO].minduration;
placement.maxduration = mediaTypes[VIDEO].maxduration;
placement.mimes = mediaTypes[VIDEO].mimes;
placement.protocols = mediaTypes[VIDEO].protocols;
placement.startdelay = mediaTypes[VIDEO].startdelay;
placement.placement = mediaTypes[VIDEO].placement;
placement.plcmt = mediaTypes[VIDEO].plcmt;
placement.skip = mediaTypes[VIDEO].skip;
placement.skipafter = mediaTypes[VIDEO].skipafter;
placement.minbitrate = mediaTypes[VIDEO].minbitrate;
placement.maxbitrate = mediaTypes[VIDEO].maxbitrate;
placement.delivery = mediaTypes[VIDEO].delivery;
placement.playbackmethod = mediaTypes[VIDEO].playbackmethod;
placement.api = mediaTypes[VIDEO].api;
placement.linearity = mediaTypes[VIDEO].linearity;
} else if (mediaTypes && mediaTypes[NATIVE]) {
placement.native = mediaTypes[NATIVE];
placement.adFormat = NATIVE;
}

return placement;
}

function getBidFloor(bid) {
if (!isFn(bid.getFloor)) {
return deepAccess(bid, 'params.bidfloor', 0);
}

try {
const bidFloor = bid.getFloor({
currency: 'USD',
mediaType: '*',
size: '*',
});
return bidFloor.floor;
} catch (err) {
logError(err);
return 0;
}
}

export const spec = {
code: BIDDER_CODE,
supportedMediaTypes: [BANNER, VIDEO, NATIVE],

isBidRequestValid: (bid = {}) => {
const { params, bidId, mediaTypes } = bid;
let valid = Boolean(bidId && params && (params.placementId || params.endpointId));

if (mediaTypes && mediaTypes[BANNER]) {
valid = valid && Boolean(mediaTypes[BANNER] && mediaTypes[BANNER].sizes);
} else if (mediaTypes && mediaTypes[VIDEO]) {
valid = valid && Boolean(mediaTypes[VIDEO] && mediaTypes[VIDEO].playerSize);
} else if (mediaTypes && mediaTypes[NATIVE]) {
valid = valid && Boolean(mediaTypes[NATIVE]);
} else {
valid = false;
}
return valid;
},

buildRequests: (validBidRequests = [], bidderRequest = {}) => {
// convert Native ORTB definition to old-style prebid native definition
validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests);

let deviceWidth = 0;
let deviceHeight = 0;

let winLocation;
try {
const winTop = window.top;
deviceWidth = winTop.screen.width;
deviceHeight = winTop.screen.height;
winLocation = winTop.location;
} catch (e) {
logMessage(e);
winLocation = window.location;
}

const refferUrl = bidderRequest.refererInfo && bidderRequest.refererInfo.page;
let refferLocation;
try {
refferLocation = refferUrl && new URL(refferUrl);
} catch (e) {
logMessage(e);
}
// TODO: does the fallback make sense here?
let location = refferLocation || winLocation;
const language = (navigator && navigator.language) ? navigator.language.split('-')[0] : '';
const host = location.host;
const page = location.pathname;
const secure = location.protocol === 'https:' ? 1 : 0;
const placements = [];
const request = {
deviceWidth,
deviceHeight,
language,
secure,
host,
page,
placements,
coppa: config.getConfig('coppa') === true ? 1 : 0,
ccpa: bidderRequest.uspConsent || undefined,
gdpr: bidderRequest.gdprConsent || undefined,
tmax: bidderRequest.timeout
};

const len = validBidRequests.length;
for (let i = 0; i < len; i++) {
const bid = validBidRequests[i];
placements.push(getPlacementReqData(bid));
}

return {
method: 'POST',
url: AD_URL,
data: request
};
},

interpretResponse: (serverResponse) => {
let response = [];
for (let i = 0; i < serverResponse.body.length; i++) {
let resItem = serverResponse.body[i];
if (isBidResponseValid(resItem)) {
const advertiserDomains = resItem.adomain && resItem.adomain.length ? resItem.adomain : [];
resItem.meta = { ...resItem.meta, advertiserDomains };

response.push(resItem);
}
}
return response;
}
isBidRequestValid: isBidRequestValid(),
buildRequests: buildRequests(AD_URL),
interpretResponse
};

registerBidder(spec);
134 changes: 118 additions & 16 deletions test/spec/modules/edge226BidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,19 @@ import { spec } from '../../../modules/edge226BidAdapter.js';
import { BANNER, VIDEO, NATIVE } from '../../../src/mediaTypes.js';
import { getUniqueIdentifierStr } from '../../../src/utils.js';

const bidder = 'edge226'
const bidder = 'edge226';

describe('Edge226BidAdapter', function () {
const userIdAsEids = [{
source: 'test.org',
uids: [{
id: '01**********',
atype: 1,
ext: {
third: '01***********'
}
}]
}];
const bids = [
{
bidId: getUniqueIdentifierStr(),
Expand All @@ -16,8 +26,9 @@ describe('Edge226BidAdapter', function () {
}
},
params: {
placementId: 'testBanner',
}
placementId: 'testBanner'
},
userIdAsEids
},
{
bidId: getUniqueIdentifierStr(),
Expand All @@ -30,8 +41,9 @@ describe('Edge226BidAdapter', function () {
}
},
params: {
placementId: 'testVideo',
}
placementId: 'testVideo'
},
userIdAsEids
},
{
bidId: getUniqueIdentifierStr(),
Expand All @@ -53,8 +65,9 @@ describe('Edge226BidAdapter', function () {
}
},
params: {
placementId: 'testNative',
}
placementId: 'testNative'
},
userIdAsEids
}
];

Expand All @@ -73,9 +86,20 @@ describe('Edge226BidAdapter', function () {

const bidderRequest = {
uspConsent: '1---',
gdprConsent: 'COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw',
gdprConsent: {
consentString: 'COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw',
vendorData: {}
},
refererInfo: {
referer: 'https://test.com'
referer: 'https://test.com',
page: 'https://test.com'
},
ortb2: {
device: {
w: 1512,
h: 982,
language: 'en-UK'
}
},
timeout: 500
};
Expand Down Expand Up @@ -129,7 +153,7 @@ describe('Edge226BidAdapter', function () {
expect(data.host).to.be.a('string');
expect(data.page).to.be.a('string');
expect(data.coppa).to.be.a('number');
expect(data.gdpr).to.be.a('string');
expect(data.gdpr).to.be.a('object');
expect(data.ccpa).to.be.a('string');
expect(data.tmax).to.be.a('number');
expect(data.placements).to.have.lengthOf(3);
Expand All @@ -145,6 +169,56 @@ describe('Edge226BidAdapter', function () {
expect(placement.schain).to.be.an('object');
expect(placement.bidfloor).to.exist.and.to.equal(0);
expect(placement.type).to.exist.and.to.equal('publisher');
expect(placement.eids).to.exist.and.to.be.deep.equal(userIdAsEids);

if (placement.adFormat === BANNER) {
expect(placement.sizes).to.be.an('array');
}
switch (placement.adFormat) {
case BANNER:
expect(placement.sizes).to.be.an('array');
break;
case VIDEO:
expect(placement.playerSize).to.be.an('array');
expect(placement.minduration).to.be.an('number');
expect(placement.maxduration).to.be.an('number');
break;
case NATIVE:
expect(placement.native).to.be.an('object');
break;
}
}
});

it('Returns valid endpoints', function () {
const bids = [
{
bidId: getUniqueIdentifierStr(),
bidder: bidder,
mediaTypes: {
[BANNER]: {
sizes: [[300, 250]]
}
},
params: {
endpointId: 'testBanner',
},
userIdAsEids
}
];

let serverRequest = spec.buildRequests(bids, bidderRequest);

const { placements } = serverRequest.data;
for (let i = 0, len = placements.length; i < len; i++) {
const placement = placements[i];
expect(placement.endpointId).to.be.oneOf(['testBanner', 'testVideo', 'testNative']);
expect(placement.adFormat).to.be.oneOf([BANNER, VIDEO, NATIVE]);
expect(placement.bidId).to.be.a('string');
expect(placement.schain).to.be.an('object');
expect(placement.bidfloor).to.exist.and.to.equal(0);
expect(placement.type).to.exist.and.to.equal('network');
expect(placement.eids).to.exist.and.to.be.deep.equal(userIdAsEids);

if (placement.adFormat === BANNER) {
expect(placement.sizes).to.be.an('array');
Expand All @@ -170,8 +244,10 @@ describe('Edge226BidAdapter', function () {
serverRequest = spec.buildRequests(bids, bidderRequest);
let data = serverRequest.data;
expect(data.gdpr).to.exist;
expect(data.gdpr).to.be.a('string');
expect(data.gdpr).to.equal(bidderRequest.gdprConsent);
expect(data.gdpr).to.be.a('object');
expect(data.gdpr).to.have.property('consentString');
expect(data.gdpr).to.not.have.property('vendorData');
expect(data.gdpr.consentString).to.equal(bidderRequest.gdprConsent.consentString);
expect(data.ccpa).to.not.exist;
delete bidderRequest.gdprConsent;
});
Expand All @@ -186,12 +262,38 @@ describe('Edge226BidAdapter', function () {
expect(data.ccpa).to.equal(bidderRequest.uspConsent);
expect(data.gdpr).to.not.exist;
});
});

it('Returns empty data if no valid requests are passed', function () {
serverRequest = spec.buildRequests([], bidderRequest);
describe('gpp consent', function () {
it('bidderRequest.gppConsent', () => {
bidderRequest.gppConsent = {
gppString: 'abc123',
applicableSections: [8]
};

let serverRequest = spec.buildRequests(bids, bidderRequest);
let data = serverRequest.data;
expect(data.placements).to.be.an('array').that.is.empty;
});
expect(data).to.be.an('object');
expect(data).to.have.property('gpp');
expect(data).to.have.property('gpp_sid');

delete bidderRequest.gppConsent;
})

it('bidderRequest.ortb2.regs.gpp', () => {
bidderRequest.ortb2 = bidderRequest.ortb2 || {};
bidderRequest.ortb2.regs = bidderRequest.ortb2.regs || {};
bidderRequest.ortb2.regs.gpp = 'abc123';
bidderRequest.ortb2.regs.gpp_sid = [8];

let serverRequest = spec.buildRequests(bids, bidderRequest);
let data = serverRequest.data;
expect(data).to.be.an('object');
expect(data).to.have.property('gpp');
expect(data).to.have.property('gpp_sid');

bidderRequest.ortb2;
})
});

describe('interpretResponse', function () {
Expand Down

0 comments on commit dd35fd8

Please sign in to comment.