Skip to content

Commit

Permalink
Enhance location detection within utils (prebid#2167)
Browse files Browse the repository at this point in the history
* fix sovrn dealid

* send 'iv' param if present

* `page` field in `site` object sends full url

* Enhance location detection within util function.

* fix func call

* fix tagid var type

* add test for converting tagid to string

* CR

* Reorg gettopwindowlocation util & add tests.

* lint fixes

* search param is string in window location objects
  • Loading branch information
rachelrj authored and dluxemburg committed Jul 17, 2018
1 parent dc2a469 commit 2d0dbdb
Show file tree
Hide file tree
Showing 6 changed files with 173 additions and 14 deletions.
7 changes: 4 additions & 3 deletions modules/sovrnBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,24 @@ export const spec = {
* @return object of parameters for Prebid AJAX request
*/
buildRequests: function(bidReqs) {
const loc = utils.getTopWindowLocation();
let sovrnImps = [];
let iv;
utils._each(bidReqs, function (bid) {
iv = iv || utils.getBidIdParameter('iv', bid.params);
sovrnImps.push({
id: bid.bidId,
banner: { w: 1, h: 1 },
tagid: utils.getBidIdParameter('tagid', bid.params),
tagid: String(utils.getBidIdParameter('tagid', bid.params)),
bidfloor: utils.getBidIdParameter('bidfloor', bid.params)
});
});
const sovrnBidReq = {
id: utils.getUniqueIdentifierStr(),
imp: sovrnImps,
site: {
domain: window.location.host,
page: window.location.host + window.location.pathname + location.search + location.hash
domain: loc.host,
page: loc.host + loc.pathname + loc.search + loc.hash
}
};
if (iv) sovrnBidReq.iv = iv;
Expand Down
5 changes: 4 additions & 1 deletion src/url.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,15 @@ export function parse(url, options) {
} else {
parsed.href = decodeURIComponent(url);
}
// in window.location 'search' is string, not object
let qsAsString = (options && 'decodeSearchAsString' in options && options.decodeSearchAsString);
return {
href: parsed.href,
protocol: (parsed.protocol || '').replace(/:$/, ''),
hostname: parsed.hostname,
port: +parsed.port,
pathname: parsed.pathname.replace(/^(?!\/)/, '/'),
search: parseQS(parsed.search || ''),
search: (qsAsString) ? parsed.search : parseQS(parsed.search || ''),
hash: (parsed.hash || '').replace(/^#/, ''),
host: parsed.host || window.location.host
};
Expand Down
53 changes: 46 additions & 7 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { config } from './config';
import clone from 'just-clone';
import find from 'core-js/library/fn/array/find';
import includes from 'core-js/library/fn/array/includes';
import { parse } from './url';
const CONSTANTS = require('./constants');

var _loggingChecked = false;
Expand Down Expand Up @@ -157,17 +158,55 @@ export function parseGPTSingleSizeArray(singleSize) {
}
};

exports.getTopWindowLocation = function () {
let location;
exports.getTopWindowLocation = function() {
if (exports.inIframe()) {
let loc;
try {
loc = exports.getAncestorOrigins() || exports.getTopFrameReferrer();
} catch (e) {
logInfo('could not obtain top window location', e);
}
if (loc) return parse(loc, {'decodeSearchAsString': true});
}
return exports.getWindowLocation();
}

exports.getTopFrameReferrer = function () {
try {
// force an exception in x-domain enviornments. #1509
// force an exception in x-domain environments. #1509
window.top.location.toString();
location = window.top.location;
let referrerLoc = '';
let currentWindow;
do {
currentWindow = currentWindow ? currentWindow.parent : window;
if (currentWindow.document && currentWindow.document.referrer) {
referrerLoc = currentWindow.document.referrer;
}
}
while (currentWindow !== window.top);
return referrerLoc;
} catch (e) {
location = window.location;
return window.document.referrer;
}
};

exports.getAncestorOrigins = function () {
if (window.document.location && window.document.location.ancestorOrigins &&
window.document.location.ancestorOrigins.length >= 1) {
return window.document.location.ancestorOrigins[window.document.location.ancestorOrigins.length - 1];
}
};

exports.getWindowTop = function () {
return window.top;
};

exports.getWindowSelf = function () {
return window.self;
};

return location;
exports.getWindowLocation = function () {
return window.location;
};

exports.getTopWindowUrl = function () {
Expand Down Expand Up @@ -658,7 +697,7 @@ export function deepClone(obj) {

export function inIframe() {
try {
return window.self !== window.top;
return exports.getWindowSelf() !== exports.getWindowTop();
} catch (e) {
return true;
}
Expand Down
20 changes: 20 additions & 0 deletions test/spec/modules/sovrnBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,26 @@ describe('sovrnBidAdapter', function() {

expect(request.data).to.contain('"iv":"vet"')
})

it('converts tagid to string', () => {
const ivBidRequests = [{
'bidder': 'sovrn',
'params': {
'tagid': 403370,
'iv': 'vet'
},
'adUnitCode': 'adunit-code',
'sizes': [
[300, 250]
],
'bidId': '30b31c1838de1e',
'bidderRequestId': '22edbae2733bf6',
'auctionId': '1d1a030790a475'
}];
const request = spec.buildRequests(ivBidRequests);

expect(request.data).to.contain('"tagid":"403370"')
})
});

describe('interpretResponse', () => {
Expand Down
13 changes: 13 additions & 0 deletions test/spec/url_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,17 @@ describe('helpers.url', () => {
})).to.equal('http://example.com');
});
});

describe('parse(url, {decodeSearchAsString: true})', () => {
let parsed;

beforeEach(() => {
parsed = parse('http://example.com:3000/pathname/?search=test&foo=bar&bar=foo%26foo%3Dxxx#hash', {decodeSearchAsString: true});
});

it('extracts the search query', () => {
expect(parsed).to.have.property('search');
expect(parsed.search).to.equal('?search=test&foo=bar&bar=foo&foo=xxx');
});
});
});
89 changes: 86 additions & 3 deletions test/spec/utils_spec.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { getSlotTargeting, getAdServerTargeting } from 'test/fixtures/fixtures';
import { cookiesAreEnabled } from '../../src/utils';
import { getAdServerTargeting } from 'test/fixtures/fixtures';

