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

Equativ Bid Adapter: support native bid requests #12566

Merged
merged 63 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
2f8a35c
add support of dsa
eszponder Aug 19, 2024
3120efd
Merge pull request #27 from smartadserver/dsa-2
eszponder Aug 19, 2024
9483a81
restore topics
eszponder Aug 19, 2024
5e04eae
Merge pull request #28 from smartadserver/dsa-2
eszponder Aug 19, 2024
6acff45
DSA fix for UT
eszponder Aug 20, 2024
55bbc9d
Merge pull request #29 from smartadserver/dsa-2
eszponder Aug 20, 2024
a0e1efe
Merge branch 'prebid:master' into master
krzysztofequativ Sep 2, 2024
b03579d
Merge branch 'prebid:master' into master
krzysztofequativ Sep 11, 2024
f618679
Merge branch 'prebid:master' into master
krzysztofequativ Oct 14, 2024
d5a3178
drafy of adapter
krzysztofequativ Sep 11, 2024
92091d4
fixes after dev test
krzysztofequativ Sep 12, 2024
23eac33
make world simpler
krzysztofequativ Sep 12, 2024
3a5eda0
fix prev commit
krzysztofequativ Sep 12, 2024
86a7845
return empty userSyncs array by default
krzysztofequativ Sep 12, 2024
52752e7
adjustments
janzych-smart Sep 16, 2024
b75a5c2
apply prettier
janzych-smart Sep 16, 2024
9ec6fe4
unit tests for Equativ adapter
janzych-smart Sep 17, 2024
259cba2
add dsp user sync
krzysztofequativ Sep 20, 2024
9a92f9d
add readme
krzysztofequativ Sep 20, 2024
811932c
body can be undef
krzysztofequativ Sep 20, 2024
ae67b8a
support additional br params
krzysztofequativ Sep 25, 2024
bc4e78a
remove user sync
krzysztofequativ Sep 27, 2024
3148ed8
do not send dt param
krzysztofequativ Oct 8, 2024
f08f05d
handle floors and network id
krzysztofequativ Oct 9, 2024
3fac9a9
handle empty media types
krzysztofequativ Oct 10, 2024
e65525d
get min floor
krzysztofequativ Oct 15, 2024
9ce2bc2
fix desc for u.t.
krzysztofequativ Oct 16, 2024
fb9b893
better name for u.t.
krzysztofequativ Oct 16, 2024
9f9c133
add u.t. for not supported media type
krzysztofequativ Oct 16, 2024
08e3c52
improve currency u.t.
krzysztofequativ Oct 16, 2024
0bc782c
updates after pr review
krzysztofequativ Oct 25, 2024
c0990eb
SADR-6484: initial video setup for new PBJS adapter
jefftmahoney Oct 25, 2024
19b147c
SADR-6484: Adding logging requirement missed earlier
jefftmahoney Oct 28, 2024
3a6c723
SADR-6484: handle ext.rewarded prop for video with new oRTBConverter
jefftmahoney Oct 29, 2024
c1a2e63
SADR-6484: test revision + not sending bid requests where video obj i…
jefftmahoney Oct 30, 2024
3bfac49
resolving merge conflicts
jefftmahoney Nov 4, 2024
0f1d815
Merge branch 'master' into SADR-6484
krzysztofequativ Nov 13, 2024
578f79f
Merge branch 'master' of https://github.com/smartadserver/Prebid.js
jefftmahoney Nov 14, 2024
4be5f71
refactoring and u.t.
krzysztofequativ Nov 15, 2024
4f400c3
rename variable
krzysztofequativ Nov 18, 2024
1b74710
Equativ: SADR-6615: adding unit tests for and additional logging to b…
jefftmahoney Nov 22, 2024
e95f8b4
revert changes rel. to test endpoint
krzysztofequativ Nov 27, 2024
f35f424
revert changes rel. to test endpoint
krzysztofequativ Nov 27, 2024
65905e0
Merge pull request #34 from smartadserver/SADR-6484
krzysztofequativ Nov 27, 2024
28a1e74
split imp[0] into seperate requests and fix u.t.
krzysztofequativ Nov 29, 2024
9aae66c
Merge pull request #37 from smartadserver/split-imp
eszponder Dec 3, 2024
e081bf3
Merge branch 'master' into master
jefftmahoney Dec 3, 2024
33e2c3c
Equativ bid adapter: adding support for native media type
jefftmahoney Dec 4, 2024
14d5e6d
Resolve merge conflicts
jefftmahoney Dec 4, 2024
1b3f249
Resolving merge conflicts
jefftmahoney Dec 4, 2024
ef71a28
Equativ bid adapter: update unit test for native-support work
jefftmahoney Dec 4, 2024
f3dc7c7
Merge branch 'prebid:master' into master
krzysztofequativ Dec 5, 2024
78a32de
Equativ bid adapter: removing console.log from unit test file
jefftmahoney Dec 9, 2024
716423c
Merge branch 'master' of https://github.com/smartadserver/Prebid.js
jefftmahoney Dec 9, 2024
f309940
Equativ bid adapter: clarifying refinements regarding native-request …
jefftmahoney Dec 10, 2024
0208c9e
Merge pull request #38 from smartadserver/SADR-6615
jefftmahoney Dec 10, 2024
b3d9086
Merge branch 'master' of https://github.com/smartadserver/Prebid.js
jefftmahoney Dec 10, 2024
f7109f8
Merge branch 'prebid:master' into master
jefftmahoney Dec 10, 2024
29161bb
Merge branch 'master' of https://github.com/smartadserver/Prebid.js
jefftmahoney Dec 10, 2024
4cd1038
Equativ Bid Adapter: updating unit tests for native requests
jefftmahoney Dec 10, 2024
2337165
Merge pull request #39 from smartadserver/SADR-6615
jefftmahoney Dec 10, 2024
786cfde
Merge branch 'master' of https://github.com/smartadserver/Prebid.js
jefftmahoney Dec 11, 2024
12f1f17
PR feedback
jefftmahoney Dec 11, 2024
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
33 changes: 22 additions & 11 deletions modules/equativBidAdapter.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { config } from '../src/config.js';
import { BANNER, VIDEO } from '../src/mediaTypes.js';
import { getBidFloor } from '../libraries/equativUtils/equativUtils.js'
import { getStorageManager } from '../src/storageManager.js';

