Skip to content

Commit

Permalink
Initial commit for ResponsiveAds bid adapter (#12554)
Browse files Browse the repository at this point in the history
  • Loading branch information
pzagor2 authored Dec 16, 2024
1 parent 9fe52d9 commit 0a0325f
Show file tree
Hide file tree
Showing 3 changed files with 263 additions and 0 deletions.
80 changes: 80 additions & 0 deletions modules/responsiveAdsBidAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import {registerBidder} from '../src/adapters/bidderFactory.js';
import { BANNER } from '../src/mediaTypes.js';
import { ortbConverter } from '../libraries/ortbConverter/converter.js'
import {
logMessage,
isSafeFrameWindow,
mergeDeep,
canAccessWindowTop,
} from '../src/utils.js';

const BIDDER_VERSION = '1.0';
const BIDDER_CODE = 'responsiveads';
const ENDPOINT_URL = 'https://ve60c4xzl9.execute-api.us-east-1.amazonaws.com/prod/prebidjs';
const DEFAULT_CURRENCY = 'USD';
const GVLID = 1189;

const converter = ortbConverter({
context: {
mediaType: BANNER,
netRevenue: true,
ttl: 300,
currency: DEFAULT_CURRENCY,
},
request(buildRequest, imps, bidderRequest, context) {
const req = buildRequest(imps, bidderRequest, context);
// add additional information we might need on the backend
mergeDeep(req, {
ext: {
prebid: {
adapterVersion: `${BIDDER_VERSION}`,
},
},
});
return req;
},
});

export const spec = {
code: BIDDER_CODE,
gvlid: GVLID,
supportedMediaTypes: [BANNER],
isBidRequestValid: function(bid) {
// validate the bid request
return !!(bid.params);
},
buildRequests: function(bidRequests, bidderRequest) {
// we only want to bid if we are not in a safeframe
if (isSafeFrameWindow()) {
return null;
}

// if we can't access top we don't want to bid
if (!canAccessWindowTop()) {
return null;
}
const data = converter.toORTB({ bidRequests, bidderRequest });
return {
method: 'POST',
url: ENDPOINT_URL,
data: data,
options: {
contentType: 'application/json',
withCredentials: false
},
bidderRequest
};
},
interpretResponse: function(response, request) {
const res = converter.fromORTB({ response: response.body, request: request.data });
const bids = res.bids;
return bids;
},

onBidWon: (bid) => {
logMessage('onBidWon', bid);
}

};

registerBidder(spec);
38 changes: 38 additions & 0 deletions modules/responsiveAdsBidAdapter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Overview

```markdown
Module Name: responsiveAdsBidAdapter
Module Type: Bidder Adapter
Maintainer: [email protected]
```


# Description
Module that connects to ResponsiveAds Programmatic Fluid demand.


## Running the code
To view an example of the on page setup required:

```bash
gulp serve-and-test --file test/spec/modules/responsiveAdsBidAdapter_spec.js
```

# Test Parameters
```
var adUnits = [{
code: 'div-gpt-ad-1460505748561-0',
mediaTypes: {
banner: {
sizes: [[300, 250]]
}
},
// Replace this object to test a new Adapter!
bids: [{
bidder: 'responsiveads',
params: {}
}]
}];
```
145 changes: 145 additions & 0 deletions test/spec/modules/responsiveAdsBidAdapter_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import { expect } from 'chai';
import { spec } from 'modules/responsiveAdsBidAdapter.js';
import * as utils from 'src/utils.js';

describe('responsiveAdsBidAdapter', function() {
let bidRequests;
let bidderRequest;
let sandbox;

beforeEach(function () {
sandbox = sinon.sandbox.create();
sandbox.stub(utils, 'isSafeFrameWindow').returns(false);
sandbox.stub(utils, 'canAccessWindowTop').returns(true);
bidRequests = [{
bidder: 'responsiveads',
params: {
placementId: '1',
},
adUnitCode: '/3434399/header-bid-tag-1',
mediaTypes: {
banner: {
sizes: [[300, 250], [300, 600]],
}
},
bidId: '123',
auctionId: '456',
bidderRequestId: '789',
transactionId: '123'
}];

bidderRequest = {
timeout: 3000,
}
});

afterEach(function () {
sandbox.restore();
});

describe('Check if bid is valid', function() {
it('Should accept valid bid', function() {
const validBid = {
bidder: 'responsiveads',
params: {},
};

const isValid = spec.isBidRequestValid(validBid);
expect(isValid).to.equal(true);
});

it('Should not reject bid if missing placementId', function() {
const validBid = {
bidder: 'responsiveads',
params: {}
};

const isValid = spec.isBidRequestValid(validBid);
expect(isValid).to.equal(true);
});
});

describe('Build requests', function () {
it('Should not bit on safeframe', function() {
utils.isSafeFrameWindow.restore();
sandbox.stub(utils, 'isSafeFrameWindow').returns(true);

const requests = spec.buildRequests(bidRequests, bidderRequest);
expect(requests).to.be.null;
});

it('Should not bit if cant access window top', function () {
utils.canAccessWindowTop.restore();
sandbox.stub(utils, 'canAccessWindowTop').returns(false);

const requests = spec.buildRequests(bidRequests, bidderRequest);
expect(requests).to.be.null;
});

it('Should use POST and have URL', function() {
const request = spec.buildRequests(bidRequests, bidderRequest);

expect(request.method).to.exist;
expect(request.method).to.equal('POST');
expect(request.url).to.exist;
});

it('Should add adapter version', function() {
const request = spec.buildRequests(bidRequests, bidderRequest);
expect(request.data.ext.prebid.adapterVersion).to.exist;
});
});

describe('Handling responses', function() {
it('Should return complete bid response', function() {
const serverResponse = {
body: {
id: 'response-id',
cur: 'USD',
seatbid: [
{
bid: [
{
id: '123',
impid: '123',
price: 0.5,
adm: `<creative></creative>`,
nurl: 'https://example.com/win',
crid: '662d13e12e0c567af92d0918',
w: 300,
h: 250,
mediaType: 'banner',
adomain: ['responsiveads.com'],
attr: [1],
cat: ['IAB1']
}
]
}
]
}
};

const request = spec.buildRequests(bidRequests, bidderRequest);
const bids = spec.interpretResponse(serverResponse, request);

expect(bids).to.be.lengthOf(1);
expect(bids[0].requestId).to.equal('123');
expect(bids[0].cpm).to.equal(0.5);
expect(bids[0].width).to.equal(300);
expect(bids[0].height).to.equal(250);
expect(bids[0].ad).to.have.length.above(1);
expect(bids[0].meta.advertiserDomains).to.deep.equal(['responsiveads.com']);
});

it('should return empty bid response', function () {
const emptyServerResponse = {
body: []
};

const request = spec.buildRequests(bidRequests, bidderRequest);
const bids = spec.interpretResponse(emptyServerResponse, request);

expect(bids).to.be.lengthOf(0);
});
});
});

0 comments on commit 0a0325f

Please sign in to comment.