Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 17 additions & 13 deletions modules/33acrossBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ function _getAdSlotHTMLElement(adUnitCode) {

// Infer the necessary data from valid bid for a minimal ttxRequest and create HTTP request
// NOTE: At this point, TTX only accepts request for a single impression
function _createServerRequest(bidRequest, gdprConsent) {
function _createServerRequest(bidRequest, gdprConsent = {}) {
const ttxRequest = {};
const params = bidRequest.params;
const element = _getAdSlotHTMLElement(bidRequest.adUnitCode);
Expand Down Expand Up @@ -143,14 +143,22 @@ function _createServerRequest(bidRequest, gdprConsent) {
}

// Sync object will always be of type iframe for TTX
function _createSync(siteId) {
function _createSync({siteId, gdprConsent = {}}) {
const ttxSettings = config.getConfig('ttxSettings');
const syncUrl = (ttxSettings && ttxSettings.syncUrl) || SYNC_ENDPOINT;

return {
const {consentString, gdprApplies} = gdprConsent;

const sync = {
type: 'iframe',
url: `${syncUrl}&id=${siteId}`
url: `${syncUrl}&id=${siteId}&gdpr_consent=${encodeURIComponent(consentString)}`
};

if (typeof gdprApplies === 'boolean') {
sync.url += `&gdpr=${Number(gdprApplies)}`;
}

return sync;
}

function _getSize(size) {
Expand Down Expand Up @@ -282,8 +290,6 @@ function isBidRequestValid(bid) {

// NOTE: With regards to gdrp consent data,
// - the server independently infers gdpr applicability therefore, setting the default value to false
// - the server, at this point, also doesn't need the consent string to handle gdpr compliance. So passing
// value whether set or not, for the sake of future dev.
function buildRequests(bidRequests, bidderRequest) {
const gdprConsent = Object.assign({
consentString: undefined,
Expand All @@ -307,14 +313,12 @@ function interpretResponse(serverResponse, bidRequest) {
return bidResponses;
}

// Register one sync per unique guid
// NOTE: If gdpr applies do not sync
// Register one sync per unique guid so long as iframe is enable
// Else no syncs
// For logic on how we handle gdpr data see _createSyncs and module's unit tests
// '33acrossBidAdapter#getUserSyncs'
function getUserSyncs(syncOptions, responses, gdprConsent) {
if (gdprConsent && gdprConsent.gdprApplies === true) {
return []
} else {
return (syncOptions.iframeEnabled) ? adapterState.uniqueSiteIds.map(_createSync) : ([]);
}
return (syncOptions.iframeEnabled) ? adapterState.uniqueSiteIds.map((siteId) => _createSync({gdprConsent, siteId})) : ([]);
}

export const spec = {
Expand Down
147 changes: 107 additions & 40 deletions test/spec/modules/33acrossBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -618,73 +618,140 @@ describe('33acrossBidAdapter:', function () {
];
});

context('when gdpr does not apply', function() {
let gdprConsent;
context('when iframe is not enabled', function() {
it('returns empty sync array', function() {
const syncOptions = {};

spec.buildRequests(bidRequests);

expect(spec.getUserSyncs(syncOptions)).to.deep.equal([]);
});
});

context('when iframe is enabled', function() {
let syncOptions;
beforeEach(function() {
gdprConsent = {
gdprApplies: false
syncOptions = {
iframeEnabled: true
};
});

context('when iframe is not enabled', function() {
it('returns empty sync array', function() {
const syncOptions = {};
context('when there is no gdpr consent data', function() {
it('returns sync urls with undefined consent string as param', function() {
spec.buildRequests(bidRequests);

const syncResults = spec.getUserSyncs(syncOptions, {}, undefined);
const expectedSyncs = [
{
type: 'iframe',
url: `${syncs[0].url}&gdpr_consent=undefined`
},
{
type: 'iframe',
url: `${syncs[1].url}&gdpr_consent=undefined`
}
]

expect(syncResults).to.deep.equal(expectedSyncs);
})
});

context('when gdpr applies but there is no consent string', function() {
it('returns sync urls with undefined consent string as param and gdpr=1', function() {
spec.buildRequests(bidRequests);

expect(spec.getUserSyncs(syncOptions, {}, gdprConsent)).to.deep.equal([]);
const syncResults = spec.getUserSyncs(syncOptions, {}, {gdprApplies: true});
const expectedSyncs = [
{
type: 'iframe',
url: `${syncs[0].url}&gdpr_consent=undefined&gdpr=1`
},
{
type: 'iframe',
url: `${syncs[1].url}&gdpr_consent=undefined&gdpr=1`
}
];

expect(syncResults).to.deep.equal(expectedSyncs);
});
});

context('when iframe is enabled', function() {
it('returns sync array equal to number of unique siteIDs', function() {
const syncOptions = {
iframeEnabled: true
};

context('when gdpr applies and there is consent string', function() {
it('returns sync urls with gdpr_consent=consent string as param and gdpr=1', function() {
spec.buildRequests(bidRequests);

expect(spec.getUserSyncs(syncOptions, {}, gdprConsent)).to.deep.equal(syncs);
const syncResults = spec.getUserSyncs(syncOptions, {}, {gdprApplies: true, consentString: 'consent123A'});
const expectedSyncs = [
{
type: 'iframe',
url: `${syncs[0].url}&gdpr_consent=consent123A&gdpr=1`
},
{
type: 'iframe',
url: `${syncs[1].url}&gdpr_consent=consent123A&gdpr=1`
}
];

expect(syncResults).to.deep.equal(expectedSyncs);
});
});
});

context('when consent data is not defined', function() {
context('when iframe is not enabled', function() {
it('returns empty sync array', function() {
const syncOptions = {};

context('when gdpr does not apply and there is no consent string', function() {
it('returns sync urls with undefined consent string as param and gdpr=0', function() {
spec.buildRequests(bidRequests);

expect(spec.getUserSyncs(syncOptions)).to.deep.equal([]);
const syncResults = spec.getUserSyncs(syncOptions, {}, {gdprApplies: false});
const expectedSyncs = [
{
type: 'iframe',
url: `${syncs[0].url}&gdpr_consent=undefined&gdpr=0`
},
{
type: 'iframe',
url: `${syncs[1].url}&gdpr_consent=undefined&gdpr=0`
}
];
expect(syncResults).to.deep.equal(expectedSyncs);
});
});

context('when iframe is enabled', function() {
it('returns sync array equal to number of unique siteIDs', function() {
const syncOptions = {
iframeEnabled: true
};

context('when gdpr is unknown and there is consent string', function() {
it('returns sync urls with only consent string as param', function() {
spec.buildRequests(bidRequests);

expect(spec.getUserSyncs(syncOptions)).to.deep.equal(syncs);
const syncResults = spec.getUserSyncs(syncOptions, {}, {consentString: 'consent123A'});
const expectedSyncs = [
{
type: 'iframe',
url: `${syncs[0].url}&gdpr_consent=consent123A`
},
{
type: 'iframe',
url: `${syncs[1].url}&gdpr_consent=consent123A`
}
];
expect(syncResults).to.deep.equal(expectedSyncs);
});
});
});

context('when gdpr applies', function() {
it('returns empty sync array', function() {
const syncOptions = {};
const gdprConsent = {
gdprApplies: true
};

spec.buildRequests(bidRequests);
context('when gdpr does not apply and there is consent string (yikes!)', function() {
it('returns sync urls with consent string as param and gdpr=0', function() {
spec.buildRequests(bidRequests);

expect(spec.getUserSyncs(syncOptions, {}, gdprConsent)).to.deep.equal([]);
const syncResults = spec.getUserSyncs(syncOptions, {}, {gdprApplies: false, consentString: 'consent123A'});
const expectedSyncs = [
{
type: 'iframe',
url: `${syncs[0].url}&gdpr_consent=consent123A&gdpr=0`
},
{
type: 'iframe',
url: `${syncs[1].url}&gdpr_consent=consent123A&gdpr=0`
}
];
expect(syncResults).to.deep.equal(expectedSyncs);
});
});
})
});
});
});