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

GrowAdvertising: add native support #7126

Merged
merged 4 commits into from
Jul 9, 2021
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
70 changes: 58 additions & 12 deletions modules/growadvertisingBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@

import * as utils from '../src/utils.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {BANNER, NATIVE} from '../src/mediaTypes.js';
import {triggerPixel} from '../src/utils.js';

const BIDDER_CODE = 'growads';

export const spec = {
code: BIDDER_CODE,
supportedMediaTypes: [BANNER, NATIVE],

isBidRequestValid: function (bid) {
return bid.params && !!bid.params.zoneId;
Expand Down Expand Up @@ -59,6 +62,7 @@ export const spec = {
let isCorrectCPM = true;
let minCPM;
let maxCPM;
let bid = {};

let body = serverResponse.body;

Expand Down Expand Up @@ -86,32 +90,74 @@ export const spec = {
isCorrectCPM = false;
}

// Ensure that response ad matches one of the placement sizes.
utils._each(utils.deepAccess(request, 'mediaTypes.banner.sizes', []), function (size) {
if (width === size[0] && height === size[1]) {
isCorrectSize = true;
}
});

if (isCorrectCPM && isCorrectSize) {
bidResponses.push({
if (isCorrectCPM) {
bid = {
requestId: request.bidId,
bidderCode: request.bidder,
creativeId: response.creativeId,
cpm: CPM,
width: width,
height: height,
ad: response.ad,
currency: response.currency,
netRevenue: true,
ttl: response.ttl,
adUnitCode: request.adUnitCode,
referrer: utils.deepAccess(request, 'refererInfo.referer')
});
};

if (response.hasOwnProperty(NATIVE)) {
bid[NATIVE] = {
title: response[NATIVE].title,
body: response[NATIVE].body,
body2: response[NATIVE].body2,
cta: response[NATIVE].cta,
sponsoredBy: response[NATIVE].sponsoredBy,
clickUrl: response[NATIVE].clickUrl,
impressionTrackers: response[NATIVE].impressionTrackers,
};

if (response[NATIVE].image) {
bid[NATIVE].image = {
url: response[NATIVE].image.url,
height: response[NATIVE].image.height,
width: response[NATIVE].image.width
};
}

if (response[NATIVE].icon) {
bid[NATIVE].icon = {
url: response[NATIVE].icon.url,
height: response[NATIVE].icon.height,
width: response[NATIVE].icon.width
};
}
bid.mediaType = NATIVE;
isCorrectSize = true;
} else {
bid.ad = response.ad;
bid.mediaType = BANNER;
// Ensure that response ad matches one of the placement sizes.
utils._each(utils.deepAccess(request, 'mediaTypes.banner.sizes', []), function (size) {
if (width === size[0] && height === size[1]) {
isCorrectSize = true;
}
});
}

if (isCorrectSize) {
bidResponses.push(bid);
}
}
}

return bidResponses;
}
},

onBidWon: function (bid) {
if (bid.vurl) {
triggerPixel(bid.vurl);
}
},
};

