Skip to content

Commit

Permalink
moving schain validation logic inside PM adapter
Browse files Browse the repository at this point in the history
  • Loading branch information
pm-harshad-mane committed Aug 27, 2019
1 parent 4c218f3 commit 31d00d5
Show file tree
Hide file tree
Showing 2 changed files with 233 additions and 31 deletions.
122 changes: 113 additions & 9 deletions modules/pubmaticBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,118 @@ function _handleEids(payload, validBidRequests) {
}
}

function _isSchainObjectValid(schainObject) {
const schainErrorPrefix = 'Invalid schain object found: ';
const shouldBeAString = ' should be a string';
const shouldBeAnInteger = ' should be an Integer';
const shouldBeAnObject = ' should be an object';
const shouldBeAnArray = ' should be an Array';

if (!utils.isPlainObject(schainObject)) {
utils.logError(schainErrorPrefix + `schain` + shouldBeAnObject);
return false;
}

// complete: Integer
if (!utils.isNumber(schainObject.complete) || !utils.isInteger(schainObject.complete)) {
utils.logError(schainErrorPrefix + `schain.complete` + shouldBeAnInteger);
return false;
}

// ver: String
if (!utils.isStr(schainObject.ver)) {
utils.logError(schainErrorPrefix + `schain.ver` + shouldBeAString);
return false;
}

// ext: Object [optional]
if (utils.hasOwn(schainObject, 'ext')) {
if (!utils.isPlainObject(schainObject.ext)) {
utils.logError(schainErrorPrefix + `schain.ext` + shouldBeAnObject);
return false;
}
}

// nodes: Array of objects
if (!utils.isArray(schainObject.nodes)) {
utils.logError(schainErrorPrefix + `schain.nodes` + shouldBeAnArray);
return false;
}

// now validate each node
let isEachNodeIsValid = true;
schainObject.nodes.forEach(node => {
// asi: String
if (!utils.isStr(node.asi)) {
isEachNodeIsValid = isEachNodeIsValid && false;
utils.logError(schainErrorPrefix + `schain.nodes[].asi` + shouldBeAString);
}

// sid: String
if (!utils.isStr(node.sid)) {
isEachNodeIsValid = isEachNodeIsValid && false;
utils.logError(schainErrorPrefix + `schain.nodes[].sid` + shouldBeAString);
}

// hp: Integer
if (!utils.isNumber(node.hp) || !utils.isInteger(node.hp)) {
isEachNodeIsValid = isEachNodeIsValid && false;
utils.logError(schainErrorPrefix + `schain.nodes[].hp` + shouldBeAnInteger);
}

// rid: String [Optional]
if (utils.hasOwn(node, 'rid')) {
if (!utils.isStr(node.rid)) {
isEachNodeIsValid = isEachNodeIsValid && false;
utils.logError(schainErrorPrefix + `schain.nodes[].rid` + shouldBeAString);
}
}

// name: String [Optional]
if (utils.hasOwn(node, 'name')) {
if (!utils.isStr(node.name)) {
isEachNodeIsValid = isEachNodeIsValid && false;
utils.logError(schainErrorPrefix + `schain.nodes[].name` + shouldBeAString);
}
}

// domain: String [Optional]
if (utils.hasOwn(node, 'domain')) {
if (!isStr(node.domain)) {
isEachNodeIsValid = isEachNodeIsValid && false;
utils.logError(schainErrorPrefix + `schain.nodes[].domain` + shouldBeAString);
}
}

// ext: Object [Optional]
if (utils.hasOwn(node, 'ext')) {
if (!utils.isPlainObject(node.ext)) {
isEachNodeIsValid = isEachNodeIsValid && false;
logError(schainErrorPrefix + `schain.nodes[].ext` + shouldBeAnObject);
}
}
});

if (!isEachNodeIsValid) {
return false;
}

return true;
}

function _addSchainObjet(payload) {
let schainConfig = config.getConfig('schain');
if (schainConfig && _isSchainObjectValid(schainConfig)) {
if (!payload.source) {
payload.source = {};
}
if (!payload.source.ext) {
payload.source.ext = {};
}
payload.source.ext.schain = schainConfig;
}
}

