Skip to content

Commit

Permalink
Fluct Bid Adapter: add adomain for Prebid 5 compliance (prebid#7353)
Browse files Browse the repository at this point in the history
* add fluct

* add newline for linting
  • Loading branch information
ChrisHuie authored and Chris Pabst committed Jan 10, 2022
1 parent 6973d75 commit 2f949c0
Show file tree
Hide file tree
Showing 2 changed files with 338 additions and 0 deletions.
125 changes: 125 additions & 0 deletions modules/fluctBidAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import * as utils from '../src/utils.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';

const BIDDER_CODE = 'fluct';
const END_POINT = 'https://hb.adingo.jp/prebid';
const VERSION = '1.2';
const NET_REVENUE = true;
const TTL = 300;

export const spec = {
code: BIDDER_CODE,
aliases: ['adingo'],

/**
* Determines whether or not the given bid request is valid.
*
* @param {BidRequest} bid The bid params to validate.
* @return boolean True if this is a valid bid, and false otherwise.
*/
isBidRequestValid: (bid) => {
return !!(bid.params.groupId && bid.params.tagId);
},

/**
* Make a server request from the list of BidRequests.
*
* @param {validBidRequests[]} - an array of bids.
* @return ServerRequest Info describing the request to the server.
*/
buildRequests: (validBidRequests, bidderRequest) => {
const serverRequests = [];
const referer = bidderRequest.refererInfo.referer;

utils._each(validBidRequests, (request) => {
const data = Object();

data.referer = referer;
data.adUnitCode = request.adUnitCode;
data.bidId = request.bidId;
data.transactionId = request.transactionId;

data.sizes = [];
utils._each(request.sizes, (size) => {
data.sizes.push({
w: size[0],
h: size[1]
});
});

data.params = request.params;
const searchParams = new URLSearchParams(request.params);

serverRequests.push({
method: 'POST',
url: END_POINT + '?' + searchParams.toString(),
options: {
contentType: 'application/json',
withCredentials: true,
customHeaders: {
'x-fluct-app': 'prebid/fluctBidAdapter',
'x-fluct-version': VERSION,
'x-openrtb-version': 2.5
}
},
data: data
});
});

return serverRequests;
},

/*
* Unpack the respnse from the server into a list of bids.
*
* @param {serverResponse} serverResponse A successful response from the server.
* @return {bid[]} An array of bids which weer nested inside the server.
*/
interpretResponse: (serverResponse, serverRequest) => {
const bidResponses = [];

const res = serverResponse.body;
if (!utils.isEmpty(res) && !utils.isEmpty(res.seatbid) && !utils.isEmpty(res.seatbid[0].bid)) {
const bid = res.seatbid[0].bid[0];
const dealId = bid.dealid;
const beaconUrl = bid.burl;
const callImpBeacon = `<script type="application/javascript">` +
`(function() { var img = new Image(); img.src = "${beaconUrl}"})()` +
`</script>`;
let data = {
bidderCode: BIDDER_CODE,
requestId: res.id,
currency: res.cur,
cpm: parseFloat(bid.price) || 0,
netRevenue: NET_REVENUE,
width: bid.w,
height: bid.h,
creativeId: bid.crid,
ttl: TTL,
ad: bid.adm + callImpBeacon,
meta: {
advertiserDomains: bid.adomain || [],
},
};
if (!utils.isEmpty(dealId)) {
data.dealId = dealId;
}
bidResponses.push(data);
}
return bidResponses;
},

/*
* Register the user sync pixels which should be dropped after the auction.
*
* @params {syncOptions} syncOptions which user syncs are allowed?
* @params {ServerResponse[]} serverResponses List of server's responses.
* @return {UserSync[]} The user syncs which should be dropped.
*
*/
getUserSyncs: (syncOptions, serverResponses) => {
return [];
},
};

registerBidder(spec);
213 changes: 213 additions & 0 deletions test/spec/modules/fluctBidAdapter_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
import {expect} from 'chai';
import {spec} from 'modules/fluctBidAdapter';
import {newBidder} from 'src/adapters/bidderFactory';
import {config} from 'src/config';

describe('fluctAdapter', function () {
const adapter = newBidder(spec);

describe('inherited functions', function () {
it('exists and is a function', function () {
expect(adapter.callBids).to.exist.and.to.be.a('function');
});
});

describe('isBidRequestValid', function () {
const bid = {
bidder: 'fluct',
params: {
dfpUnitCode: '/1000/dfp_unit_code',
tagId: '10000:100000001',
groupId: '1000000002',
}
};
it('should return true when required params found', function () {
expect(spec.isBidRequestValid(bid)).to.equal(true);
});

it('should return false when required params are not passed', function () {
let bid = Object.assign({}, bid);
delete bid.params;
bid.params = {};
expect(spec.isBidRequestValid(bid)).to.equal(false);
});

it('should return true when dfpUnitCode is not passed', function () {
let bid = Object.assign({}, bid);
delete bid.params;
bid.params = {
tagId: '10000:100000001',
groupId: '1000000002',
};
expect(spec.isBidRequestValid(bid)).to.equal(true);
});

it('should return false when groupId is not passed', function () {
let bid = Object.assign({}, bid);
delete bid.params;
bid.params = {
dfpUnitCode: '/1000/dfp_unit_code',
tagId: '10000:100000001',
};
expect(spec.isBidRequestValid(bid)).to.equal(false);
});
});

describe('buildRequests', function () {
const bidRequests = [{
bidder: 'fluct',
params: {
dfpUnitCode: '/100000/unit_code',
tagId: '10000:100000001',
groupId: '1000000002',
},
adUnitCode: '/10000/unit_code',
sizes: [[300, 250], [336, 280]],
bidId: '237f4d1a293f99',
bidderRequestId: '1a857fa34c1c96',
auctionId: 'a297d1aa-7900-4ce4-a0aa-caa8d46c4af7',
transactionId: '00b2896c-2731-4f01-83e4-7a3ad5da13b6',
}];
const bidderRequest = {
refererInfo: {
referer: 'http://example.com'
}
};

it('sends bid request to ENDPOINT via POST', function () {
const request = spec.buildRequests(bidRequests, bidderRequest)[0];
expect(request.method).to.equal('POST');
});

it('sends bid request to ENDPOINT with query parameter', function () {
const request = spec.buildRequests(bidRequests, bidderRequest)[0];
expect(request.url).to.equal('https://hb.adingo.jp/prebid?dfpUnitCode=%2F100000%2Funit_code&tagId=10000%3A100000001&groupId=1000000002');
});
});

describe('interpretResponse', function() {
const callBeaconSnippet = '<script type="application/javascript">' +
'(function() { var img = new Image(); img.src = ' +
'"https://i.adingo.jp/?test=1&et=hb&bidid=237f4d1a293f99"' +
'})()</script>';

it('should get correct bid response', function() {
const bidRequest = {
bidder: 'fluct',
params: {
dfpUnitCode: '/10000/unit_code',
tagid: '10000:100000001',
groupId: '1000000002',
},
adUnitCode: '/10000/unit_code',
sizes: [[300, 250], [336, 280]],
bidId: '237f4d1a293f99',
bidderRequestId: '1a857fa34c1c96',
auctionId: 'a297d1aa-7900-4ce4-a0aa-caa8d46c4af7',
transactionId: '00b2896c-2731-4f01-83e4-7a3ad5da13b6',
};

const serverResponse = {
body: {
id: '237f4d1a293f99',
cur: 'JPY',
seatbid: [{
bid: [{
price: 100,
w: 300,
h: 250,
adm: '<!-- test creative -->',
burl: 'https://i.adingo.jp/?test=1&et=hb&bidid=237f4d1a293f99',
crid: 'test_creative',
adomain: ['test_adomain']
}]
}]
}
};

const expectedResponse = [
{
bidderCode: 'fluct',
requestId: '237f4d1a293f99',
currency: 'JPY',
cpm: 100,
netRevenue: true,
width: 300,
height: 250,
creativeId: 'test_creative',
ttl: 300,
ad: '<!-- test creative -->' + callBeaconSnippet,
meta: {
advertiserDomains: ['test_adomain'],
},
}
];

const result = spec.interpretResponse(serverResponse, bidRequest);
expect(result).to.have.lengthOf(1);
expect(result).to.deep.have.same.members(expectedResponse);
});

it('should get correct bid response with dealId', function() {
const bidRequest = {
bidder: 'fluct',
params: {
dfpUnitCode: '/10000/unit_code',
tagid: '10000:100000001',
groupId: '1000000002'
},
adUnitCode: '/10000/unit_code',
sizes: [[300, 250], [336, 280]],
bidId: '237f4d1a293f99',
bidderRequestId: '1a857fa34c1c96',
auctionId: 'a297d1aa-7900-4ce4-a0aa-caa8d46c4af7',
transactionId: '00b2896c-2731-4f01-83e4-7a3ad5da13b6',
};

const serverResponse = {
body: {
id: '237f4d1a293f99',
cur: 'JPY',
seatbid: [{
bid: [{
price: 100,
w: 300,
h: 250,
adm: '<!-- test creative -->',
burl: 'https://i.adingo.jp/?test=1&et=hb&bidid=237f4d1a293f99',
crid: 'test_creative',
dealid: 'test_deal',
}]
}]
}
};

const expectedResponse = [
{
bidderCode: 'fluct',
requestId: '237f4d1a293f99',
currency: 'JPY',
cpm: 100,
netRevenue: true,
width: 300,
height: 250,
creativeId: 'test_creative',
ttl: 300,
ad: '<!-- test creative -->' + callBeaconSnippet,
dealId: 'test_deal',
meta: {
advertiserDomains: [],
},
}
];

const result = spec.interpretResponse(serverResponse, bidRequest);
expect(result).to.have.lengthOf(1);
expect(result).to.deep.have.same.members(expectedResponse);
});

it('should get empty response when bid server returns 204', function() {
expect(spec.interpretResponse({})).to.be.empty;
});
});
});

0 comments on commit 2f949c0

Please sign in to comment.