mk9-prebid
Version:
Header Bidding Management Library
539 lines (501 loc) • 17.4 kB
JavaScript
import { expect } from 'chai';
import { spec, resetUserSync, getSyncUrl } from 'modules/gridNMBidAdapter.js';
import { newBidder } from 'src/adapters/bidderFactory.js';
describe('TheMediaGridNM Adapter', function () {
const adapter = newBidder(spec);
describe('inherited functions', function () {
it('exists and is a function', function () {
expect(adapter.callBids).to.exist.and.to.be.a('function');
});
});
describe('isBidRequestValid', function () {
let bid = {
'bidder': 'gridNM',
'params': {
'source': 'jwp',
'secid': '11',
'pubid': '22',
'video': {
'mimes': ['video/mp4', 'video/x-ms-wmv'],
'protocols': [1, 2, 3, 4, 5, 6]
}
},
'adUnitCode': 'adunit-code',
'sizes': [[300, 250], [300, 600]],
'bidId': '30b31c1838de1e',
'bidderRequestId': '22edbae2733bf6',
'auctionId': '1d1a030790a475',
};
it('should return true when required params found', function () {
expect(spec.isBidRequestValid(bid)).to.equal(true);
});
it('should return false when required params are not passed', function () {
const paramsList = [
{
'source': 'jwp',
'secid': '11',
'pubid': '22',
'video': {
'protocols': [1, 2, 3, 4, 5, 6]
}
},
{
'source': 'jwp',
'secid': '11',
'pubid': '22',
'video': {
'mimes': ['video/mp4', 'video/x-ms-wmv'],
}
},
{
'secid': '11',
'pubid': '22',
'video': {
'mimes': ['video/mp4', 'video/x-ms-wmv'],
'protocols': [1, 2, 3, 4, 5, 6]
}
},
{
'source': 'jwp',
'pubid': '22',
'video': {
'mimes': ['video/mp4', 'video/x-ms-wmv'],
'protocols': [1, 2, 3, 4, 5, 6]
}
},
{
'source': 'jwp',
'secid': '11',
'video': {
'mimes': ['video/mp4', 'video/x-ms-wmv'],
'protocols': [1, 2, 3, 4, 5, 6]
}
}
];
paramsList.forEach((params) => {
const invalidBid = Object.assign({}, bid);
delete invalidBid.params;
invalidBid.params = params;
expect(spec.isBidRequestValid(invalidBid)).to.equal(false);
});
});
it('should return false when required params has invalid values', function () {
const paramsList = [
{
'source': 'jwp',
'secid': '11',
'pubid': '22',
'video': {
'mimes': ['video/mp4', 'video/x-ms-wmv'],
'protocols': '1,2,3,4,5'
}
},
{
'source': 'jwp',
'secid': '11',
'pubid': '22',
'video': {
'mimes': [1, 2],
'protocols': [1, 2, 3, 4, 5]
}
},
{
'source': 'jwp',
'secid': 11,
'pubid': '22',
'video': {
'mimes': ['video/mp4', 'video/x-ms-wmv'],
'protocols': [1, 2, 3, 4, 5]
}
},
{
'source': 111,
'secid': '11',
'pubid': '22',
'video': {
'mimes': ['video/mp4', 'video/x-ms-wmv'],
'protocols': [1, 2, 3, 4, 5]
}
}
];
paramsList.forEach((params) => {
const invalidBid = Object.assign({}, bid);
delete invalidBid.params;
invalidBid.params = params;
expect(spec.isBidRequestValid(invalidBid)).to.equal(false);
});
});
it('should return true when required params is absent, but available in mediaTypes', function () {
const paramsList = [
{
'source': 'jwp',
'secid': '11',
'pubid': '22',
'video': {
'protocols': [1, 2, 3, 4, 5, 6]
}
},
{
'source': 'jwp',
'secid': '11',
'pubid': '22',
'video': {
'mimes': ['video/mp4', 'video/x-ms-wmv'],
}
}
];
const mediaTypes = {
video: {
mimes: ['video/mp4', 'video/x-ms-wmv'],
playerSize: [200, 300],
protocols: [1, 2, 3, 4, 5, 6]
}
};
paramsList.forEach((params) => {
const validBid = Object.assign({}, bid);
delete validBid.params;
validBid.params = params;
validBid.mediaTypes = mediaTypes;
expect(spec.isBidRequestValid(validBid)).to.equal(true);
});
});
});
describe('buildRequests', function () {
function parseRequestUrl(url) {
const res = {};
url.replace(/^[^\?]+\?/, '').split('&').forEach((it) => {
const couple = it.split('=');
res[couple[0]] = decodeURIComponent(couple[1]);
});
return res;
}
const bidderRequest = {refererInfo: {referer: 'https://example.com'}};
const referrer = bidderRequest.refererInfo.referer;
let bidRequests = [
{
'bidder': 'gridNM',
'params': {
'source': 'jwp',
'secid': '11',
'pubid': '22',
'video': {
'mimes': ['video/mp4', 'video/x-ms-wmv'],
'protocols': [1, 2, 3, 4, 5, 6]
}
},
'adUnitCode': 'adunit-code-1',
'sizes': [[300, 250], [300, 600]],
'bidId': '30b31c1838de1e',
'bidderRequestId': '22edbae2733bf6',
'auctionId': '1d1a030790a475',
},
{
'bidder': 'gridNM',
'params': {
'source': 'jwp',
'secid': '11',
'pubid': '22',
'video': {
'mimes': ['video/mp4'],
'protocols': [1, 2, 3],
'skip': 1
}
},
'adUnitCode': 'adunit-code-2',
'sizes': [[728, 90]],
'bidId': '3150ccb55da321',
'bidderRequestId': '22edbae2733bf6',
'auctionId': '1d1a030790a475',
}
];
it('should attach valid params to the tag', function () {
const requests = spec.buildRequests(bidRequests, bidderRequest);
const requestsSizes = ['300x250,300x600', '728x90'];
requests.forEach((req, i) => {
expect(req.url).to.be.an('string');
const payload = parseRequestUrl(req.url);
expect(payload).to.have.property('u', referrer);
expect(payload).to.have.property('r', '22edbae2733bf6');
expect(payload).to.have.property('wrapperType', 'Prebid_js');
expect(payload).to.have.property('wrapperVersion', '$prebid.version$');
expect(payload).to.have.property('sizes', requestsSizes[i]);
expect(req.data).to.deep.equal(bidRequests[i].params);
});
});
it('should attach valid params from mediaTypes', function () {
const mediaTypes = {
video: {
skipafter: 10,
minduration: 10,
maxduration: 100,
protocols: [1, 3, 4],
playerSize: [300, 250]
}
};
const bidRequest = Object.assign({ mediaTypes }, bidRequests[0]);
const req = spec.buildRequests([bidRequest], bidderRequest)[0];
const expectedVideo = {
'skipafter': 10,
'mind': 10,
'maxd': 100,
'mimes': ['video/mp4', 'video/x-ms-wmv'],
'protocols': [1, 2, 3, 4, 5, 6],
'size': '300x250'
};
const expectedParams = Object.assign({}, bidRequest.params);
expectedParams.video = Object.assign(expectedParams.video, expectedVideo);
expect(req.url).to.be.an('string');
const payload = parseRequestUrl(req.url);
expect(payload).to.have.property('u', referrer);
expect(payload).to.have.property('r', '22edbae2733bf6');
expect(payload).to.have.property('wrapperType', 'Prebid_js');
expect(payload).to.have.property('wrapperVersion', '$prebid.version$');
expect(payload).to.have.property('sizes', '300x250,300x600');
expect(req.data).to.deep.equal(expectedParams);
});
it('if gdprConsent is present payload must have gdpr params', function () {
const [request] = spec.buildRequests([bidRequests[0]], {gdprConsent: {consentString: 'AAA', gdprApplies: true}, refererInfo: bidderRequest.refererInfo});
expect(request.url).to.be.an('string');
const payload = parseRequestUrl(request.url);
expect(payload).to.have.property('u', referrer);
expect(payload).to.have.property('gdpr_consent', 'AAA');
expect(payload).to.have.property('gdpr_applies', '1');
});
it('if gdprApplies is false gdpr_applies must be 0', function () {
const [request] = spec.buildRequests([bidRequests[0]], {gdprConsent: {consentString: 'AAA', gdprApplies: false}});
expect(request.url).to.be.an('string');
const payload = parseRequestUrl(request.url);
expect(payload).to.have.property('gdpr_consent', 'AAA');
expect(payload).to.have.property('gdpr_applies', '0');
});
it('if gdprApplies is undefined gdpr_applies must be 1', function () {
const [request] = spec.buildRequests([bidRequests[0]], {gdprConsent: {consentString: 'AAA'}});
expect(request.url).to.be.an('string');
const payload = parseRequestUrl(request.url);
expect(payload).to.have.property('gdpr_consent', 'AAA');
expect(payload).to.have.property('gdpr_applies', '1');
});
it('if usPrivacy is present payload must have us_privacy param', function () {
const bidderRequestWithUSP = Object.assign({uspConsent: '1YNN'}, bidderRequest);
const [request] = spec.buildRequests([bidRequests[0]], bidderRequestWithUSP);
expect(request.url).to.be.an('string');
const payload = parseRequestUrl(request.url);
expect(payload).to.have.property('us_privacy', '1YNN');
});
});
describe('interpretResponse', function () {
const responses = [
{'bid': [{'price': 1.15, 'adm': '<VAST version=\"3.0\">\n<Ad id=\"21341234\"><\/Ad>\n<\/VAST>', 'content_type': 'video', 'h': 250, 'w': 300, 'dealid': 11}], 'seat': '2'},
{'bid': [{'price': 0.5, 'adm': '<VAST version=\"3.0\">\n<Ad id=\"21341235\"><\/Ad>\n<\/VAST>', 'content_type': 'video', 'h': 600, 'w': 300, adomain: ['my_domain.ru']}], 'seat': '2'},
{'bid': [{'price': 0, 'h': 250, 'w': 300}], 'seat': '2'},
{'bid': [{'price': 0, 'adm': '<VAST version=\"3.0\">\n<Ad id=\"21341237\"><\/Ad>\n<\/VAST>', 'h': 250, 'w': 300}], 'seat': '2'},
undefined,
{'bid': [], 'seat': '2'},
{'seat': '2'},
];
it('should get correct video bid response', function () {
const bidRequests = [
{
'bidder': 'gridNM',
'params': {
'source': 'jwp',
'secid': '11',
'pubid': '22',
'video': {
'mimes': ['video/mp4', 'video/x-ms-wmv'],
'protocols': [1, 2, 3, 4, 5, 6]
}
},
'adUnitCode': 'adunit-code-1',
'sizes': [[300, 250], [300, 600]],
'bidId': '659423fff799cb',
'bidderRequestId': '5f2009617a7c0a',
'auctionId': '1cbd2feafe5e8b',
'mediaTypes': {
'video': {
'context': 'instream'
}
}
},
{
'bidder': 'gridNM',
'params': {
'source': 'jwp',
'secid': '11',
'pubid': '22',
'video': {
'mimes': ['video/mp4'],
'protocols': [1, 2, 3, 4, 5],
'skip': 1
}
},
'adUnitCode': 'adunit-code-1',
'sizes': [[300, 250], [300, 600]],
'bidId': '2bc598e42b6a',
'bidderRequestId': '1e8b5a465f404',
'auctionId': '1cbd2feafe5e8b',
'mediaTypes': {
'video': {
'context': 'instream'
}
}
}
];
const requests = spec.buildRequests(bidRequests);
const expectedResponse = [
{
'requestId': '659423fff799cb',
'cpm': 1.15,
'creativeId': '5f2009617a7c0a',
'dealId': 11,
'width': 300,
'height': 250,
'currency': 'USD',
'mediaType': 'video',
'netRevenue': true,
'ttl': 360,
'vastXml': '<VAST version=\"3.0\">\n<Ad id=\"21341234\"><\/Ad>\n<\/VAST>',
'meta': {
'advertiserDomains': []
},
'adResponse': {
'content': '<VAST version=\"3.0\">\n<Ad id=\"21341234\"><\/Ad>\n<\/VAST>'
}
},
{
'requestId': '2bc598e42b6a',
'cpm': 0.5,
'creativeId': '1e8b5a465f404',
'dealId': undefined,
'width': 300,
'height': 600,
'currency': 'USD',
'mediaType': 'video',
'netRevenue': true,
'ttl': 360,
'vastXml': '<VAST version=\"3.0\">\n<Ad id=\"21341235\"><\/Ad>\n<\/VAST>',
'meta': {
'advertiserDomains': ['my_domain.ru']
},
'adResponse': {
'content': '<VAST version=\"3.0\">\n<Ad id=\"21341235\"><\/Ad>\n<\/VAST>'
}
}
];
requests.forEach((req, i) => {
const result = spec.interpretResponse({'body': {'seatbid': [responses[i]]}}, req);
expect(result[0]).to.deep.equal(expectedResponse[i]);
});
});
it('handles wrong and nobid responses', function () {
responses.slice(2).forEach((resp) => {
const request = spec.buildRequests([{
'bidder': 'gridNM',
'params': {
'source': 'jwp',
'secid': '11',
'pubid': '22',
'video': {
'mimes': ['video/mp4'],
'protocols': [1, 2, 3, 4, 5],
'skip': 1
}
},
'adUnitCode': 'adunit-code-1',
'sizes': [[300, 250], [300, 600]],
'bidId': '2bc598e42b6a',
'bidderRequestId': '39d74f5b71464',
'auctionId': '1cbd2feafe5e8b',
'meta': {
'advertiserDomains': []
},
'mediaTypes': {
'video': {
'context': 'instream'
}
}
}]);
const result = spec.interpretResponse({'body': {'seatbid': [resp]}}, request[0]);
expect(result.length).to.equal(0);
});
});
});
describe('user sync', function () {
const syncUrl = getSyncUrl();
beforeEach(function () {
resetUserSync();
});
it('should register the Emily iframe', function () {
let syncs = spec.getUserSyncs({
pixelEnabled: true
});
expect(syncs).to.deep.equal({type: 'image', url: syncUrl});
});
it('should not register the Emily iframe more than once', function () {
let syncs = spec.getUserSyncs({
pixelEnabled: true
});
expect(syncs).to.deep.equal({type: 'image', url: syncUrl});
// when called again, should still have only been called once
syncs = spec.getUserSyncs();
expect(syncs).to.equal(undefined);
});
it('should pass gdpr params if consent is true', function () {
expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {
gdprApplies: true, consentString: 'foo'
})).to.deep.equal({
type: 'image', url: `${syncUrl}&gdpr=1&gdpr_consent=foo`
});
});
it('should pass gdpr params if consent is false', function () {
expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {
gdprApplies: false, consentString: 'foo'
})).to.deep.equal({
type: 'image', url: `${syncUrl}&gdpr=0&gdpr_consent=foo`
});
});
it('should pass gdpr param gdpr_consent only when gdprApplies is undefined', function () {
expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {
consentString: 'foo'
})).to.deep.equal({
type: 'image', url: `${syncUrl}&gdpr_consent=foo`
});
});
it('should pass no params if gdpr consentString is not defined', function () {
expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {})).to.deep.equal({
type: 'image', url: syncUrl
});
});
it('should pass no params if gdpr consentString is a number', function () {
expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {
consentString: 0
})).to.deep.equal({
type: 'image', url: syncUrl
});
});
it('should pass no params if gdpr consentString is null', function () {
expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {
consentString: null
})).to.deep.equal({
type: 'image', url: syncUrl
});
});
it('should pass no params if gdpr consentString is a object', function () {
expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {
consentString: {}
})).to.deep.equal({
type: 'image', url: syncUrl
});
});
it('should pass no params if gdpr is not defined', function () {
expect(spec.getUserSyncs({ pixelEnabled: true }, {}, undefined)).to.deep.equal({
type: 'image', url: syncUrl
});
});
it('should pass usPrivacy param if it is available', function() {
expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {}, '1YNN')).to.deep.equal({
type: 'image', url: `${syncUrl}&us_privacy=1YNN`
});
});
});
});