Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sync with master #16

Merged
merged 4 commits into from
Jul 4, 2024
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
6 changes: 5 additions & 1 deletion modules/anonymisedRtdProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@ import {getStorageManager} from '../src/storageManager.js';
import {submodule} from '../src/hook.js';
import {isPlainObject, mergeDeep, logMessage, logError} from '../src/utils.js';
import {MODULE_TYPE_RTD} from '../src/activities/modules.js';

/**
* @typedef {import('../modules/rtdModule/index.js').RtdSubmodule} RtdSubmodule
*/
export function createRtdProvider(moduleName) {
const MODULE_NAME = 'realTimeData';
const SUBMODULE_NAME = moduleName;
const GVLID = 1116;

const storage = getStorageManager({ moduleType: MODULE_TYPE_RTD, moduleName: SUBMODULE_NAME });
/**
Expand Down Expand Up @@ -106,6 +109,7 @@ export function createRtdProvider(moduleName) {
/** @type {RtdSubmodule} */
const rtdSubmodule = {
name: SUBMODULE_NAME,
gvlid: GVLID,
getBidRequestData: getRealTimeData,
init: init
};
Expand Down
2 changes: 1 addition & 1 deletion modules/anonymisedRtdProvider.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Anonymised’s Real-time Data Provider automatically obtains segment IDs from th
- Build the anonymisedRtd module into the Prebid.js package with:

```bash
gulp build --modules=anonymisedRtdProvider,...
gulp build --modules=rtdModule,anonymisedRtdProvider,...
```

- Use `setConfig` to instruct Prebid.js to initilaize the anonymisedRtdProvider module, as specified below.
Expand Down
32 changes: 26 additions & 6 deletions modules/jwplayerRtdProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import {submodule} from '../src/hook.js';
import {config} from '../src/config.js';
import {ajaxBuilder} from '../src/ajax.js';
import {deepAccess, logError} from '../src/utils.js';
import { deepAccess, logError, logWarn } from '../src/utils.js'
import {find} from '../src/polyfill.js';
import {getGlobal} from '../src/prebidGlobal.js';

Expand Down Expand Up @@ -429,17 +429,37 @@ export function addTargetingToBid(bid, targeting) {
bid.rtd = Object.assign({}, rtd, jwRtd);
}

function getPlayer(playerDivId) {
export function getPlayer(playerDivId) {
const jwplayer = window.jwplayer;
if (!jwplayer) {
logError(SUBMODULE_NAME + '.js was not found on page');
return;
}

const player = jwplayer(playerDivId);
if (!player || !player.getPlaylist) {
logError('player ID did not match any players');
let player = jwplayer(playerDivId);
if (player && player.getPlaylist) {
return player;
}

const playerOnPageCount = document.getElementsByClassName('jwplayer').length;
if (playerOnPageCount === 0) {
logError('No JWPlayer instances have been detected on the page');
return;
}
return player;

let errorMessage = `player Div ID ${playerDivId} did not match any players.`;

// If there are multiple instances on the page, we cannot guess which one should be targeted.
if (playerOnPageCount > 1) {
logError(errorMessage);
return;
}

player = jwplayer();
if (player && player.getPlaylist) {
logWarn(`${errorMessage} Targeting player Div ID ${player.id} instead`);
return player;
}

logError(errorMessage);
}
4 changes: 3 additions & 1 deletion modules/mgidBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ _each(NATIVE_ASSETS, anAsset => { _NATIVE_ASSET_ID_TO_KEY_MAP[anAsset.ID] = anAs
_each(NATIVE_ASSETS, anAsset => { _NATIVE_ASSET_KEY_TO_ASSET_MAP[anAsset.KEY] = anAsset });

export const spec = {
VERSION: '1.6',
VERSION: '1.7',
code: BIDDER_CODE,
gvlid: GVLID,
supportedMediaTypes: [BANNER, NATIVE],
Expand Down Expand Up @@ -167,6 +167,8 @@ export const spec = {
tagid,
secure,
};
const gpid = deepAccess(bid, 'ortb2Imp.ext.gpid');
gpid && isStr(gpid) && deepSetValue(impObj, `ext.gpid`, gpid);
const floorData = getBidFloor(bid, cur);
if (floorData.floor) {
impObj.bidfloor = floorData.floor;
Expand Down
94 changes: 72 additions & 22 deletions modules/permutiveRtdProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ export function getModuleConfig(customModuleConfig) {
/**
* Sets ortb2 config for ac bidders
* @param {Object} bidderOrtb2 - The ortb2 object for the all bidders
* @param {Object} customModuleConfig - Publisher config for module
* @param {Object} moduleConfig - Publisher config for module
* @param {Object} segmentData - Segment data grouped by bidder or type
*/
export function setBidderRtb (bidderOrtb2, moduleConfig, segmentData) {
const acBidders = deepAccess(moduleConfig, 'params.acBidders')
Expand Down Expand Up @@ -129,13 +130,13 @@ export function setBidderRtb (bidderOrtb2, moduleConfig, segmentData) {

/**
* Updates `user.data` object in existing bidder config with Permutive segments
* @param string bidder - The bidder
* @param {string} bidder - The bidder identifier
* @param {Object} currConfig - Current bidder config
* @param {Object[]} transformationConfigs - array of objects with `id` and `config` properties, used to determine
* the transformations on user data to include the ORTB2 object
* @param {string[]} segmentIDs - Permutive segment IDs
* @param {string[]} sspSegmentIDs - Permutive SSP segment IDs
* @param {Object} topics - Privacy Sandbox Topics, keyed by IAB taxonomy version (600, 601, etc.)
* @param {Object[]} transformationConfigs - array of objects with `id` and `config` properties, used to determine
* the transformations on user data to include the ORTB2 object
* @param {Object} segmentData - The segments available for targeting
* @return {Object} Merged ortb2 object
*/
Expand Down Expand Up @@ -270,7 +271,7 @@ function setSegments (reqBidsConfigObj, moduleConfig, segmentData) {
*/
function makeSafe (fn) {
try {
fn()
return fn()
} catch (e) {
logError(e)
}
Expand Down Expand Up @@ -310,23 +311,71 @@ export function isPermutiveOnPage () {
* @param {number} maxSegs - Maximum number of segments to be included
* @return {Object}
*/
export function getSegments (maxSegs) {
const legacySegs = readSegments('_psegs', []).map(Number).filter(seg => seg >= 1000000).map(String)
const _ppam = readSegments('_ppam', [])
const _pcrprs = readSegments('_pcrprs', [])

export function getSegments(maxSegs) {
const segments = {
ac: [..._pcrprs, ..._ppam, ...legacySegs],
ix: readSegments('_pindexs', []),
rubicon: readSegments('_prubicons', []),
appnexus: readSegments('_papns', []),
gam: readSegments('_pdfps', []),
ssp: readSegments('_pssps', {
cohorts: [],
ssps: []
ac:
makeSafe(() => {
const legacySegs =
makeSafe(() =>
readSegments('_psegs', [])
.map(Number)
.filter((seg) => seg >= 1000000)
.map(String),
) || [];
const _ppam = makeSafe(() => readSegments('_ppam', []).map(String)) || [];
const _pcrprs = makeSafe(() => readSegments('_pcrprs', []).map(String)) || [];

return [..._pcrprs, ..._ppam, ...legacySegs];
}) || [],

ix:
makeSafe(() => {
const _pindexs = readSegments('_pindexs', []);
return _pindexs.map(String);
}) || [],

rubicon:
makeSafe(() => {
const _prubicons = readSegments('_prubicons', []);
return _prubicons.map(String);
}) || [],

appnexus:
makeSafe(() => {
const _papns = readSegments('_papns', []);
return _papns.map(String);
}) || [],

gam:
makeSafe(() => {
const _pdfps = readSegments('_pdfps', []);
return _pdfps.map(String);
}) || [],

ssp: makeSafe(() => {
const _pssps = readSegments('_pssps', {
cohorts: [],
ssps: [],
});

return {
cohorts: makeSafe(() => _pssps.cohorts.map(String)) || [],
ssps: makeSafe(() => _pssps.ssps.map(String)) || [],
};
}),
topics: readSegments('_ppsts', {}),
}

topics:
makeSafe(() => {
const _ppsts = readSegments('_ppsts', {});

const topics = {};
for (const [k, value] of Object.entries(_ppsts)) {
topics[k] = makeSafe(() => value.map(String)) || [];
}

return topics;
}) || {},
};

for (const bidder in segments) {
if (bidder === 'ssp') {
Expand All @@ -342,7 +391,8 @@ export function getSegments (maxSegs) {
}
}

return segments
logger.logInfo(`Read segments`, segments)
return segments;
}

/**
Expand Down Expand Up @@ -393,7 +443,7 @@ function iabSegmentId(permutiveSegmentId, iabIds) {
* Pull the latest configuration and cohort information and update accordingly.
*
* @param reqBidsConfigObj - Bidder provided config for request
* @param customModuleConfig - Publisher provide config
* @param moduleConfig - Publisher provided config
*/
export function readAndSetCohorts(reqBidsConfigObj, moduleConfig) {
const segmentData = getSegments(deepAccess(moduleConfig, 'params.maxSegs'))
Expand Down
61 changes: 61 additions & 0 deletions test/spec/modules/jwplayerRtdProvider_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
getVatFromCache,
getVatFromPlayer,
setOverrides,
getPlayer,
jwplayerSubmodule
} from 'modules/jwplayerRtdProvider.js';
import {server} from 'test/mocks/xhr.js';
Expand Down Expand Up @@ -1603,6 +1604,66 @@ describe('jwplayerRtdProvider', function() {
});
});

describe('Player detection', function () {
const playerInstanceMock = {
getPlaylist: () => [],
getPlaylistItem: () => ({})
};

beforeEach(function () {
window.jwplayer = sinon.stub();
});

afterEach(function () {
delete window.jwplayer;
});

it('should fail if jwplayer global does not exist', function () {
delete window.jwplayer;
expect(getPlayer('divId')).to.be.undefined;
});

it('should return the player instance for the specified div id', function () {
window.jwplayer.returns(playerInstanceMock);
const player = getPlayer('divId');
expect(player).to.deep.equal(playerInstanceMock);
});

it('should request a player when the div id does not match a player on the page and only 1 player is in the DOM', function () {
const playerDomElement = document.createElement('div');
playerDomElement.className = 'jwplayer';
document.body.appendChild(playerDomElement);

window.jwplayer.withArgs('invalidDivId').returns(undefined);
window.jwplayer.returns(playerInstanceMock);

const playerInstance = getPlayer('invalidDivId');

expect(playerInstance).to.deep.equal(playerInstanceMock);

document.body.removeChild(playerDomElement);
});

it('should fail when the div id does not match a player on the page, and multiple players are instantiated', function () {
const firstPlayerDomElement = document.createElement('div');
const secondPlayerDomElement = document.createElement('div');
firstPlayerDomElement.className = 'jwplayer';
secondPlayerDomElement.className = 'jwplayer';
document.body.appendChild(firstPlayerDomElement);
document.body.appendChild(secondPlayerDomElement);

window.jwplayer.withArgs('invalidDivId').returns(undefined);
window.jwplayer.returns(playerInstanceMock);

const playerInstance = getPlayer('invalidDivId');

expect(playerInstance).to.be.undefined;

document.body.removeChild(firstPlayerDomElement);
document.body.removeChild(secondPlayerDomElement);
});
});

describe('jwplayerSubmodule', function () {
it('successfully instantiates', function () {
expect(jwplayerSubmodule.init()).to.equal(true);
Expand Down
20 changes: 15 additions & 5 deletions test/spec/modules/mgidBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,14 @@ describe('Mgid bid adapter', function () {
let abid = {
adUnitCode: 'div',
bidder: 'mgid',
ortb2Imp: {
ext: {
gpid: '/1111/gpid',
data: {
pbadslot: '/1111/gpid',
}
}
},
params: {
accountId: '1',
placementId: '2',
Expand Down Expand Up @@ -447,12 +455,13 @@ describe('Mgid bid adapter', function () {
expect(data.device.w).equal(screenWidth);
expect(data.device.language).to.deep.equal(lang);
expect(data.imp[0].tagid).to.deep.equal('2/div');
expect(data.imp[0].ext.gpid).to.deep.equal('/1111/gpid');
expect(data.imp[0].banner).to.deep.equal({w: 300, h: 250});
expect(data.imp[0].secure).to.deep.equal(secure);
expect(request).to.deep.equal({
'method': 'POST',
'url': 'https://prebid.mgid.com/prebid/1',
'data': `{"site":{"domain":"${domain}","page":"${page}"},"cur":["USD"],"geo":{"utcoffset":${utcOffset}},"device":{"ua":"${ua}","js":1,"dnt":${dnt},"h":${screenHeight},"w":${screenWidth},"language":"${lang}"},"ext":{"mgid_ver":"${mgid_ver}","prebid_ver":"${version}"},"imp":[{"tagid":"2/div","secure":${secure},"banner":{"w":300,"h":250}}],"tmax":3000}`,
'data': `{"site":{"domain":"${domain}","page":"${page}"},"cur":["USD"],"geo":{"utcoffset":${utcOffset}},"device":{"ua":"${ua}","js":1,"dnt":${dnt},"h":${screenHeight},"w":${screenWidth},"language":"${lang}"},"ext":{"mgid_ver":"${mgid_ver}","prebid_ver":"${version}"},"imp":[{"tagid":"2/div","secure":${secure},"ext":{"gpid":"/1111/gpid"},"banner":{"w":300,"h":250}}],"tmax":3000}`,
});
});
it('should not return native imp if minimum asset list not requested', function () {
Expand Down Expand Up @@ -496,12 +505,13 @@ describe('Mgid bid adapter', function () {
expect(data.device.w).equal(screenWidth);
expect(data.device.language).to.deep.equal(lang);
expect(data.imp[0].tagid).to.deep.equal('2/div');
expect(data.imp[0].ext.gpid).to.deep.equal('/1111/gpid');
expect(data.imp[0].native).is.a('object').and.to.deep.equal({'request': {'assets': [{'id': 1, 'required': 1, 'title': {'len': 80}}, {'id': 2, 'img': {'h': 80, 'type': 3, 'w': 80}, 'required': 0}, {'data': {'type': 1}, 'id': 11, 'required': 0}], 'plcmtcnt': 1}});
expect(data.imp[0].secure).to.deep.equal(secure);
expect(request).to.deep.equal({
'method': 'POST',
'url': 'https://prebid.mgid.com/prebid/1',
'data': `{"site":{"domain":"${domain}","page":"${page}"},"cur":["USD"],"geo":{"utcoffset":${utcOffset}},"device":{"ua":"${ua}","js":1,"dnt":${dnt},"h":${screenHeight},"w":${screenWidth},"language":"${lang}"},"ext":{"mgid_ver":"${mgid_ver}","prebid_ver":"${version}"},"imp":[{"tagid":"2/div","secure":${secure},"native":{"request":{"plcmtcnt":1,"assets":[{"id":1,"required":1,"title":{"len":80}},{"id":2,"required":0,"img":{"type":3,"w":80,"h":80}},{"id":11,"required":0,"data":{"type":1}}]}}}],"tmax":3000}`,
'data': `{"site":{"domain":"${domain}","page":"${page}"},"cur":["USD"],"geo":{"utcoffset":${utcOffset}},"device":{"ua":"${ua}","js":1,"dnt":${dnt},"h":${screenHeight},"w":${screenWidth},"language":"${lang}"},"ext":{"mgid_ver":"${mgid_ver}","prebid_ver":"${version}"},"imp":[{"tagid":"2/div","secure":${secure},"ext":{"gpid":"/1111/gpid"},"native":{"request":{"plcmtcnt":1,"assets":[{"id":1,"required":1,"title":{"len":80}},{"id":2,"required":0,"img":{"type":3,"w":80,"h":80}},{"id":11,"required":0,"data":{"type":1}}]}}}],"tmax":3000}`,
});
});
it('should return proper native imp with image altered', function () {
Expand Down Expand Up @@ -538,7 +548,7 @@ describe('Mgid bid adapter', function () {
expect(request).to.deep.equal({
'method': 'POST',
'url': 'https://prebid.mgid.com/prebid/1',
'data': `{"site":{"domain":"${domain}","page":"${page}"},"cur":["USD"],"geo":{"utcoffset":${utcOffset}},"device":{"ua":"${ua}","js":1,"dnt":${dnt},"h":${screenHeight},"w":${screenWidth},"language":"${lang}"},"ext":{"mgid_ver":"${mgid_ver}","prebid_ver":"${version}"},"imp":[{"tagid":"2/div","secure":${secure},"native":{"request":{"plcmtcnt":1,"assets":[{"id":1,"required":1,"title":{"len":80}},{"id":2,"required":1,"img":{"type":3,"w":492,"h":328,"wmin":50,"hmin":50}},{"id":3,"required":0,"img":{"type":1,"w":50,"h":50}},{"id":11,"required":0,"data":{"type":1}}]}}}],"tmax":3000}`,
'data': `{"site":{"domain":"${domain}","page":"${page}"},"cur":["USD"],"geo":{"utcoffset":${utcOffset}},"device":{"ua":"${ua}","js":1,"dnt":${dnt},"h":${screenHeight},"w":${screenWidth},"language":"${lang}"},"ext":{"mgid_ver":"${mgid_ver}","prebid_ver":"${version}"},"imp":[{"tagid":"2/div","secure":${secure},"ext":{"gpid":"/1111/gpid"},"native":{"request":{"plcmtcnt":1,"assets":[{"id":1,"required":1,"title":{"len":80}},{"id":2,"required":1,"img":{"type":3,"w":492,"h":328,"wmin":50,"hmin":50}},{"id":3,"required":0,"img":{"type":1,"w":50,"h":50}},{"id":11,"required":0,"data":{"type":1}}]}}}],"tmax":3000}`,
});
});
it('should return proper native imp with sponsoredBy', function () {
Expand Down Expand Up @@ -574,7 +584,7 @@ describe('Mgid bid adapter', function () {
expect(request).to.deep.equal({
'method': 'POST',
'url': 'https://prebid.mgid.com/prebid/1',
'data': `{"site":{"domain":"${domain}","page":"${page}"},"cur":["USD"],"geo":{"utcoffset":${utcOffset}},"device":{"ua":"${ua}","js":1,"dnt":${dnt},"h":${screenHeight},"w":${screenWidth},"language":"${lang}"},"ext":{"mgid_ver":"${mgid_ver}","prebid_ver":"${version}"},"imp":[{"tagid":"2/div","secure":${secure},"native":{"request":{"plcmtcnt":1,"assets":[{"id":1,"required":1,"title":{"len":80}},{"id":2,"required":0,"img":{"type":3,"w":80,"h":80}},{"id":4,"required":0,"data":{"type":1}}]}}}],"tmax":3000}`,
'data': `{"site":{"domain":"${domain}","page":"${page}"},"cur":["USD"],"geo":{"utcoffset":${utcOffset}},"device":{"ua":"${ua}","js":1,"dnt":${dnt},"h":${screenHeight},"w":${screenWidth},"language":"${lang}"},"ext":{"mgid_ver":"${mgid_ver}","prebid_ver":"${version}"},"imp":[{"tagid":"2/div","secure":${secure},"ext":{"gpid":"/1111/gpid"},"native":{"request":{"plcmtcnt":1,"assets":[{"id":1,"required":1,"title":{"len":80}},{"id":2,"required":0,"img":{"type":3,"w":80,"h":80}},{"id":4,"required":0,"data":{"type":1}}]}}}],"tmax":3000}`,
});
});
it('should return proper banner request', function () {
Expand Down Expand Up @@ -608,7 +618,7 @@ describe('Mgid bid adapter', function () {
expect(request).to.deep.equal({
'method': 'POST',
'url': 'https://prebid.mgid.com/prebid/1',
'data': `{"site":{"domain":"${domain}","page":"${page}"},"cur":["USD"],"geo":{"utcoffset":${utcOffset}},"device":{"ua":"${ua}","js":1,"dnt":${dnt},"h":${screenHeight},"w":${screenWidth},"language":"${lang}"},"ext":{"mgid_ver":"${mgid_ver}","prebid_ver":"${version}"},"imp":[{"tagid":"2/div","secure":${secure},"banner":{"w":300,"h":600,"format":[{"w":300,"h":600},{"w":300,"h":250}],"pos":1}}],"tmax":3000}`,
'data': `{"site":{"domain":"${domain}","page":"${page}"},"cur":["USD"],"geo":{"utcoffset":${utcOffset}},"device":{"ua":"${ua}","js":1,"dnt":${dnt},"h":${screenHeight},"w":${screenWidth},"language":"${lang}"},"ext":{"mgid_ver":"${mgid_ver}","prebid_ver":"${version}"},"imp":[{"tagid":"2/div","secure":${secure},"ext":{"gpid":"/1111/gpid"},"banner":{"w":300,"h":600,"format":[{"w":300,"h":600},{"w":300,"h":250}],"pos":1}}],"tmax":3000}`,
});
});
it('should proper handle ortb2 data', function () {
Expand Down
Loading