Skip to content

Commit

Permalink
sspBC adapter: update to v4.6 (notifications, user sync) (prebid#5941)
Browse files Browse the repository at this point in the history
Update adapter to v4.6
- add notification endpoint
- send bidWon and onTimeout notifications
- send CMP version to user sync endpoint

Co-authored-by: Wojciech Biały <wb@WojciechBialy.local>
  • Loading branch information
2 people authored and stsepelin committed May 28, 2021
1 parent b777133 commit ebf1bb1
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 5 deletions.
51 changes: 48 additions & 3 deletions modules/sspBCAdapter.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import * as utils from '../src/utils.js';
import { ajax } from '../src/ajax.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { BANNER } from '../src/mediaTypes.js';

const BIDDER_CODE = 'sspBC';
const BIDDER_URL = 'https://ssp.wp.pl/bidder/';
const SYNC_URL = 'https://ssp.wp.pl/bidder/usersync';
const NOTIFY_URL = 'https://ssp.wp.pl/bidder/notify';
const TMAX = 450;
const BIDDER_VERSION = '4.5';
const BIDDER_VERSION = '4.6';
const W = window;
const { navigator } = W;
var consentApiVersion;

const cookieSupport = () => {
const isSafari = /^((?!chrome|android|crios|fxios).)*safari/i.test(navigator.userAgent);
Expand Down Expand Up @@ -53,6 +56,7 @@ const applyClientHints = ortbRequest => {

function applyGdpr(bidderRequest, ortbRequest) {
if (bidderRequest && bidderRequest.gdprConsent) {
consentApiVersion = bidderRequest.gdprConsent.apiVersion;
ortbRequest.regs = Object.assign(ortbRequest.regs, { '[ortb_extensions.gdpr]': bidderRequest.gdprConsent.gdprApplies ? 1 : 0 });
ortbRequest.user = Object.assign(ortbRequest.user, { '[ortb_extensions.consent]': bidderRequest.gdprConsent.consentString });
}
Expand All @@ -68,6 +72,14 @@ function setOnAny(collection, key) {
}
}

function sendNotification(payload) {
ajax(NOTIFY_URL, null, JSON.stringify(payload), {
withCredentials: false,
method: 'POST',
crossOrigin: true
});
}

/**
* @param {object} slot Ad Unit Params by Prebid
* @returns {object} Banner by OpenRTB 2.5 §3.2.6
Expand Down Expand Up @@ -278,6 +290,7 @@ const spec = {
mediaType: 'banner',
meta: {
advertiserDomains: serverBid.adomain,
networkName: seat,
},
netRevenue: true,
ad: renderCreative(site, response.id, serverBid, seat, request.bidderRequest),
Expand All @@ -303,12 +316,44 @@ const spec = {
if (syncOptions.iframeEnabled) {
return [{
type: 'iframe',
url: SYNC_URL,
url: SYNC_URL + '?tcf=' + consentApiVersion,
}];
}
utils.logWarn('sspBC adapter requires iframe based user sync.');
},
onTimeout() {

onTimeout(timeoutData) {
var adSlots = [];
const bid = timeoutData && timeoutData[0];
if (bid) {
timeoutData.forEach(bid => { adSlots.push(bid.params[0] && bid.params[0].id) })
const payload = {
event: 'timeout',
requestId: bid.auctionId,
siteId: bid.params ? [bid.params[0].siteId] : [],
slotId: adSlots,
timeout: bid.timeout,
}
sendNotification(payload);
return payload;
}
},

onBidWon(bid) {
if (bid && bid.auctionId) {
const payload = {
event: 'bidWon',
requestId: bid.auctionId,
siteId: bid.params ? [bid.params[0].siteId] : [],
slotId: bid.params ? [bid.params[0].id] : [],
cpm: bid.cpm,
creativeId: bid.creativeId,
adomain: (bid.meta && bid.meta.advertiserDomains) ? bid.meta.advertiserDomains[0] : '',
networkName: (bid.meta && bid.meta.networkName) ? bid.meta.networkName : '',
}
sendNotification(payload);
return payload;
}
},
};

Expand Down
70 changes: 68 additions & 2 deletions test/spec/modules/sspBCAdapter_spec.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { assert, expect } from 'chai';
import { spec } from 'modules/sspBCAdapter.js';
import * as utils from 'src/utils.js';
import * as sinon from 'sinon';
import * as ajax from 'src/ajax.js';

const BIDDER_CODE = 'sspBC';
const BIDDER_URL = 'https://ssp.wp.pl/bidder/';
Expand Down Expand Up @@ -60,10 +62,33 @@ describe('SSPBC adapter', function () {
},
auctionId,
bidderRequestId,
bidId: auctionId + '1',
bidId: auctionId + '2',
transactionId,
}
];
const bids_timeouted = [{
adUnitCode: 'test_wideboard',
bidder: BIDDER_CODE,
params: [{
id: '003',
siteId: '8816',
}],
auctionId,
bidId: auctionId + '1',
timeout: 100,
},
{
adUnitCode: 'test_rectangle',
bidder: BIDDER_CODE,
params: [{
id: '005',
siteId: '8816',
}],
auctionId,
bidId: auctionId + '2',
timeout: 100,
}
];
const bids_test = [{
adUnitCode: 'test_wideboard',
bidder: BIDDER_CODE,
Expand Down Expand Up @@ -209,6 +234,7 @@ describe('SSPBC adapter', function () {
return {
bids,
bids_test,
bids_timeouted,
bidRequest,
bidRequestSingle,
bidRequestTest,
Expand Down Expand Up @@ -323,12 +349,52 @@ describe('SSPBC adapter', function () {

it('should provide correct url, if frame sync is allowed', function () {
expect(syncResultAll).to.have.length(1);
expect(syncResultAll[0].url).to.be.equal(SYNC_URL);
expect(syncResultAll[0].url).to.have.string(SYNC_URL);
});

it('should send no syncs, if frame sync is not allowed', function () {
expect(syncResultImage).to.be.undefined;
expect(syncResultNone).to.be.undefined;
});
});

describe('onBidWon', function () {
it('should generate no notification if bid is undefined', function () {
let notificationPayload = spec.onBidWon();
expect(notificationPayload).to.be.undefined;
});

it('should generate notification with event name and request/site/slot data, if correct bid is provided', function () {
const { bids } = prepareTestData();
let bid = bids[0];
bid.params = [bid.params];

let notificationPayload = spec.onBidWon(bid);
expect(notificationPayload).to.have.property('event').that.equals('bidWon');
expect(notificationPayload).to.have.property('requestId').that.equals(bid.auctionId);
expect(notificationPayload).to.have.property('siteId').that.deep.equals([bid.params[0].siteId]);
expect(notificationPayload).to.have.property('slotId').that.deep.equals([bid.params[0].id]);
});
});

describe('onTimeout', function () {
it('should generate no notification if timeout data is undefined / has no bids', function () {
let notificationPayloadUndefined = spec.onTimeout();
let notificationPayloadNoBids = spec.onTimeout([]);

expect(notificationPayloadUndefined).to.be.undefined;
expect(notificationPayloadNoBids).to.be.undefined;
});

it('should generate single notification for any number of timeouted bids', function () {
const { bids_timeouted } = prepareTestData();

let notificationPayload = spec.onTimeout(bids_timeouted);

expect(notificationPayload).to.have.property('event').that.equals('timeout');
expect(notificationPayload).to.have.property('requestId').that.equals(bids_timeouted[0].auctionId);
expect(notificationPayload).to.have.property('siteId').that.deep.equals([bids_timeouted[0].params[0].siteId]);
expect(notificationPayload).to.have.property('slotId').that.deep.equals([bids_timeouted[0].params[0].id, bids_timeouted[1].params[0].id]);
});
});
});

0 comments on commit ebf1bb1

Please sign in to comment.