diff --git a/modules/sharethroughBidAdapter.js b/modules/sharethroughBidAdapter.js
index bb7f778089a..9aabca9518a 100644
--- a/modules/sharethroughBidAdapter.js
+++ b/modules/sharethroughBidAdapter.js
@@ -1,12 +1,14 @@
import { registerBidder } from 'src/adapters/bidderFactory';
+const VERSION = '3.0.0';
const BIDDER_CODE = 'sharethrough';
-const VERSION = '2.0.0';
const STR_ENDPOINT = document.location.protocol + '//btlr.sharethrough.com/header-bid/v1';
export const sharethroughAdapterSpec = {
code: BIDDER_CODE,
+
isBidRequestValid: bid => !!bid.params.pkey && bid.bidder === BIDDER_CODE,
+
buildRequests: (bidRequests, bidderRequest) => {
return bidRequests.map(bid => {
let query = {
@@ -26,67 +28,112 @@ export const sharethroughAdapterSpec = {
query.consent_required = !!bidderRequest.gdprConsent.gdprApplies;
}
+ // Data that does not need to go to the server,
+ // but we need as part of interpretResponse()
+ const strData = {
+ stayInIframe: bid.params.iframe,
+ sizes: bid.sizes
+ }
+
return {
method: 'GET',
url: STR_ENDPOINT,
- data: query
+ data: query,
+ strData: strData
};
})
},
+
interpretResponse: ({ body }, req) => {
- if (!body || !Object.keys(body).length || !body.creatives.length) {
+ if (!body || !body.creatives || !body.creatives.length) {
return [];
}
const creative = body.creatives[0];
+ let size = [0, 0];
+ if (req.strData.stayInIframe) {
+ size = getLargestSize(req.strData.sizes);
+ }
return [{
requestId: req.data.bidId,
- width: 0,
- height: 0,
+ width: size[0],
+ height: size[1],
cpm: creative.cpm,
creativeId: creative.creative.creative_key,
- deal_id: creative.creative.deal_id,
+ dealId: creative.creative.deal_id,
currency: 'USD',
netRevenue: true,
ttl: 360,
ad: generateAd(body, req)
}];
},
+
getUserSyncs: (syncOptions, serverResponses) => {
const syncs = [];
- if (syncOptions.pixelEnabled && serverResponses.length > 0 && serverResponses[0].body) {
+ const shouldCookieSync = syncOptions.pixelEnabled &&
+ serverResponses.length > 0 &&
+ serverResponses[0].body &&
+ serverResponses[0].body.cookieSyncUrls;
+
+ if (shouldCookieSync) {
serverResponses[0].body.cookieSyncUrls.forEach(url => {
syncs.push({ type: 'image', url: url });
});
}
+
return syncs;
}
}
+function getLargestSize(sizes) {
+ function area(size) {
+ return size[0] * size[1];
+ }
+
+ return sizes.reduce((prev, current) => {
+ if (area(current) > area(prev)) {
+ return current
+ } else {
+ return prev
+ }
+ }, [0, 0]);
+}
+
function generateAd(body, req) {
const strRespId = `str_response_${req.data.bidId}`;
- return `
+ let adMarkup = `
-
- `;
+ `
+
+ if (req.strData.stayInIframe) {
+ // Don't break out of iframe
+ adMarkup = adMarkup + ``
+ } else {
+ // Break out of iframe
+ adMarkup = adMarkup + `
+
+ `
+ }
+
+ return adMarkup;
}
// See https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding#The_Unicode_Problem
diff --git a/modules/sharethroughBidAdapter.md b/modules/sharethroughBidAdapter.md
index 8ab44f2a0f2..d2d8030c5f7 100644
--- a/modules/sharethroughBidAdapter.md
+++ b/modules/sharethroughBidAdapter.md
@@ -26,12 +26,13 @@ Module that connects to Sharethrough's demand sources
]
},{
code: 'test-div',
- sizes: [[1, 1]], // a mobile size
+ sizes: [[300,250], [1, 1]], // a mobile size
bids: [
{
bidder: "sharethrough",
params: {
- pkey: 'LuB3vxGGFrBZJa6tifXW4xgK'
+ pkey: 'LuB3vxGGFrBZJa6tifXW4xgK',
+ iframe: true
}
}
]
diff --git a/test/spec/modules/sharethroughBidAdapter_spec.js b/test/spec/modules/sharethroughBidAdapter_spec.js
index 2aef88fe7eb..a599ce6cdc8 100644
--- a/test/spec/modules/sharethroughBidAdapter_spec.js
+++ b/test/spec/modules/sharethroughBidAdapter_spec.js
@@ -19,17 +19,38 @@ const bidderRequest = [
sizes: [[700, 400]],
placementCode: 'bar',
params: {
- pkey: 'bbbb2222'
+ pkey: 'bbbb2222',
+ iframe: true
}
}];
-const prebidRequest = [{
- method: 'GET',
- url: document.location.protocol + '//btlr.sharethrough.com' + '/header-bid/v1',
- data: {
- bidId: 'bidId',
- placement_key: 'pKey'
- }
-}];
+
+const prebidRequests = [
+ {
+ method: 'GET',
+ url: document.location.protocol + '//btlr.sharethrough.com' + '/header-bid/v1',
+ data: {
+ bidId: 'bidId',
+ placement_key: 'pKey'
+ },
+ strData: {
+ stayInIframe: false,
+ sizes: []
+ }
+ },
+ {
+ method: 'GET',
+ url: document.location.protocol + '//btlr.sharethrough.com' + '/header-bid/v1',
+ data: {
+ bidId: 'bidId',
+ placement_key: 'pKey'
+ },
+ strData: {
+ stayInIframe: true,
+ sizes: [[300, 250], [300, 300], [250, 250], [600, 50]]
+ }
+ },
+];
+
const bidderResponse = {
body: {
'adserverRequestId': '40b6afd5-6134-4fbb-850a-bb8972a46994',
@@ -48,6 +69,7 @@ const bidderResponse = {
},
header: { get: (header) => header }
};
+
// Mirrors the one in modules/sharethroughBidAdapter.js as the function is unexported
const b64EncodeUnicode = (str) => {
return btoa(
@@ -56,6 +78,7 @@ const b64EncodeUnicode = (str) => {
return String.fromCharCode('0x' + p1);
}));
}
+
describe('sharethrough adapter spec', () => {
describe('.code', () => {
it('should return a bidder code of sharethrough', () => {
@@ -119,13 +142,27 @@ describe('sharethrough adapter spec', () => {
describe('.interpretResponse', () => {
it('returns a correctly parsed out response', () => {
- expect(spec.interpretResponse(bidderResponse, prebidRequest[0])[0]).to.include(
+ expect(spec.interpretResponse(bidderResponse, prebidRequests[0])[0]).to.include(
{
width: 0,
height: 0,
cpm: 12.34,
creativeId: 'aCreativeId',
- deal_id: 'aDealId',
+ dealId: 'aDealId',
+ currency: 'USD',
+ netRevenue: true,
+ ttl: 360,
+ });
+ });
+
+ it('returns a correctly parsed out response with largest size when strData.stayInIframe is true', () => {
+ expect(spec.interpretResponse(bidderResponse, prebidRequests[1])[0]).to.include(
+ {
+ width: 300,
+ height: 300,
+ cpm: 12.34,
+ creativeId: 'aCreativeId',
+ dealId: 'aDealId',
currency: 'USD',
netRevenue: true,
ttl: 360,
@@ -134,21 +171,21 @@ describe('sharethrough adapter spec', () => {
it('returns a blank array if there are no creatives', () => {
const bidResponse = { body: { creatives: [] } };
- expect(spec.interpretResponse(bidResponse, prebidRequest[0])).to.be.an('array').that.is.empty;
+ expect(spec.interpretResponse(bidResponse, prebidRequests[0])).to.be.an('array').that.is.empty;
});
it('returns a blank array if body object is empty', () => {
const bidResponse = { body: {} };
- expect(spec.interpretResponse(bidResponse, prebidRequest[0])).to.be.an('array').that.is.empty;
+ expect(spec.interpretResponse(bidResponse, prebidRequests[0])).to.be.an('array').that.is.empty;
});
it('returns a blank array if body is null', () => {
const bidResponse = { body: null };
- expect(spec.interpretResponse(bidResponse, prebidRequest[0])).to.be.an('array').that.is.empty;
+ expect(spec.interpretResponse(bidResponse, prebidRequests[0])).to.be.an('array').that.is.empty;
});
- it('correctly sends back a sfp script tag', () => {
- const adMarkup = spec.interpretResponse(bidderResponse, prebidRequest[0])[0].ad;
+ it('correctly generates ad markup', () => {
+ const adMarkup = spec.interpretResponse(bidderResponse, prebidRequests[0])[0].ad;
let resp = null;
expect(() => btoa(JSON.stringify(bidderResponse))).to.throw();
@@ -163,6 +200,19 @@ describe('sharethrough adapter spec', () => {
expect(adMarkup).to.match(
/window.top.document.getElementsByTagName\('body'\)\[0\].appendChild\(sfp_js\);/)
});
+
+ it('correctly generates ad markup for staying in iframe', () => {
+ const adMarkup = spec.interpretResponse(bidderResponse, prebidRequests[1])[0].ad;
+ let resp = null;
+
+ expect(() => btoa(JSON.stringify(bidderResponse))).to.throw();
+ expect(() => resp = b64EncodeUnicode(JSON.stringify(bidderResponse))).not.to.throw();
+ expect(adMarkup).to.match(
+ /data-str-native-key="pKey" data-stx-response-name=\"str_response_bidId\"/);
+ expect(!!adMarkup.indexOf(resp)).to.eql(true);
+ expect(adMarkup).to.match(
+ /