Skip to content

Commit

Permalink
SmartyTech Bid Adapter : initial adapter release (prebid#9196)
Browse files Browse the repository at this point in the history
* Add new bid adapter for company smartytech

* change domain to prod

* update unit tests

* remove unused code

* remove unused code
  • Loading branch information
preved-medved authored and JacobKlein26 committed Feb 8, 2023
1 parent f8ddf8f commit 45bf543
Show file tree
Hide file tree
Showing 3 changed files with 284 additions and 0 deletions.
78 changes: 78 additions & 0 deletions modules/smartytechBidAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {buildUrl} from '../src/utils.js'

const BIDDER_CODE = 'smartytech';
export const ENDPOINT_PROTOCOL = 'https';
export const ENDPOINT_DOMAIN = 'server.smartytech.io';
export const ENDPOINT_PATH = '/hb/bidder';

export const spec = {
code: BIDDER_CODE,

isBidRequestValid: function (bidRequest) {
return !!parseInt(bidRequest.params.endpointId);
},

buildRequests: function (validBidRequests, bidderRequest) {
const referer = bidderRequest?.refererInfo?.page || window.location.href;

const bidRequests = validBidRequests.map((validBidRequest) => {
return {
endpointId: validBidRequest.params.endpointId,
adUnitCode: validBidRequest.adUnitCode,
sizes: validBidRequest.sizes,
bidId: validBidRequest.bidId,
referer: referer
};
});

let adPartnerRequestUrl = buildUrl({
protocol: ENDPOINT_PROTOCOL,
hostname: ENDPOINT_DOMAIN,
pathname: ENDPOINT_PATH,
});

return {
method: 'POST',
url: adPartnerRequestUrl,
data: bidRequests
};
},

interpretResponse: function (serverResponse, bidRequest) {
if (typeof serverResponse.body === 'undefined') {
return [];
}

const validBids = bidRequest.data;
const keys = Object.keys(serverResponse.body)
const responseBody = serverResponse.body;

return keys.filter(key => {
return responseBody[key].ad
}).map(key => {
return {
bid: validBids.find(b => b.adUnitCode === key),
response: responseBody[key]
}
}).map(item => spec.adResponse(item.bid.bidId, item.response));
},

adResponse: function (requestId, response) {
const bidObject = {
requestId,
ad: response.ad,
cpm: response.cpm,
width: response.width,
height: response.height,
ttl: 60,
creativeId: response.creativeId,
netRevenue: true,
currency: response.currency,
}
return bidObject;
},

}

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

Module Name: SmartyTech Bidder Adapter

Module Type: Bidder Adapter

Maintainer: info@adpartner.pro

# Description

You can use this adapter to get a bid from smartytech.io.

About us : https://smartytech.io

# Test Parameters

```javascript
var adUnits = [
{
code: 'div-smartytech-example',
sizes: [[300, 250]],
bids: [
{
bidder: "smartytech",
params: {
endpointId: 14
}
}
]
},
{
code: 'div-smartytech-example-2',
sizes: [[300, 250]],
bids: [
{
bidder: "smartytech",
params: {
endpointId: 14
}
}
]
}
];
```
162 changes: 162 additions & 0 deletions test/spec/modules/smartytechBidAdapter_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
import {expect} from 'chai';
import {spec, ENDPOINT_PROTOCOL, ENDPOINT_DOMAIN, ENDPOINT_PATH} from 'modules/smartytechBidAdapter';
import {newBidder} from 'src/adapters/bidderFactory.js';

const BIDDER_CODE = 'smartytech';

describe('SmartyTechDSPAdapter: inherited functions', function () {
let adapter;
beforeEach(() => {
adapter = newBidder(spec);
});
it('exists and is a function', function () {
expect(adapter.callBids).to.be.exist.and.to.be.a('function');
});
it(`bidder code is ${BIDDER_CODE}`, function () {
expect(spec.code).to.be.equal(BIDDER_CODE);
})
});

describe('SmartyTechDSPAdapter: isBidRequestValid', function () {
it('Invalid bid request. Should return false', function () {
const invalidBidFixture = {
params: {
use_id: 13144375
}
}
expect(spec.isBidRequestValid(invalidBidFixture)).to.be.false
});
it('Valid bid request. Should return true', function () {
const validBidFixture = {
params: {
endpointId: 13144375
}
}
expect(spec.isBidRequestValid(validBidFixture)).to.be.true
});
});

function mockRandomSizeArray(len) {
return Array.apply(null, {length: len}).map(i => {
return [Math.floor(Math.random() * 800), Math.floor(Math.random() * 800)]
});
}

function mockBidRequestListData(size) {
return Array.apply(null, {length: size}).map((i, index) => {
const id = Math.floor(Math.random() * 800) * (index + 1);
return {
adUnitCode: `adUnitCode-${id}`,
sizes: mockRandomSizeArray(index + 1),
bidId: `bidId-${id}`,
params: {
endpointId: id
}
}
});
}

function mockRefererData() {
return {
refererInfo: {
page: 'https://some-test.page'
}
}
}

function mockResponseData(requestData) {
let data = {}

requestData.data.forEach((request, index) => {
const sizeArrayIndex = Math.floor(Math.random() * (request.sizes.length - 1));
const rndIndex = Math.floor(Math.random() * 800);

data[request.adUnitCode] = {
ad: `ad-${rndIndex}`,
width: request.sizes[sizeArrayIndex][0],
height: request.sizes[sizeArrayIndex][1],
creativeId: `creative-id-${index}`,
cpm: Math.floor(Math.random() * 100),
currency: `UAH-${rndIndex}`
};
});
return {
body: data
}
};

describe('SmartyTechDSPAdapter: buildRequests', () => {
let mockBidRequest;
let mockReferer;
beforeEach(() => {
mockBidRequest = mockBidRequestListData(8);
mockReferer = mockRefererData();
});
it('has return data', () => {
const request = spec.buildRequests(mockBidRequest, mockReferer);
expect(request).not.null;
});
it('correct request URL', () => {
const request = spec.buildRequests(mockBidRequest, mockReferer);
expect(request.url).to.be.equal(`${ENDPOINT_PROTOCOL}://${ENDPOINT_DOMAIN}${ENDPOINT_PATH}`)
});
it('correct request method', () => {
const request = spec.buildRequests(mockBidRequest, mockReferer);
expect(request.method).to.be.equal(`POST`)
});
it('correct request data', () => {
const data = spec.buildRequests(mockBidRequest, mockReferer).data;
data.forEach((request, index) => {
expect(request.adUnitCode).to.be.equal(mockBidRequest[index].adUnitCode);
expect(request.sizes).to.be.equal(mockBidRequest[index].sizes);
expect(request.bidId).to.be.equal(mockBidRequest[index].bidId);
expect(request.endpointId).to.be.equal(mockBidRequest[index].params.endpointId);
expect(request.referer).to.be.equal(mockReferer.refererInfo.page);
})
});
});

describe('SmartyTechDSPAdapter: interpretResponse', () => {
let mockBidRequest;
let mockReferer;
let request;
let mockResponse;
beforeEach(() => {
const brData = mockBidRequestListData(2);
mockReferer = mockRefererData();
request = spec.buildRequests(brData, mockReferer);
mockBidRequest = {
data: brData
}
mockResponse = mockResponseData(request);
});

it('interpretResponse: empty data request', () => {
delete mockResponse['body']
const data = spec.interpretResponse(mockResponse, mockBidRequest);
expect(data.length).to.be.equal(0);
});

it('interpretResponse: response data and convert data arrays has same length', () => {
const keys = Object.keys(mockResponse.body);
const data = spec.interpretResponse(mockResponse, mockBidRequest);
expect(data.length).to.be.equal(keys.length);
});

it('interpretResponse: convert to correct data', () => {
const keys = Object.keys(mockResponse.body);
const data = spec.interpretResponse(mockResponse, mockBidRequest);

data.forEach((responseItem, index) => {
expect(responseItem.ad).to.be.equal(mockResponse.body[keys[index]].ad);
expect(responseItem.cpm).to.be.equal(mockResponse.body[keys[index]].cpm);
expect(responseItem.creativeId).to.be.equal(mockResponse.body[keys[index]].creativeId);
expect(responseItem.currency).to.be.equal(mockResponse.body[keys[index]].currency);
expect(responseItem.netRevenue).to.be.true;
expect(responseItem.ttl).to.be.equal(60);
expect(responseItem.requestId).to.be.equal(mockBidRequest.data[index].bidId);
expect(responseItem.width).to.be.equal(mockResponse.body[keys[index]].width);
expect(responseItem.height).to.be.equal(mockResponse.body[keys[index]].height);
});
});
});

0 comments on commit 45bf543

Please sign in to comment.