Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SmartyTech Bid Adapter : initial adapter release #9196

Merged
merged 6 commits into from
Nov 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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);
});
});
});