Skip to content

Commit cdec638

Browse files
authored
Video values, update logic concerning (#12217)
* Updating bid adapter and unit tests to remove some default video logic, which will now be handled within the Sharethrough exchange.
1 parent 86ec40c commit cdec638

File tree

2 files changed

+68
-104
lines changed

2 files changed

+68
-104
lines changed

modules/sharethroughBidAdapter.js

Lines changed: 26 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import { registerBidder } from '../src/adapters/bidderFactory.js';
22
import { config } from '../src/config.js';
33
import { BANNER, VIDEO } from '../src/mediaTypes.js';
4-
import { deepAccess, generateUUID, inIframe, mergeDeep } from '../src/utils.js';
4+
import { deepAccess, generateUUID, inIframe, logWarn, mergeDeep } from '../src/utils.js';
55

66
const VERSION = '4.3.0';
77
const BIDDER_CODE = 'sharethrough';
88
const SUPPLY_ID = 'WYu2BXv1';
99

1010
const STR_ENDPOINT = `https://btlr.sharethrough.com/universal/v1?supply_id=${SUPPLY_ID}`;
11+
const IDENTIFIER_PREFIX = 'Sharethrough:';
1112

1213
// this allows stubbing of utility function that is used internally by the sharethrough adapter
1314
export const sharethroughInternal = {
@@ -129,38 +130,40 @@ export const sharethroughAdapterSpec = {
129130
[w, h] = videoRequest.playerSize[0];
130131
}
131132

132-
const getVideoPlacementValue = (vidReq) => {
133-
if (vidReq.plcmt) {
134-
return vidReq.placement;
135-
} else {
136-
return vidReq.context === 'instream' ? 1 : +deepAccess(vidReq, 'placement', 4);
133+
/**
134+
* Applies a specified property to an impression object if it is present in the video request
135+
* @param {string} prop A property to apply to the impression object
136+
* @param {object} vidReq A video request object from which to extract the property
137+
* @param {object} imp A video impression object to which to apply the property
138+
*/
139+
const applyVideoProperty = (prop, vidReq, imp) => {
140+
const propIsTypeArray = ['api', 'battr', 'mimes', 'playbackmethod', 'protocols'].includes(prop);
141+
if (propIsTypeArray) {
142+
const notAssignable = (!Array.isArray(vidReq[prop]) || vidReq[prop].length === 0) && vidReq[prop];
143+
if (notAssignable) {
144+
logWarn(`${IDENTIFIER_PREFIX} Invalid video request property: "${prop}" must be an array with at least 1 entry. Value supplied: "${vidReq[prop]}". This will not be added to the bid request.`);
145+
return;
146+
}
147+
}
148+
if (vidReq[prop]) {
149+
imp.video[prop] = vidReq[prop];
137150
}
138151
};
139152

140153
impression.video = {
141154
pos: nullish(videoRequest.pos, 0),
142155
topframe: inIframe() ? 0 : 1,
143-
skip: nullish(videoRequest.skip, 0),
144-
linearity: nullish(videoRequest.linearity, 1),
145-
minduration: nullish(videoRequest.minduration, 5),
146-
maxduration: nullish(videoRequest.maxduration, 60),
147-
playbackmethod: videoRequest.playbackmethod || [2],
148-
api: getVideoApi(videoRequest),
149-
mimes: videoRequest.mimes || ['video/mp4'],
150-
protocols: getVideoProtocols(videoRequest),
151156
w,
152157
h,
153-
startdelay: nullish(videoRequest.startdelay, 0),
154-
skipmin: nullish(videoRequest.skipmin, 0),
155-
skipafter: nullish(videoRequest.skipafter, 0),
156-
placement: getVideoPlacementValue(videoRequest),
157-
plcmt: videoRequest.plcmt ? videoRequest.plcmt : null,
158158
};
159159

160-
if (videoRequest.battr) impression.video.battr = videoRequest.battr;
161-
if (videoRequest.delivery) impression.video.delivery = videoRequest.delivery;
162-
if (videoRequest.companiontype) impression.video.companiontype = videoRequest.companiontype;
163-
if (videoRequest.companionad) impression.video.companionad = videoRequest.companionad;
160+
const propertiesToConsider = [
161+
'api', 'battr', 'companionad', 'companiontype', 'delivery', 'linearity', 'maxduration', 'mimes', 'minduration', 'placement', 'playbackmethod', 'plcmt', 'protocols', 'skip', 'skipafter', 'skipmin', 'startdelay'
162+
]
163+
164+
propertiesToConsider.forEach(propertyToConsider => {
165+
applyVideoProperty(propertyToConsider, videoRequest, impression);
166+
});
164167
} else {
165168
impression.banner = {
166169
pos: deepAccess(bidReq, 'mediaTypes.banner.pos', 0),
@@ -274,24 +277,6 @@ export const sharethroughAdapterSpec = {
274277
onSetTargeting: (bid) => {},
275278
};
276279

277-
function getVideoApi({ api }) {
278-
let defaultValue = [2];
279-
if (api && Array.isArray(api) && api.length > 0) {
280-
return api;
281-
} else {
282-
return defaultValue;
283-
}
284-
}
285-
286-
function getVideoProtocols({ protocols }) {
287-
let defaultValue = [2, 3, 5, 6, 7, 8];
288-
if (protocols && Array.isArray(protocols) && protocols.length > 0) {
289-
return protocols;
290-
} else {
291-
return defaultValue;
292-
}
293-
}
294-
295280
function getBidRequestFloor(bid) {
296281
let floor = null;
297282
if (typeof bid.getFloor === 'function') {

test/spec/modules/sharethroughBidAdapter_spec.js

Lines changed: 42 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ describe('sharethrough adapter spec', function () {
217217
video: {
218218
pos: 3,
219219
skip: 1,
220-
linearity: 0,
220+
linearity: 1,
221221
minduration: 10,
222222
maxduration: 30,
223223
playbackmethod: [1],
@@ -233,6 +233,8 @@ describe('sharethrough adapter spec', function () {
233233
companiontype: 'companion type',
234234
companionad: 'companion ad',
235235
context: 'instream',
236+
placement: 1,
237+
plcmt: 1,
236238
},
237239
},
238240
getFloor: () => ({ currency: 'USD', floor: 42 }),
@@ -618,7 +620,7 @@ describe('sharethrough adapter spec', function () {
618620
expect(videoImp.pos).to.equal(3);
619621
expect(videoImp.topframe).to.equal(1);
620622
expect(videoImp.skip).to.equal(1);
621-
expect(videoImp.linearity).to.equal(0);
623+
expect(videoImp.linearity).to.equal(1);
622624
expect(videoImp.minduration).to.equal(10);
623625
expect(videoImp.maxduration).to.equal(30);
624626
expect(videoImp.playbackmethod).to.deep.equal([1]);
@@ -637,89 +639,66 @@ describe('sharethrough adapter spec', function () {
637639
expect(videoImp.companionad).to.equal('companion ad');
638640
});
639641

640-
it('should set defaults if no value provided', () => {
642+
it('should set defaults in some circumstances if no value provided', () => {
641643
delete bidRequests[1].mediaTypes.video.pos;
642-
delete bidRequests[1].mediaTypes.video.skip;
643-
delete bidRequests[1].mediaTypes.video.linearity;
644-
delete bidRequests[1].mediaTypes.video.minduration;
645-
delete bidRequests[1].mediaTypes.video.maxduration;
646-
delete bidRequests[1].mediaTypes.video.playbackmethod;
647-
delete bidRequests[1].mediaTypes.video.api;
648-
delete bidRequests[1].mediaTypes.video.mimes;
649-
delete bidRequests[1].mediaTypes.video.protocols;
650644
delete bidRequests[1].mediaTypes.video.playerSize;
651-
delete bidRequests[1].mediaTypes.video.startdelay;
652-
delete bidRequests[1].mediaTypes.video.skipmin;
653-
delete bidRequests[1].mediaTypes.video.skipafter;
654-
delete bidRequests[1].mediaTypes.video.placement;
655-
delete bidRequests[1].mediaTypes.video.delivery;
656-
delete bidRequests[1].mediaTypes.video.battr;
657-
delete bidRequests[1].mediaTypes.video.companiontype;
658-
delete bidRequests[1].mediaTypes.video.companionad;
659645

660646
const builtRequest = spec.buildRequests(bidRequests, bidderRequest)[1];
661647

662648
const videoImp = builtRequest.data.imp[0].video;
663649
expect(videoImp.pos).to.equal(0);
664-
expect(videoImp.skip).to.equal(0);
665-
expect(videoImp.linearity).to.equal(1);
666-
expect(videoImp.minduration).to.equal(5);
667-
expect(videoImp.maxduration).to.equal(60);
668-
expect(videoImp.playbackmethod).to.deep.equal([2]);
669-
expect(videoImp.api).to.deep.equal([2]);
670-
expect(videoImp.mimes).to.deep.equal(['video/mp4']);
671-
expect(videoImp.protocols).to.deep.equal([2, 3, 5, 6, 7, 8]);
672650
expect(videoImp.w).to.equal(640);
673651
expect(videoImp.h).to.equal(360);
674-
expect(videoImp.startdelay).to.equal(0);
675-
expect(videoImp.skipmin).to.equal(0);
676-
expect(videoImp.skipafter).to.equal(0);
677-
expect(videoImp.placement).to.equal(1);
678-
expect(videoImp.delivery).to.be.undefined;
679-
expect(videoImp.battr).to.be.undefined;
680-
expect(videoImp.companiontype).to.be.undefined;
681-
expect(videoImp.companionad).to.be.undefined;
682652
});
683653

684-
describe('outstream', () => {
685-
it('should use placement value if provided', () => {
686-
bidRequests[1].mediaTypes.video.context = 'outstream';
687-
bidRequests[1].mediaTypes.video.placement = 3;
654+
it('should not set values in some circumstances when non-valid values are supplied', () => {
655+
// arrange
656+
bidRequests[1].mediaTypes.video.api = 1; // non-array value, will not be used
657+
bidRequests[1].mediaTypes.video.battr = undefined; // non-array value, will not be used
658+
bidRequests[1].mediaTypes.video.mimes = 'video/3gpp'; // non-array value, will not be used
659+
bidRequests[1].mediaTypes.video.playbackmethod = null; // non-array value, will not be used
660+
bidRequests[1].mediaTypes.video.protocols = []; // empty array, will not be used
688661

689-
const builtRequest = spec.buildRequests(bidRequests, bidderRequest)[1];
690-
const videoImp = builtRequest.data.imp[0].video;
691-
692-
expect(videoImp.placement).to.equal(3);
693-
});
662+
// act
663+
const builtRequest = spec.buildRequests(bidRequests, bidderRequest)[1];
664+
const videoImp = builtRequest.data.imp[0].video;
694665

695-
it('should default placement to 4 if not provided', () => {
696-
bidRequests[1].mediaTypes.video.context = 'outstream';
666+
// assert
667+
expect(videoImp.api).to.be.undefined;
668+
expect(videoImp.battr).to.be.undefined;
669+
expect(videoImp.mimes).to.be.undefined;
670+
expect(videoImp.playbackmethod).to.be.undefined;
671+
expect(videoImp.protocols).to.be.undefined;
672+
});
697673

698-
const builtRequest = spec.buildRequests(bidRequests, bidderRequest)[1];
699-
const videoImp = builtRequest.data.imp[0].video;
674+
it('should not set a property if no corresponding property is detected on mediaTypes.video', () => {
675+
// arrange
676+
const propertiesToConsider = [
677+
'api', 'battr', 'companionad', 'companiontype', 'delivery', 'linearity', 'maxduration', 'mimes', 'minduration', 'placement', 'playbackmethod', 'plcmt', 'protocols', 'skip', 'skipafter', 'skipmin', 'startdelay'
678+
]
700679

701-
expect(videoImp.placement).to.equal(4);
680+
// act
681+
propertiesToConsider.forEach(propertyToConsider => {
682+
delete bidRequests[1].mediaTypes.video[propertyToConsider];
702683
});
684+
const builtRequest = spec.buildRequests(bidRequests, bidderRequest)[1];
685+
const videoImp = builtRequest.data.imp[0].video;
703686

704-
it('should not override "placement" value if "plcmt" prop is present', () => {
705-
// ASSEMBLE
706-
const ARBITRARY_PLACEMENT_VALUE = 99;
707-
const ARBITRARY_PLCMT_VALUE = 100;
708-
709-
bidRequests[1].mediaTypes.video.context = 'instream';
710-
bidRequests[1].mediaTypes.video.placement = ARBITRARY_PLACEMENT_VALUE;
687+
// assert
688+
propertiesToConsider.forEach(propertyToConsider => {
689+
expect(videoImp[propertyToConsider]).to.be.undefined;
690+
});
691+
});
711692

712-
// adding "plcmt" property - this should prevent "placement" prop
713-
// from getting overridden to 1
714-
bidRequests[1].mediaTypes.video['plcmt'] = ARBITRARY_PLCMT_VALUE;
693+
describe('outstream', () => {
694+
it('should use placement value if provided', () => {
695+
bidRequests[1].mediaTypes.video.context = 'outstream';
696+
bidRequests[1].mediaTypes.video.placement = 3;
715697

716-
// ACT
717698
const builtRequest = spec.buildRequests(bidRequests, bidderRequest)[1];
718699
const videoImp = builtRequest.data.imp[0].video;
719700

720-
// ASSERT
721-
expect(videoImp.placement).to.equal(ARBITRARY_PLACEMENT_VALUE);
722-
expect(videoImp.plcmt).to.equal(ARBITRARY_PLCMT_VALUE);
701+
expect(videoImp.placement).to.equal(3);
723702
});
724703
});
725704
});

0 commit comments

Comments
 (0)