var assert = require('assert');
var utils = require('../../src/utils');
var utils = require('src/utils');

describe('Utils', function () {
var obj_string = 's',
Expand Down Expand Up @@ -623,4 +622,88 @@ describe('Utils', function () {
expect(adUnitCopy[0].renderer.render).to.be.a('function');
});
});
describe('getTopWindowLocation', () => {
let sandbox;

beforeEach(() => {
sandbox = sinon.sandbox.create();
});

afterEach(() => {
sandbox.restore();
});

it('returns window.location if not in iFrame', () => {
sandbox.stub(utils, 'getWindowLocation').returns({
href: 'https://www.google.com/',
ancestorOrigins: {},
origin: 'https://www.google.com',
protocol: 'https',
host: 'www.google.com',
hostname: 'www.google.com',
port: '',
pathname: '/',
search: '',
hash: ''
});
let windowSelfAndTopObject = { self: 'is same as top' };
sandbox.stub(utils, 'getWindowSelf').returns(
windowSelfAndTopObject
);
sandbox.stub(utils, 'getWindowTop').returns(
windowSelfAndTopObject
);
var topWindowLocation = utils.getTopWindowLocation();
expect(topWindowLocation).to.be.a('object');
expect(topWindowLocation.href).to.equal('https://www.google.com/');
expect(topWindowLocation.protocol).to.equal('https');
expect(topWindowLocation.hostname).to.equal('www.google.com');
expect(topWindowLocation.port).to.equal('');
expect(topWindowLocation.pathname).to.equal('/');
expect(topWindowLocation.hash).to.equal('');
expect(topWindowLocation.search).to.equal('');
expect(topWindowLocation.host).to.equal('www.google.com');
});

it('returns parsed dom string from ancestorOrigins if in iFrame & ancestorOrigins is populated', () => {
sandbox.stub(utils, 'getWindowSelf').returns(
{ self: 'is not same as top' }
);
sandbox.stub(utils, 'getWindowTop').returns(
{ top: 'is not same as self' }
);
sandbox.stub(utils, 'getAncestorOrigins').returns('https://www.google.com/a/umich.edu/acs');
var topWindowLocation = utils.getTopWindowLocation();
expect(topWindowLocation).to.be.a('object');
expect(topWindowLocation.pathname).to.equal('/a/umich.edu/acs');
expect(topWindowLocation.href).to.equal('https://www.google.com/a/umich.edu/acs');
expect(topWindowLocation.protocol).to.equal('https');
expect(topWindowLocation.hostname).to.equal('www.google.com');
expect(topWindowLocation.port).to.equal(0);
expect(topWindowLocation.hash).to.equal('');
expect(topWindowLocation.search).to.equal('');
expect(topWindowLocation.host).to.equal('www.google.com');
});

it('returns parsed referrer string if in iFrame but no ancestorOrigins', () => {
sandbox.stub(utils, 'getWindowSelf').returns(
{ self: 'is not same as top' }
);
sandbox.stub(utils, 'getWindowTop').returns(
{ top: 'is not same as self' }
);
sandbox.stub(utils, 'getAncestorOrigins').returns(null);
sandbox.stub(utils, 'getTopFrameReferrer').returns('https://www.example.com/');
var topWindowLocation = utils.getTopWindowLocation();
expect(topWindowLocation).to.be.a('object');
expect(topWindowLocation.href).to.equal('https://www.example.com/');
expect(topWindowLocation.protocol).to.equal('https');
expect(topWindowLocation.hostname).to.equal('www.example.com');
expect(topWindowLocation.port).to.equal(0);
expect(topWindowLocation.pathname).to.equal('/');
expect(topWindowLocation.hash).to.equal('');
expect(topWindowLocation.search).to.equal('');
expect(topWindowLocation.host).to.equal('www.example.com');
});
});
});

0 comments on commit 2d0dbdb

Please sign in to comment.