function _checkMediaType(adm, newBid) {
// Create a regex here to check the strings
var admStr = '';
Expand Down Expand Up @@ -873,15 +985,6 @@ export const spec = {
payload.site.page = conf.kadpageurl.trim() || payload.site.page.trim();
payload.site.domain = _getDomainFromURL(payload.site.page);

// adding schain object
if (validBidRequests[0].schain) {
payload.source = {
ext: {
schain: validBidRequests[0].schain
}
};
}

// Attaching GDPR Consent Params
if (bidderRequest && bidderRequest.gdprConsent) {
payload.user.ext = {
Expand All @@ -895,6 +998,7 @@ export const spec = {
};
}

_addSchainObjet(payload);
_handleDealCustomTargetings(payload, dctrArr, validBidRequests);
_handleEids(payload, validBidRequests);
_blockedIabCategoriesValidation(payload, blockedIabCategories);
Expand Down
142 changes: 120 additions & 22 deletions test/spec/modules/pubmaticBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,27 +24,8 @@ describe('PubMatic adapter', function () {
let bannerVideoAndNativeBidRequests;
let bannerBidResponse;
let videoBidResponse;
let schainConfig;

beforeEach(function () {
schainConfig = {
'ver': '1.0',
'complete': 1,
'nodes': [
{
'asi': 'indirectseller.com',
'sid': '00001',
'hp': 1
},

{
'asi': 'indirectseller-2.com',
'sid': '00002',
'hp': 2
}
]
};

bidRequests = [
{
bidder: 'pubmatic',
Expand Down Expand Up @@ -74,8 +55,7 @@ describe('PubMatic adapter', function () {
bidId: '23acc48ad47af5',
requestId: '0fb4905b-9456-4152-86be-c6f6d259ba99',
bidderRequestId: '1c56ad30b9b8ca8',
transactionId: '92489f71-1bf2-49a0-adf9-000cea934729',
schain: schainConfig
transactionId: '92489f71-1bf2-49a0-adf9-000cea934729'
}
];

Expand Down Expand Up @@ -748,7 +728,6 @@ describe('PubMatic adapter', function () {
expect(data.imp[0].banner.h).to.equal(250); // height
expect(data.imp[0].ext.pmZoneId).to.equal(bidRequests[0].params.pmzoneid.split(',').slice(0, 50).map(id => id.trim()).join()); // pmzoneid
expect(data.imp[0].bidfloorcur).to.equal(bidRequests[0].params.currency);
expect(data.source.ext.schain).to.deep.equal(bidRequests[0].schain);
});

it('Request params check: without adSlot', function () {
Expand Down Expand Up @@ -1476,6 +1455,125 @@ describe('PubMatic adapter', function () {
});
});

describe('schain from config', function() {
let schainConfig;
let sandbox;

beforeEach(function() {
sandbox = sinon.sandbox.create();

schainConfig = {
'ver': '1.0',
'complete': 1,
'nodes': [
{
'asi': 'indirectseller.com',
'sid': '00001',
'hp': 1
},

{
'asi': 'indirectseller-2.com',
'sid': '00002',
'hp': 2
}
]
};
});

afterEach(() => {
sandbox.restore();
delete window.DigiTrust;
});

it('if schain is not defined then schain should not be passed in request', function() {
sandbox.stub(config, 'getConfig').callsFake((key) => {
var config = {};
return config[key];
});
let request = spec.buildRequests(bidRequests, {});
let data = JSON.parse(request.data);
expect(data.source).to.deep.equal(undefined);
});

it('if schain is a string then schain should not be passed in request', function() {
schainConfig = JSON.stringify(schainConfig);
sandbox.stub(config, 'getConfig').callsFake((key) => {
var config = {
schain: schainConfig
};
return config[key];
});
let request = spec.buildRequests(bidRequests, {});
let data = JSON.parse(request.data);
expect(data.source).to.deep.equal(undefined);
});

it('if schain.complete is NOT Integer then schain should not be passed in request', function() {
sandbox.stub(config, 'getConfig').callsFake((key) => {
var config = {
schain: schainConfig
};
return config[key];
});
let request, data;

schainConfig.complete = 1; // integer
request = spec.buildRequests(bidRequests, {});
data = JSON.parse(request.data);
expect(data.source.ext.schain).to.deep.equal(schainConfig);

schainConfig.complete = '1'; // string
request = spec.buildRequests(bidRequests, {});
data = JSON.parse(request.data);
expect(data.source).to.deep.equal(undefined);

schainConfig.complete = 1.1; // float
request = spec.buildRequests(bidRequests, {});
data = JSON.parse(request.data);
expect(data.source).to.deep.equal(undefined);

schainConfig.complete = {}; // object
request = spec.buildRequests(bidRequests, {});
data = JSON.parse(request.data);
expect(data.source).to.deep.equal(undefined);

delete schainConfig.complete; // undefined
request = spec.buildRequests(bidRequests, {});
data = JSON.parse(request.data);
expect(data.source).to.deep.equal(undefined);

schainConfig.complete = true; // boolean
request = spec.buildRequests(bidRequests, {});
data = JSON.parse(request.data);
expect(data.source).to.deep.equal(undefined);

schainConfig.complete = []; // array
request = spec.buildRequests(bidRequests, {});
data = JSON.parse(request.data);
expect(data.source).to.deep.equal(undefined);
});

it('if schain.version is NOT String then schain should not be passed in request', function() {
schainConfig.ver = 1; // Integer
request = spec.buildRequests(bidRequests, {});
data = JSON.parse(request.data);
expect(data.source).to.deep.equal(undefined);

schainConfig.ver = 1.1; // float
expect(isSchainObjectValid(schainConfig)).to.false;
schainConfig.ver = {}; // object
expect(isSchainObjectValid(schainConfig)).to.false;
delete schainConfig.ver; // undefined
expect(isSchainObjectValid(schainConfig)).to.false;
schainConfig.ver = true; // boolean
expect(isSchainObjectValid(schainConfig)).to.false;
schainConfig.ver = []; // array
expect(isSchainObjectValid(schainConfig)).to.false;
});

});

it('Request params check for video ad', function () {
let request = spec.buildRequests(videoBidRequests);
let data = JSON.parse(request.data);
Expand Down

0 comments on commit 31d00d5

Please sign in to comment.