Skip to content

Commit

Permalink
Feedad Bid Adapter: fixed usersync parsing (prebid#9353)
Browse files Browse the repository at this point in the history
* added file scaffold

* added isBidRequestValid implementation

* added local prototype of ad integration

* added implementation for placement ID validation

* fixed video context filter

* applied lint to feedad bid adapter

* added unit test for bid request validation

* added buildRequest unit test

* added unit tests for timeout and bid won callbacks

* updated bid request to FeedAd API

* added parsing of feedad api bid response

* added transmisison of tracking events to FeedAd Api

* code cleanup

* updated feedad unit tests for buildRequest method

* added unit tests for event tracking implementation

* added unit test for interpretResponse method

* added adapter documentation

* added dedicated feedad example page

* updated feedad adapter to use live system

* updated FeedAd adapter placement ID regex

* removed groups from FeedAd adapter placement ID regex

* removed dedicated feedad example page

* updated imports in FeedAd adapter file to use relative paths

* updated FeedAd adapter unit test to use sinon.useFakeXMLHttpRequest()

* added GDPR fields to the FeedAd bid request

* removed video from supported media types of the FeedAd adapter

* increased version code of FeedAd adapter to 1.0.2

* removed unnecessary check of bidder request

* fixed unit test testing for old FeedAd version

* removed video media type example from documentation file

* added gvlid to FeedAd adapter

* added decoration parameter to adapter documentation

* added pass through of additional bid parameters

* added user syncs to FeedAd bid adapter

* increased FeedAd bid adapter version

* lint pass over FeedAd bid adapter

* fixed parsing of user syncs from server response

* increased FeedAd bid adapter version

* fixed version code in test file
  • Loading branch information
couchcrew-thomas authored and jorgeluisrocha committed May 18, 2023
1 parent c231734 commit 4746d65
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 16 deletions.
14 changes: 11 additions & 3 deletions modules/feedadBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {ajax} from '../src/ajax.js';
* Version of the FeedAd bid adapter
* @type {string}
*/
const VERSION = '1.0.3';
const VERSION = '1.0.4';

/**
* @typedef {object} FeedAdApiBidRequest
Expand Down Expand Up @@ -294,12 +294,20 @@ function trackingHandlerFactory(klass) {
/**
* Reads the user syncs off the server responses and converts them into Prebid.JS format
* @param {SyncOptions} syncOptions
* @param {FeedAdApiBidResponse[]} serverResponses
* @param {ServerResponse[]} serverResponses
* @param gdprConsent
* @param uspConsent
*/
function getUserSyncs(syncOptions, serverResponses, gdprConsent, uspConsent) {
return serverResponses.map(response => response.ext)
return serverResponses.map(response => {
// validate response format
const ext = deepAccess(response, 'body.ext', []);
if (ext == null) {
return null;
}
return ext;
})
.filter(ext => ext != null)
.flatMap(extension => {
// extract user syncs from extension
const pixels = syncOptions.pixelEnabled && extension.pixels ? extension.pixels : [];
Expand Down
51 changes: 38 additions & 13 deletions test/spec/modules/feedadBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -358,14 +358,20 @@ describe('FeedAdAdapter', function () {
const pixelSync2 = {type: 'image', url: 'the pixel url 2'};
const iFrameSync1 = {type: 'iframe', url: 'the iFrame url 1'};
const iFrameSync2 = {type: 'iframe', url: 'the iFrame url 2'};
const mockServerResponse = (content) => {
if (!(content instanceof Array)) {
content = [content];
}
return content.map(it => ({body: it}));
};

it('should pass through the syncs out of the extension fields of the server response', function () {
const serverResponse = [{
const serverResponse = mockServerResponse([{
ext: {
pixels: [pixelSync1, pixelSync2],
iframes: [iFrameSync1, iFrameSync2],
}
}];
}]);
const result = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}, serverResponse)
expect(result).to.deep.equal([
pixelSync1,
Expand All @@ -376,7 +382,7 @@ describe('FeedAdAdapter', function () {
});

it('should concat the syncs of all responses', function () {
const serverResponse = [{
const serverResponse = mockServerResponse([{
ext: {
pixels: [pixelSync1],
iframes: [iFrameSync2],
Expand All @@ -391,7 +397,7 @@ describe('FeedAdAdapter', function () {
ext: {
pixels: [pixelSync2],
}
}];
}]);
const result = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}, serverResponse);
expect(result).to.deep.equal([
pixelSync1,
Expand All @@ -402,7 +408,7 @@ describe('FeedAdAdapter', function () {
});

it('should filter out duplicates', function () {
const serverResponse = [{
const serverResponse = mockServerResponse([{
ext: {
pixels: [pixelSync1, pixelSync1],
iframes: [iFrameSync2, iFrameSync2],
Expand All @@ -411,7 +417,7 @@ describe('FeedAdAdapter', function () {
ext: {
iframes: [iFrameSync2, iFrameSync2],
}
}];
}]);
const result = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}, serverResponse);
expect(result).to.deep.equal([
pixelSync1,
Expand All @@ -420,12 +426,12 @@ describe('FeedAdAdapter', function () {
});

it('should not include iFrame syncs if the option is disabled', function () {
const serverResponse = [{
const serverResponse = mockServerResponse([{
ext: {
pixels: [pixelSync1, pixelSync2],
iframes: [iFrameSync1, iFrameSync2],
}
}];
}]);
const result = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, serverResponse);
expect(result).to.deep.equal([
pixelSync1,
Expand All @@ -434,12 +440,12 @@ describe('FeedAdAdapter', function () {
});

it('should not include pixel syncs if the option is disabled', function () {
const serverResponse = [{
const serverResponse = mockServerResponse([{
ext: {
pixels: [pixelSync1, pixelSync2],
iframes: [iFrameSync1, iFrameSync2],
}
}];
}]);
const result = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: false}, serverResponse);
expect(result).to.deep.equal([
iFrameSync1,
Expand All @@ -448,15 +454,34 @@ describe('FeedAdAdapter', function () {
});

it('should not include any syncs if the sync options are disabled or missing', function () {
const serverResponse = [{
const serverResponse = mockServerResponse([{
ext: {
pixels: [pixelSync1, pixelSync2],
iframes: [iFrameSync1, iFrameSync2],
}
}];
}]);
const result = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: false}, serverResponse);
expect(result).to.deep.equal([]);
});

it('should handle empty responses', function () {
const serverResponse = mockServerResponse([]);
const result = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}, serverResponse)
expect(result).to.deep.equal([]);
});

it('should not throw if the server response is weird', function () {
const responses = [
mockServerResponse(null),
mockServerResponse('null'),
mockServerResponse(1234),
mockServerResponse({}),
mockServerResponse([{}, 123]),
];
responses.forEach(it => {
expect(() => spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}, it)).not.to.throw;
});
});
});

describe('event tracking calls', function () {
Expand Down Expand Up @@ -592,7 +617,7 @@ describe('FeedAdAdapter', function () {
prebid_bid_id: bidId,
prebid_transaction_id: transactionId,
referer,
sdk_version: '1.0.3'
sdk_version: '1.0.4'
};
subject(data);
expect(server.requests.length).to.equal(1);
Expand Down

0 comments on commit 4746d65

Please sign in to comment.