Skip to content

Commit

Permalink
RP Analytics Adapter update for UTM KVs (#5998)
Browse files Browse the repository at this point in the history
* RP Analytics Adapter update to scan URL query params to match 'utm_' params, convert to KV object format and pass data along as fpkvs. Unique query aram KVs will be added to the fpkvs object; whereas, query params will overwrite both matching KVs defined in localstorage or setConfig

* Update to attempt to fix CircleCi errors

* Update to use utils parseQS

* Minor change to attempt to pass Safari tests

* Switching spec logic to mock parseQS function as opposed to the window.location

* Another attempt to determine Safari failure

* Reverting last change and modifying fpkvs

* Added sort to test to correctly evaluate on Safari browser and reverted back to windowLocation mock

* Update to switch logic to utilize reduce()
  • Loading branch information
mmoschovas authored Nov 30, 2020
1 parent 4b3faf4 commit a7beb57
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 0 deletions.
22 changes: 22 additions & 0 deletions modules/rubiconAnalyticsAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,29 @@ export function parseBidResponse(bid, previousBidResponse, auctionFloorData) {
]);
}

/*
Filters and converts URL Params into an object and returns only KVs that match the 'utm_KEY' format
*/
function getUtmParams() {
let search;

try {
search = utils.parseQS(utils.getWindowLocation().search);
} catch (e) {
search = {};
}

return Object.keys(search).reduce((accum, param) => {
if (param.match(/utm_/)) {
accum[param.replace(/utm_/, '')] = search[param];
}
return accum;
}, {});
}

function getFpkvs() {
rubiConf.fpkvs = Object.assign((rubiConf.fpkvs || {}), getUtmParams());

const isValid = rubiConf.fpkvs && typeof rubiConf.fpkvs === 'object' && Object.keys(rubiConf.fpkvs).every(key => typeof rubiConf.fpkvs[key] === 'string');
return isValid ? rubiConf.fpkvs : {};
}
Expand Down
87 changes: 87 additions & 0 deletions test/spec/modules/rubiconAnalyticsAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1083,6 +1083,34 @@ describe('rubicon analytics adapter', function () {
expect(message).to.deep.equal(expectedMessage);
});

it('should use the query utm param rubicon kv value and pass updated kv and pvid when defined', function () {
sandbox.stub(utils, 'getWindowLocation').returns({'search': '?utm_source=other', 'pbjs_debug': 'true'});

config.setConfig({rubicon: {
fpkvs: {
source: 'fb',
link: 'email'
}
}});
performStandardAuction();
expect(server.requests.length).to.equal(1);
let request = server.requests[0];
let message = JSON.parse(request.requestBody);
validate(message);

let expectedMessage = utils.deepClone(ANALYTICS_MESSAGE);
expectedMessage.session.pvid = STUBBED_UUID.slice(0, 8);
expectedMessage.fpkvs = [
{key: 'source', value: 'other'},
{key: 'link', value: 'email'}
]

message.fpkvs.sort((left, right) => left.key < right.key);
expectedMessage.fpkvs.sort((left, right) => left.key < right.key);

expect(message).to.deep.equal(expectedMessage);
});

it('should pick up existing localStorage and use its values', function () {
// set some localStorage
let inputlocalStorage = {
Expand Down Expand Up @@ -1135,6 +1163,65 @@ describe('rubicon analytics adapter', function () {
});
});

it('should overwrite matching localstorge value and use its remaining values', function () {
sandbox.stub(utils, 'getWindowLocation').returns({'search': '?utm_source=fb&utm_click=dog'});

// set some localStorage
let inputlocalStorage = {
id: '987654',
start: 1519766113781, // 15 mins before "now"
expires: 1519787713781, // six hours later
lastSeen: 1519766113781,
fpkvs: { source: 'tw', link: 'email' }
};
getDataFromLocalStorageStub.withArgs('rpaSession').returns(btoa(JSON.stringify(inputlocalStorage)));

config.setConfig({rubicon: {
fpkvs: {
link: 'email' // should merge this with what is in the localStorage!
}
}});
performStandardAuction();
expect(server.requests.length).to.equal(1);
let request = server.requests[0];
let message = JSON.parse(request.requestBody);
validate(message);

let expectedMessage = utils.deepClone(ANALYTICS_MESSAGE);
expectedMessage.session = {
id: '987654',
start: 1519766113781,
expires: 1519787713781,
pvid: expectedPvid
}
expectedMessage.fpkvs = [
{key: 'source', value: 'fb'},
{key: 'link', value: 'email'},
{key: 'click', value: 'dog'}
]

message.fpkvs.sort((left, right) => left.key < right.key);
expectedMessage.fpkvs.sort((left, right) => left.key < right.key);

expect(message).to.deep.equal(expectedMessage);

let calledWith;
try {
calledWith = JSON.parse(atob(setDataInLocalStorageStub.getCall(0).args[1]));
} catch (e) {
calledWith = {};
}

expect(calledWith).to.deep.equal({
id: '987654', // should have stayed same
start: 1519766113781, // should have stayed same
expires: 1519787713781, // should have stayed same
lastSeen: 1519767013781, // lastSeen updated to our "now"
fpkvs: { source: 'fb', link: 'email', click: 'dog' }, // link merged in
pvid: expectedPvid // new pvid stored
});
});

it('should throw out session if lastSeen > 30 mins ago and create new one', function () {
// set some localStorage
let inputlocalStorage = {
Expand Down

0 comments on commit a7beb57

Please sign in to comment.