registerBidder(spec);
32 changes: 31 additions & 1 deletion modules/growadvertisingBidAdapter.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,36 @@ var adUnits = [
}
}
]
}
},
// Native adUnit
{
code: 'native-div',
sizes: [[1, 1]],
mediaTypes: {
native: {
title: {
required: true
},
body: {
required: true
},
image: {
required: true
},
sponsoredBy: {
required: true
},
}
},
bids: [
{
bidder: 'growads',
params: {
zoneId: 'YpQobqT-vEybhHx-1qaNMFx-Wj3Kwc2',
domain: 'native-test.growadvertising.com'
}
}
]
},
];
```
125 changes: 96 additions & 29 deletions test/spec/modules/growadvertisingBidAdapter_spec.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,46 @@
import { expect } from 'chai';
import { spec } from 'modules/growadvertisingBidAdapter.js';
import * as utils from '../../../src/utils.js';
import {BANNER, NATIVE} from '../../../src/mediaTypes.js';

describe('GrowAdvertising Adapter', function() {
const ZONE_ID = 'unique-zone-id';
const serverResponse = {
const serverResponseBanner = {
body: {
status: 'success',
width: 300,
height: 250,
creativeId: 'ULqaukILu0RnMa0FyidOtkji4Po3qbgQ9ceRVGlhjLLKnrrLAATmGNCwtE99Ems8',
ad: '<img src="http://image.source.com/img" alt="" title="" width="300" height="250" />',
ad: '<img src="https://image.source.com/img" alt="" title="" width="300" height="250" />',
cpm: 1,
ttl: 180,
currency: 'USD',
type: BANNER,
}
};
const serverResponseNative = {
body: {
status: 'success',
width: 400,
height: 300,
creativeId: 'ULqaukILu0RnMa0FyidOtkji4Po3qbgQ9ceRVGlhjLLKnrrLAATmGNCwtE99Ems9',
cpm: 2,
ttl: 180,
currency: 'USD',
native: {
title: 'Test title',
body: 'Test body',
body2: null,
sponsoredBy: 'Sponsored by',
cta: null,
clickUrl: 'https://example.org',
image: {
width: 400,
height: 300,
url: 'https://image.source.com/img',
}
},
type: NATIVE
}
};
let bidRequests = [];
Expand All @@ -32,6 +59,25 @@ describe('GrowAdvertising Adapter', function() {
sizes: [[300, 250], [300, 600]],
},
},
},
{
bidder: 'growads',
params: {
zoneId: ZONE_ID,
},
mediaTypes: {
native: {
title: {
required: true
},
image: {
required: true
},
sponsoredBy: {
required: true
}
},
},
}
];
});
Expand Down Expand Up @@ -122,39 +168,60 @@ describe('GrowAdvertising Adapter', function() {
});

describe('bid responses', function () {
it('should return complete bid response', function () {
let bids = spec.interpretResponse(serverResponse, {bidRequest: bidRequests[0]});

expect(bids).to.be.lengthOf(1);
expect(bids[0].bidderCode).to.equal('growads');
expect(bids[0].cpm).to.equal(1);
expect(bids[0].width).to.equal(300);
expect(bids[0].height).to.equal(250);
expect(bids[0].creativeId).to.have.length.above(1);
expect(bids[0].ad).to.have.length.above(1);
});
describe(BANNER, function () {
it('should return complete bid response banner', function () {
let bids = spec.interpretResponse(serverResponseBanner, {bidRequest: bidRequests[0]});

expect(bids).to.be.lengthOf(1);
expect(bids[0].bidderCode).to.equal('growads');
expect(bids[0].cpm).to.equal(1);
expect(bids[0].width).to.equal(300);
expect(bids[0].height).to.equal(250);
expect(bids[0].creativeId).to.have.length.above(1);
expect(bids[0].ad).to.have.length.above(1);
expect(bids[0].mediaType).to.equal(BANNER);
});

it('should return empty bid on incorrect size', function () {
let response = utils.mergeDeep(serverResponse, {
body: {
width: 150,
height: 150
}
it('should return empty bid on incorrect size', function () {
let response = utils.mergeDeep(serverResponseBanner, {
body: {
width: 150,
height: 150
}
});

let bids = spec.interpretResponse(response, {bidRequest: bidRequests[0]});
expect([]).to.be.lengthOf(0);
});

let bids = spec.interpretResponse(response, {bidRequest: bidRequests[0]});
expect([]).to.be.lengthOf(0);
});
it('should return empty bid on incorrect CPM', function () {
let response = utils.mergeDeep(serverResponseBanner, {
body: {
cpm: 10
}
});

it('should return empty bid on incorrect CPM', function () {
let response = utils.mergeDeep(serverResponse, {
body: {
cpm: 10
}
let bids = spec.interpretResponse(response, {bidRequest: bidRequests[0]});
expect([]).to.be.lengthOf(0);
});
});

let bids = spec.interpretResponse(response, {bidRequest: bidRequests[0]});
expect([]).to.be.lengthOf(0);
describe(NATIVE, function () {
it('should return complete bid response banner', function () {
let bids = spec.interpretResponse(serverResponseNative, {bidRequest: bidRequests[1]});

expect(bids).to.be.lengthOf(1);
expect(bids[0].bidderCode).to.equal('growads');
expect(bids[0].cpm).to.equal(2);
expect(bids[0].width).to.equal(400);
expect(bids[0].height).to.equal(300);
expect(bids[0].creativeId).to.have.length.above(1);
expect(bids[0]).property('native');
expect(bids[0].native.title).to.have.length.above(1);
expect(bids[0].native.body).to.have.length.above(1);
expect(bids[0].native).property('image');
expect(bids[0].mediaType).to.equal(NATIVE);
});
});
});
});
Expand Down