Skip to content

Commit

Permalink
mantis privacy support, removed unsupported media types (prebid#5494)
Browse files Browse the repository at this point in the history
* mantis privacy support, removed unsupported media types

* code coverage

* lint fix
  • Loading branch information
parisholley authored Jul 20, 2020
1 parent 2f861c9 commit 884e7fc
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 49 deletions.
97 changes: 48 additions & 49 deletions modules/mantisBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,7 @@ function pixel(url, parent) {
img.style.cssText = 'display:none !important;';
(parent || document.body).appendChild(img);
}
function isDesktop(ignoreTouch) {
var supportsTouch = !ignoreTouch && ('ontouchstart' in window || navigator.msMaxTouchPoints);
if (inIframe()) {
return !supportsTouch;
}
var width = window.innerWidth || window.document.documentElement.clientWidth || window.document.body.clientWidth;
return !supportsTouch && (!width || width >= (window.mantis_breakpoint || 768));
}
function onVisible(element, doOnVisible, time, pct) {
export function onVisible(win, element, doOnVisible, time, pct) {
var started = null;
var notified = false;
var onNotVisible = null;
Expand Down Expand Up @@ -78,15 +70,15 @@ function onVisible(element, doOnVisible, time, pct) {
});
};
if (isAmp()) {
listener = window.context.observeIntersection(function (changes) {
listener = win.context.observeIntersection(function (changes) {
changes.forEach(function (change) {
doCheck(change.rootBounds.width, change.rootBounds.height, change.boundingClientRect);
});
});
}
interval = setInterval(function () {
var winHeight = (window.innerHeight || document.documentElement.clientHeight);
var winWidth = (window.innerWidth || document.documentElement.clientWidth);
var winHeight = (win.innerHeight || document.documentElement.clientHeight);
var winWidth = (win.innerWidth || document.documentElement.clientWidth);
doCheck(winWidth, winHeight, element.getBoundingClientRect());
}, 100);
}
Expand Down Expand Up @@ -136,9 +128,6 @@ function isArray(value) {
}

function jsonToQuery(data, chain, form) {
if (!data) {
return null;
}
var parts = form || [];
for (var key in data) {
var queryKey = key;
Expand All @@ -152,8 +141,6 @@ function jsonToQuery(data, chain, form) {
var aval = val[index];
if (isObject(aval)) {
jsonToQuery(aval, akey, parts);
} else if (isSendable(aval)) {
parts.push(akey + '=' + encodeURIComponent(aval));
}
}
} else if (isObject(val) && val != data) {
Expand All @@ -173,9 +160,7 @@ function buildMantisUrl(path, data, domain) {
secure: isSecure(),
version: 9
};
if (!inIframe() || isAmp()) {
params.mobile = !isAmp() && isDesktop(true) ? 'false' : 'true';
}

if (window.mantis_uuid) {
params.uuid = window.mantis_uuid;
} else if (storage.hasLocalStorage()) {
Expand Down Expand Up @@ -206,20 +191,20 @@ function buildMantisUrl(path, data, domain) {
params.referrer = window.context.referrer;
}
}
Object.keys(data || {}).forEach(function (key) {
Object.keys(data).forEach(function (key) {
params[key] = data[key];
});
var query = jsonToQuery(params);
return (window.mantis_domain === undefined ? domain || 'https://mantodea.mantisadnetwork.com' : window.mantis_domain) + path + '?' + query;
}

const spec = {
export const spec = {
code: 'mantis',
supportedMediaTypes: ['banner', 'video', 'native'],
supportedMediaTypes: ['banner'],
isBidRequestValid: function (bid) {
return !!(bid.params.property && (bid.params.code || bid.params.zoneId || bid.params.zone));
},
buildRequests: function (validBidRequests) {
buildRequests: function (validBidRequests, bidderRequest) {
var property = null;
validBidRequests.some(function (bid) {
if (bid.params.property) {
Expand All @@ -229,6 +214,7 @@ const spec = {
});
const query = {
measurable: true,
usp: bidderRequest && bidderRequest.uspConsent,
bids: validBidRequests.map(function (bid) {
return {
bidId: bid.bidId,
Expand All @@ -240,6 +226,12 @@ const spec = {
}),
property: property
};

if (bidderRequest && bidderRequest.gdprConsent && bidderRequest.gdprConsent.gdprApplies) {
// we purposefully do not track data for users in the EU
query.consent = false;
}

return {
method: 'GET',
url: buildMantisUrl('/prebid/display', query) + '&foo',
Expand All @@ -262,47 +254,54 @@ const spec = {
};
});
},
getUserSyncs: function (syncOptions) {
getUserSyncs: function (syncOptions, serverResponses, gdprConsent, uspConsent) {
if (syncOptions.iframeEnabled) {
return [{
type: 'iframe',
url: buildMantisUrl('/prebid/iframe')
url: buildMantisUrl('/prebid/iframe', {gdpr: gdprConsent, uspConsent: uspConsent})
}];
}
if (syncOptions.pixelEnabled) {
return [{
type: 'image',
url: buildMantisUrl('/prebid/pixel')
url: buildMantisUrl('/prebid/pixel', {gdpr: gdprConsent, uspConsent: uspConsent})
}];
}
}
};

export function sfPostMessage ($sf, width, height, callback) {
var viewed = false;
// eslint-disable-next-line no-undef
$sf.ext.register(width, height, function () {
// eslint-disable-next-line no-undef
if ($sf.ext.inViewPercentage() < 50 || viewed) {
return;
}
viewed = true;
callback();
});
};

export function iframePostMessage (win, name, callback) {
var frames = document.getElementsByTagName('iframe');
for (var i = 0; i < frames.length; i++) {
var frame = frames[i];
if (frame.name == name) {
onVisible(win, frame, function (stop) {
callback();
stop();
}, 1000, 0.50);
}
}
}

onMessage('iframe', function (data) {
if (window.$sf) {
var viewed = false;
// eslint-disable-next-line no-undef
$sf.ext.register(data.width, data.height, function () {
// eslint-disable-next-line no-undef
if ($sf.ext.inViewPercentage() < 50 || viewed) {
return;
}
viewed = true;
pixel(data.pixel);
});
sfPostMessage(window.$sf, data.width, data.height, () => pixel(data.pixel));
} else {
var frames = document.getElementsByTagName('iframe');
for (var i = 0; i < frames.length; i++) {
var frame = frames[i];
if (frame.name == data.frame) {
onVisible(frame, function (stop) {
pixel(data.pixel);
stop();
}, 1000, 0.50);
}
}
iframePostMessage(window, data.frame, () => pixel(data.pixel));
}
});

export { spec };

registerBidder(spec);
92 changes: 92 additions & 0 deletions test/spec/modules/mantisBidAdapter_spec.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
import {expect} from 'chai';
import {spec} from 'modules/mantisBidAdapter.js';
import {newBidder} from 'src/adapters/bidderFactory.js';
import {sfPostMessage, iframePostMessage} from 'modules/mantisBidAdapter';

describe('MantisAdapter', function () {
const adapter = newBidder(spec);
let sandbox;
let clock;

beforeEach(function() {
sandbox = sinon.sandbox.create();
clock = sandbox.useFakeTimers();
});

afterEach(function() {
sandbox.restore();
});

describe('isBidRequestValid', function () {
let bid = {
Expand Down Expand Up @@ -31,6 +43,68 @@ describe('MantisAdapter', function () {
});
});

describe('viewability', function() {
it('iframe (viewed)', () => {
let viewed = false;

sandbox.stub(document, 'getElementsByTagName').withArgs('iframe').returns([
{
name: 'mantis',
getBoundingClientRect: () => ({
top: 10,
bottom: 260,
left: 10,
right: 190,
width: 300,
height: 250
})
}
]);

iframePostMessage({innerHeight: 500, innerWidth: 500}, 'mantis', () => viewed = true);

sandbox.clock.runAll();

expect(viewed).to.equal(true);
});

it('safeframe (viewed)', () => {
let viewed = false;

sfPostMessage({
ext: {
register: (width, height, callback) => {
expect(width).to.equal(100);
expect(height).to.equal(200);

callback();
},
inViewPercentage: () => 60
}
}, 100, 200, () => viewed = true);

expect(viewed).to.equal(true);
});

it('safeframe (unviewed)', () => {
let viewed = false;

sfPostMessage({
ext: {
register: (width, height, callback) => {
expect(width).to.equal(100);
expect(height).to.equal(200);

callback();
},
inViewPercentage: () => 30
}
}, 100, 200, () => viewed = true);

expect(viewed).to.equal(false);
});
});

describe('buildRequests', function () {
let bidRequests = [
{
Expand All @@ -47,6 +121,24 @@ describe('MantisAdapter', function () {
}
];

it('gdpr consent not required', function () {
const request = spec.buildRequests(bidRequests, {gdprConsent: {gdprApplies: false}});

expect(request.url).not.to.include('consent=false');
});

it('gdpr consent required', function () {
const request = spec.buildRequests(bidRequests, {gdprConsent: {gdprApplies: true}});

expect(request.url).to.include('consent=false');
});

it('usp consent', function () {
const request = spec.buildRequests(bidRequests, {uspConsent: 'foobar'});

expect(request.url).to.include('usp=foobar');
});

it('domain override', function () {
window.mantis_domain = 'https://foo';
const request = spec.buildRequests(bidRequests);
Expand Down

0 comments on commit 884e7fc

Please sign in to comment.