import { getBidFloor } from '../libraries/equativUtils/equativUtils.js';
import { ortbConverter } from '../libraries/ortbConverter/converter.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { config } from '../src/config.js';
import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js';
import { getStorageManager } from '../src/storageManager.js';
import { deepAccess, deepSetValue, logError, logWarn, mergeDeep } from '../src/utils.js';

/**
Expand All @@ -18,22 +19,22 @@ const LOG_PREFIX = 'Equativ:';
const PID_COOKIE_NAME = 'eqt_pid';

/**
* Evaluates a bid request for validity. Returns false if the
* request contains a video media type with no properties, true
* otherwise.
* Evaluates impressions for validity. The entry evaluated is considered valid if NEITHER of these conditions are met:
* 1) it has a `video` property defined for `mediaTypes.video` which is an empty object
* 2) it has a `native` property defined for `mediaTypes.native` which is an empty object
* @param {*} bidReq A bid request object to evaluate
* @returns boolean
*/
function isValid(bidReq) {
return !(bidReq.mediaTypes.video && JSON.stringify(bidReq.mediaTypes.video) === '{}');
return !(bidReq.mediaTypes.video && JSON.stringify(bidReq.mediaTypes.video) === '{}') && !(bidReq.mediaTypes.native && JSON.stringify(bidReq.mediaTypes.native) === '{}');
}

export const storage = getStorageManager({ bidderCode: BIDDER_CODE });

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

