Skip to content

Commit

Permalink
add user syncing for kargo (prebid#3099)
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelhorwitz authored and SublimeJeremy committed Oct 1, 2018
1 parent b2a42af commit 1043db6
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 0 deletions.
37 changes: 37 additions & 0 deletions modules/kargoBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import {config} from 'src/config';
import {registerBidder} from 'src/adapters/bidderFactory';
const BIDDER_CODE = 'kargo';
const HOST = 'https://krk.kargo.com';
const SYNC = 'https://crb.kargo.com/api/v1/initsyncrnd/{UUID}?seed={SEED}&idx={INDEX}';
const SYNC_COUNT = 5;
export const spec = {
code: BIDDER_CODE,
isBidRequestValid: function(bid) {
Expand Down Expand Up @@ -54,6 +56,20 @@ export const spec = {
}
return bidResponses;
},
getUserSyncs: function(syncOptions) {
const syncs = [];
const seed = spec._generateRandomUuid();
const clientId = spec._getClientId();
if (syncOptions.iframeEnabled && seed && clientId) {
for (let i = 0; i < SYNC_COUNT; i++) {
syncs.push({
type: 'iframe',
url: SYNC.replace('{UUID}', clientId).replace('{SEED}', seed).replace('{INDEX}', i)
});
}
}
return syncs;
},

// PRIVATE
_readCookie(name) {
Expand Down Expand Up @@ -150,13 +166,34 @@ export const spec = {
};
},

_getClientId() {
const uid = spec._getUid();
return uid.clientId;
},

_getAllMetadata() {
return {
userIDs: spec._getUserIds(),
krux: spec._getKrux(),
pageURL: window.location.href,
rawCRB: spec._readCookie('krg_crb')
};
},

_generateRandomUuid() {
try {
// crypto.getRandomValues is supported everywhere but Opera Mini for years
var buffer = new Uint8Array(16);
crypto.getRandomValues(buffer);
buffer[6] = (buffer[6] & ~176) | 64;
buffer[8] = (buffer[8] & ~64) | 128;
var hex = Array.prototype.map.call(new Uint8Array(buffer), function(x) {
return ('00' + x.toString(16)).slice(-2);
}).join('');
return hex.slice(0, 8) + '-' + hex.slice(8, 12) + '-' + hex.slice(12, 16) + '-' + hex.slice(16, 20) + '-' + hex.slice(20);
} catch (e) {
return '';
}
}
};
registerBidder(spec);
93 changes: 93 additions & 0 deletions test/spec/modules/kargoBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -387,4 +387,97 @@ describe('kargo adapter tests', function () {
expect(resp).to.deep.equal(expectation);
});
});

describe('user sync handler', function() {
const clientId = '74c81cbb-7d07-46d9-be9b-68ccb291c949';
var shouldSimulateOutdatedBrowser, uid, isActuallyOutdatedBrowser;

beforeEach(() => {
uid = {};
shouldSimulateOutdatedBrowser = false;
isActuallyOutdatedBrowser = false;

// IE11 fails these tests in the Prebid test suite. Since this
// browser won't support any of this stuff we expect all user
// syncing to fail gracefully. Kargo is mobile only, so this
// doesn't really matter.
if (!window.crypto) {
isActuallyOutdatedBrowser = true;
} else {
sandbox.stub(crypto, 'getRandomValues').callsFake(function(buf) {
if (shouldSimulateOutdatedBrowser) {
throw new Error('Could not generate random values');
}
var bytes = [50, 5, 232, 133, 141, 55, 49, 57, 244, 126, 248, 44, 255, 38, 128, 0];
for (var i = 0; i < bytes.length; i++) {
buf[i] = bytes[i];
}
return buf;
});
}

sandbox.stub(spec, '_getUid').callsFake(function() {
return uid;
});
});

function getUserSyncsWhenAllowed() {
return spec.getUserSyncs({iframeEnabled: true});
}

function getUserSyncsWhenForbidden() {
return spec.getUserSyncs({});
}

function turnOnClientId() {
uid.clientId = clientId;
}

function simulateOutdatedBrowser() {
shouldSimulateOutdatedBrowser = true;
}

function getSyncUrl(index) {
return {
type: 'iframe',
url: `https://crb.kargo.com/api/v1/initsyncrnd/${clientId}?seed=3205e885-8d37-4139-b47e-f82cff268000&idx=${index}`
};
}

function getSyncUrls() {
var syncs = [];
for (var i = 0; i < 5; i++) {
syncs[i] = getSyncUrl(i);
}
return syncs;
}

function safelyRun(runExpectation) {
if (isActuallyOutdatedBrowser) {
expect(getUserSyncsWhenAllowed()).to.be.an('array').that.is.empty;
} else {
runExpectation();
}
}

it('handles user syncs when there is a client id', function() {
turnOnClientId();
safelyRun(() => expect(getUserSyncsWhenAllowed()).to.deep.equal(getSyncUrls()));
});

it('no user syncs when there is no client id', function() {
safelyRun(() => expect(getUserSyncsWhenAllowed()).to.be.an('array').that.is.empty);
});

it('no user syncs when there is outdated browser', function() {
turnOnClientId();
simulateOutdatedBrowser();
safelyRun(() => expect(getUserSyncsWhenAllowed()).to.be.an('array').that.is.empty);
});

it('no user syncs when no iframe syncing allowed', function() {
turnOnClientId();
safelyRun(() => expect(getUserSyncsWhenForbidden()).to.be.an('array').that.is.empty);
});
});
});

0 comments on commit 1043db6

Please sign in to comment.