Skip to content

Commit

Permalink
Limelight Digital Bid Adapter: Prevent duplicate iframe and pixel syn…
Browse files Browse the repository at this point in the history
…cs (#8068)

* User sync improvements

* User sync improvements

* Code review fixes

Co-authored-by: apykhteyev <[email protected]>
  • Loading branch information
apykhteyev and apykhteyev authored Feb 17, 2022
1 parent ca715fe commit 5eacb78
Show file tree
Hide file tree
Showing 3 changed files with 167 additions and 122 deletions.
35 changes: 16 additions & 19 deletions modules/limelightDigitalBidAdapter.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { logMessage, groupBy, uniques, flatten, deepAccess } from '../src/utils.js';
import { logMessage, groupBy, flatten, uniques } from '../src/utils.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { BANNER, VIDEO } from '../src/mediaTypes.js';
import {ajax} from '../src/ajax.js';
import { ajax } from '../src/ajax.js';

const BIDDER_CODE = 'limelightDigital';

Expand Down Expand Up @@ -94,23 +94,20 @@ export const spec = {
},

getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent) => {
const syncs = serverResponses.map(response => response.body).reduce(flatten, [])
.map(response => deepAccess(response, 'ext.sync')).filter(Boolean);
const iframeSyncUrls = !syncOptions.iframeEnabled ? [] : syncs.map(sync => sync.iframe).filter(Boolean)
.filter(uniques).map(url => {
return {
type: 'iframe',
url: url
}
});
const pixelSyncUrls = !syncOptions.pixelEnabled ? [] : syncs.map(sync => sync.pixel).filter(Boolean)
.filter(uniques).map(url => {
return {
type: 'image',
url: url
}
});
return [iframeSyncUrls, pixelSyncUrls].reduce(flatten, []);
const iframeSyncs = [];
const imageSyncs = [];
for (let i = 0; i < serverResponses.length; i++) {
const serverResponseHeaders = serverResponses[i].headers;
const imgSync = (serverResponseHeaders != null && syncOptions.pixelEnabled) ? serverResponseHeaders.get('X-PLL-UserSync-Image') : null
const iframeSync = (serverResponseHeaders != null && syncOptions.iframeEnabled) ? serverResponseHeaders.get('X-PLL-UserSync-Iframe') : null
if (iframeSync != null) {
iframeSyncs.push(iframeSync)
} else if (imgSync != null) {
imageSyncs.push(imgSync)
}
}
return [iframeSyncs.filter(uniques).map(it => { return { type: 'iframe', url: it } }),
imageSyncs.filter(uniques).map(it => { return { type: 'image', url: it } })].reduce(flatten, []).filter(uniques);
}
};