/**
* @param bidRequests
Expand All @@ -42,7 +43,7 @@ export const spec = {
*/
buildRequests: (bidRequests, bidderRequest) => {
if (bidRequests.filter(isValid).length === 0) {
logError(`${LOG_PREFIX} No useful bid requests to process. No request will be sent.`, bidRequests);
logError(`${LOG_PREFIX} No useful bid requests to process. No requests will be sent.`, bidRequests);
return undefined;
}

Expand Down Expand Up @@ -121,7 +122,6 @@ export const converter = ortbConverter({

imp.bidfloor = imp.bidfloor || getBidFloor(bidRequest, config.getConfig('currency.adServerCurrency'), mediaType);
imp.secure = 1;

imp.tagid = bidRequest.adUnitCode;

if (!deepAccess(bidRequest, 'ortb2Imp.rwdd') && deepAccess(bidRequest, 'mediaTypes.video.ext.rewarded')) {
Expand Down Expand Up @@ -151,6 +151,17 @@ export const converter = ortbConverter({
});
}

// "assets" is not included as a property to check here because the
// ortbConverter library checks for it already and will skip processing
// the request if it is missing
if (deepAccess(bid, 'mediaTypes.native')) {
['privacy', 'plcmttype', 'eventtrackers'].forEach(prop => {
if (!bid.mediaTypes.native.ortb[prop]) {
logWarn(`${LOG_PREFIX} Property "${prop}" is missing from request. Request will proceed, but the use of ${prop} for native requests is strongly encouraged.`, bid);
}
});
}

const pid = storage.getCookie(PID_COOKIE_NAME);
if (pid) {
deepSetValue(req, 'user.buyeruid', pid);
Expand Down
160 changes: 158 additions & 2 deletions test/spec/modules/equativBidAdapter_spec.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { BANNER } from 'src/mediaTypes.js';
import { getBidFloor } from 'libraries/equativUtils/equativUtils.js'
import { getBidFloor } from 'libraries/equativUtils/equativUtils.js';
import { converter, spec, storage } from 'modules/equativBidAdapter.js';
import { BANNER } from 'src/mediaTypes.js';
import * as utils from '../../../src/utils.js';

describe('Equativ bid adapter tests', () => {
Expand Down Expand Up @@ -78,6 +78,64 @@ describe('Equativ bid adapter tests', () => {
}
];

const nativeOrtbRequest = {
assets: [{
id: 0,
required: 1,
title: {
len: 140
}
},
{
id: 1,
required: 1,
img: {
type: 3,
w: 300,
h: 600
}
},
{
id: 2,
required: 1,
data: {
type: 1
}
}],
context: 1,
eventtrackers: [{
event: 1,
methods: [1, 2]
}],
plcmttype: 1,
privacy: 1,
ver: '1.2',
};
const DEFAULT_NATIVE_BID_REQUESTS = [
{
adUnitCode: 'equativ_native_42',
bidId: 'equativ_native_bidid_42',
mediaTypes: {
native: {
ortb: {
...nativeOrtbRequest
}
},
},
nativeOrtbRequest,
bidder: 'equativ',
params: {
networkId: 777,
},
requestId: 'equativ_native_reqid_42',
ortb2Imp: {
ext: {
tid: 'equativ_native_tid_42',
},
},
}
];

const DEFAULT_BANNER_BIDDER_REQUEST = {
bidderCode: 'equativ',
bids: DEFAULT_BANNER_BID_REQUESTS,
Expand All @@ -88,6 +146,11 @@ describe('Equativ bid adapter tests', () => {
bids: DEFAULT_VIDEO_BID_REQUESTS,
};

const DEFAULT_NATIVE_BIDDER_REQUEST = {
bidderCode: 'equativ',
bids: DEFAULT_NATIVE_BID_REQUESTS,
};

const SAMPLE_RESPONSE = {
body: {
id: '12h712u7-k22g-8124-ab7a-h268s22dy271',
Expand Down Expand Up @@ -495,6 +558,99 @@ describe('Equativ bid adapter tests', () => {
expect(utils.logError.args[0][0]).to.satisfy(arg => arg.includes('No request'));
expect(request).to.be.undefined;
});

it('should build a native request properly under normal circumstances', () => {
if (FEATURES.NATIVE) {
// ASSEMBLE
const expectedResult = true;

// ACT
const request = spec.buildRequests(DEFAULT_NATIVE_BID_REQUESTS, {})[0].data;

// ASSERT
expect(request.imp[0]).to.have.property('native');

const nativeObj = request.imp[0].native;
expect(nativeObj).to.have.property('ver').and.to.equal('1.2');
expect(nativeObj).to.have.property('request').and.to.be.a('string');

const requestObj = JSON.parse(nativeObj.request);
expect(requestObj).to.have.property('assets').and.to.be.an('array');
expect(requestObj).to.have.property('eventtrackers').and.to.be.an('array');
expect(requestObj).to.have.property('plcmttype').and.to.equal(1);
expect(requestObj).to.have.property('privacy').and.to.equal(1);
expect(requestObj).to.have.property('ver').and.to.equal('1.2');
}
});

it('should not send a native request when it has an empty body and no other impressions with any media types are defined', () => {
if (FEATURES.NATIVE) {
// ASSEMBLE
const emptyNativeRequest = {
...DEFAULT_NATIVE_BID_REQUESTS[0],
mediaTypes: {
native: {}
}
};
const bidRequests = [ emptyNativeRequest ];
const bidderRequest = { ...DEFAULT_NATIVE_BIDDER_REQUEST, bids: bidRequests };

// ACT
const request = spec.buildRequests(bidRequests, bidderRequest);

// ASSERT
expect(utils.logError.calledOnce).to.equal(true);
expect(utils.logError.args[0][0]).to.satisfy(arg => arg.includes('No request'));
expect(request).to.be.undefined;
}
});

it('should warn about missing "assets" property for native requests', () => {
if (FEATURES.NATIVE) {
// ASSEMBLE
const missingRequiredNativeRequest = DEFAULT_NATIVE_BID_REQUESTS[0];

// removing just "assets" for this test
delete missingRequiredNativeRequest.nativeOrtbRequest.assets;
const bidRequests = [ missingRequiredNativeRequest ];
const bidderRequest = { ...DEFAULT_NATIVE_BIDDER_REQUEST, bids: bidRequests };

// this value comes from native.js, part of the ortbConverter library
const warningMsgFromLibrary = 'mediaTypes.native is set, but no assets were specified. Native request skipped.'

// ACT
spec.buildRequests(bidRequests, bidderRequest);

// ASSERT
expect(utils.logWarn.callCount).to.equal(1)
expect(utils.logWarn.getCall(0).args[0]).to.satisfy(arg => arg.includes(warningMsgFromLibrary));
}
});

it('should warn about other missing required properties for native requests', () => {
if (FEATURES.NATIVE) {
// ASSEMBLE
const missingRequiredNativeRequest = DEFAULT_NATIVE_BID_REQUESTS[0];

// ortbConverter library will warn about missing assets; we supply warnings for these properties here
delete missingRequiredNativeRequest.mediaTypes.native.ortb.eventtrackers;
delete missingRequiredNativeRequest.mediaTypes.native.ortb.plcmttype;
delete missingRequiredNativeRequest.mediaTypes.native.ortb.privacy;

const bidRequests = [ missingRequiredNativeRequest ];
const bidderRequest = { ...DEFAULT_NATIVE_BIDDER_REQUEST, bids: bidRequests };

// ACT
spec.buildRequests(bidRequests, bidderRequest);

// ASSERT
expect(utils.logWarn.callCount).to.equal(4); // the first message, regarding missing assets, is supplied by the ortbConverter library
expect(utils.logWarn.getCall(0).args[0]).to.satisfy(arg => arg.includes('no assets were specified'));
expect(utils.logWarn.getCall(1).args[0]).to.satisfy(arg => arg.includes('"privacy" is missing'));
expect(utils.logWarn.getCall(2).args[0]).to.satisfy(arg => arg.includes('"plcmttype" is missing'));
expect(utils.logWarn.getCall(3).args[0]).to.satisfy(arg => arg.includes('"eventtrackers" is missing'));
}
});
});

describe('getBidFloor', () => {
Expand Down
Loading