Expand Down
4 changes: 2 additions & 2 deletions modules/limelightDigitalBidAdapter.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ var adUnits = [{
bids: [{
bidder: 'limelightDigital',
params: {
host: 'exchange.ortb.net',
host: 'exchange-9qao.ortb.net',
adUnitId: 0,
adUnitType: 'banner'
}
Expand All @@ -38,7 +38,7 @@ var videoAdUnit = [{
bids: [{
bidder: 'limelightDigital',
params: {
host: 'exchange.ortb.net',
host: 'exchange-9qao.ortb.net',
adUnitId: 0,
adUnitType: 'video'
}
Expand Down
250 changes: 149 additions & 101 deletions test/spec/modules/limelightDigitalBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -359,155 +359,203 @@ describe('limelightDigitalAdapter', function () {
});
});
describe('getUserSyncs', function () {
const serverResponses = [
{
body: [
{
ext: {
sync: {
iframe: 'iframeUrl',
}
}
},
{
ext: {
sync: {
pixel: 'pixelUrl'
}
}
},
{},
{
ext: {}
},
{
ext: {
sync: {}
}
},
{
ext: {
sync: {
iframe: 'iframeUrl2',
pixel: 'pixelUrl3'
it('should return trackers for lm(only iframe) if server responses contain lm user sync header and iframe and image enabled', function () {
const serverResponses = [
{
headers: {
get: function (header) {
if (header === 'X-PLL-UserSync-Image') {
return 'https://tracker-lm.ortb.net/sync';
}
}
}
]
},
{
body: [
{
ext: {
sync: {
iframe: 'iframeUrl2',
pixel: 'pixelUrl2'
if (header === 'X-PLL-UserSync-Iframe') {
return 'https://tracker-lm.ortb.net/sync.html';
}
}
},
{
ext: {
sync: {
iframe: 'iframeUrl3',
pixel: 'pixelUrl3'
}
}
}
]
}
];
it('should return empty array if server responses do not contain sync urls', function () {
body: []
}
];
const syncOptions = {
iframeEnabled: true,
pixelEnabled: true
};
const serverResponsesWithoutSyncUrls = serverResponses.map(serverResponse => {
const serverResponseWithoutSyncUrls = Object.assign({}, serverResponse);
serverResponseWithoutSyncUrls.body = serverResponse.body.map(serverResponseBody => {
const serverResponseBodyWithoutSyncUrls = Object.assign({}, serverResponseBody);
delete serverResponseBodyWithoutSyncUrls.ext;
return serverResponseBodyWithoutSyncUrls;
});
return serverResponseWithoutSyncUrls;
});
expect(spec.getUserSyncs(syncOptions, serverResponsesWithoutSyncUrls)).to.be.an('array').that.is.empty;
expect(spec.getUserSyncs(syncOptions, serverResponses)).to.deep.equal([
{
type: 'iframe',
url: 'https://tracker-lm.ortb.net/sync.html'
}
]);
});
it('should return empty array if all sync types are disabled', function () {
const serverResponses = [
{
headers: {
get: function (header) {
if (header === 'X-PLL-UserSync-Image') {
return 'https://tracker-1.ortb.net/sync';
}
if (header === 'X-PLL-UserSync-Iframe') {
return 'https://tracker-1.ortb.net/sync.html';
}
}
},
body: []
}
];
const syncOptions = {
iframeEnabled: false,
pixelEnabled: false
};
expect(spec.getUserSyncs(syncOptions, serverResponses)).to.be.an('array').that.is.empty;
});
it('should return iframe sync urls if iframe sync is enabled', function () {
it('should return no pixels if iframe sync is enabled and headers are blank', function () {
const serverResponses = [
{
headers: null,
body: []
}
];
const syncOptions = {
iframeEnabled: true,
pixelEnabled: false
};
expect(spec.getUserSyncs(syncOptions, serverResponses)).to.be.an('array').that.is.empty;
});
it('should return image sync urls for lm if pixel sync is enabled and headers have lm pixel', function () {
const serverResponses = [
{
headers: {
get: function (header) {
if (header === 'X-PLL-UserSync-Image') {
return 'https://tracker-lm.ortb.net/sync';
}
if (header === 'X-PLL-UserSync-Iframe') {
return 'https://tracker-lm.ortb.net/sync.html';
}
}
},
body: []
}
];
const syncOptions = {
iframeEnabled: false,
pixelEnabled: true
};
expect(spec.getUserSyncs(syncOptions, serverResponses)).to.deep.equal([
{
type: 'iframe',
url: 'iframeUrl'
},
type: 'image',
url: 'https://tracker-lm.ortb.net/sync'
}
]);
});
it('should return image sync urls for client1 and clien2 if pixel sync is enabled and two responses and headers have two pixels', function () {
const serverResponses = [
{
type: 'iframe',
url: 'iframeUrl2'
headers: {
get: function (header) {
if (header === 'X-PLL-UserSync-Image') {
return 'https://tracker-1.ortb.net/sync';
}
if (header === 'X-PLL-UserSync-Iframe') {
return 'https://tracker-1.ortb.net/sync.html';
}
}
},
body: []
},
{
type: 'iframe',
url: 'iframeUrl3'
headers: {
get: function (header) {
if (header === 'X-PLL-UserSync-Image') {
return 'https://tracker-2.ortb.net/sync';
}
if (header === 'X-PLL-UserSync-Iframe') {
return 'https://tracker-2.ortb.net/sync.html';
}
}
},
body: []
}
]);
});
it('should return image sync urls if pixel sync is enabled', function () {
];
const syncOptions = {
iframeEnabled: false,
pixelEnabled: true
};
expect(spec.getUserSyncs(syncOptions, serverResponses)).to.deep.equal([
{
type: 'image',
url: 'pixelUrl'
url: 'https://tracker-1.ortb.net/sync'
},
{
type: 'image',
url: 'pixelUrl3'
url: 'https://tracker-2.ortb.net/sync'
}
]);
});
it('should return image sync url for pll if pixel sync is enabled and two responses and headers have two same pixels', function () {
const serverResponses = [
{
headers: {
get: function (header) {
if (header === 'X-PLL-UserSync-Image') {
return 'https://tracker-lm.ortb.net/sync';
}
if (header === 'X-PLL-UserSync-Iframe') {
return 'https://tracker-lm.ortb.net/sync.html';
}
}
},
body: []
},
{
headers: {
get: function (header) {
if (header === 'X-PLL-UserSync-Image') {
return 'https://tracker-lm.ortb.net/sync';
}
if (header === 'X-PLL-UserSync-Iframe') {
return 'https://tracker-lm.ortb.net/sync.html';
}
}
},
body: []
}
];
const syncOptions = {
iframeEnabled: false,
pixelEnabled: true
};
expect(spec.getUserSyncs(syncOptions, serverResponses)).to.deep.equal([
{
type: 'image',
url: 'pixelUrl2'
url: 'https://tracker-lm.ortb.net/sync'
}
]);
});
it('should return all sync urls if all sync types are enabled', function () {
it('should return iframe sync url for pll if pixel sync is enabled and iframe is enables and headers have both iframe and img pixels', function () {
const serverResponses = [
{
headers: {
get: function (header) {
if (header === 'X-PLL-UserSync-Image') {
return 'https://tracker-lm.ortb.net/sync';
}
if (header === 'X-PLL-UserSync-Iframe') {
return 'https://tracker-lm.ortb.net/sync.html';
}
}
},
body: []
}
];
const syncOptions = {
iframeEnabled: true,
pixelEnabled: true
}
};
expect(spec.getUserSyncs(syncOptions, serverResponses)).to.deep.equal([
{
type: 'iframe',
url: 'iframeUrl'
},
{
type: 'iframe',
url: 'iframeUrl2'
},
{
type: 'iframe',
url: 'iframeUrl3'
},
{
type: 'image',
url: 'pixelUrl'
},
{
type: 'image',
url: 'pixelUrl3'
},
{
type: 'image',
url: 'pixelUrl2'
url: 'https://tracker-lm.ortb.net/sync.html'
}
]);
});
Expand Down

0 comments on commit 5eacb78

Please sign in to comment.