+
+
+
+ ]]>
+
+
+
ES
+
+
+ `;
+ let serverResponse = {
+ 'body': xmlStr1,
+ }
+ const bidResponses = spec.interpretResponse(serverResponse, bidRequest);
+ expect(bidResponses.length).to.equal(0);
+ })
+ it('It should return a banner ad.', () => {
+ let serverResponse = {
+ 'body': xmlStr,
+ }
+ setCurrentURL('https://www.sports.com');
+ const bidResponses = spec.interpretResponse(serverResponse, bidRequest);
+ expect(bidResponses.length).greaterThan(0);
+ expect(bidResponses[0].mediaType).to.be.equal(BANNER);
+ expect(bidResponses[0].ad).not.to.be.null;
+ })
+ it('It should return a video ad.', () => {
+ let serverResponse = {
+ 'body': xmlStr,
+ }
+ setCurrentURL('https://www.sports.com');
+ bidRequest.bidRequest.mediaTypes = {
+ video: {
+ sizes: [
+ [300, 250],
+ [300, 600]
+ ]
+ }
+ }
+ const bidResponses = spec.interpretResponse(serverResponse, bidRequest);
+ expect(bidResponses.length).greaterThan(0);
+ expect(bidResponses[0].mediaType).to.be.equal(VIDEO);
+ expect(bidResponses[0].vastUrl).not.to.be.null;
+ })
+ });
+});
diff --git a/test/spec/modules/contxtfulRtdProvider_spec.js b/test/spec/modules/contxtfulRtdProvider_spec.js
new file mode 100644
index 00000000000..541c0e6e6dd
--- /dev/null
+++ b/test/spec/modules/contxtfulRtdProvider_spec.js
@@ -0,0 +1,200 @@
+import { contxtfulSubmodule } from '../../../modules/contxtfulRtdProvider.js';
+import { expect } from 'chai';
+import { loadExternalScriptStub } from 'test/mocks/adloaderStub.js';
+
+import * as events from '../../../src/events';
+
+const _ = null;
+const VERSION = 'v1';
+const CUSTOMER = 'CUSTOMER';
+const CONTXTFUL_CONNECTOR_ENDPOINT = `https://api.receptivity.io/${VERSION}/prebid/${CUSTOMER}/connector/p.js`;
+const INITIAL_RECEPTIVITY = { ReceptivityState: 'INITIAL_RECEPTIVITY' };
+const INITIAL_RECEPTIVITY_EVENT = new CustomEvent('initialReceptivity', { detail: INITIAL_RECEPTIVITY });
+
+const CONTXTFUL_API = { GetReceptivity: sinon.stub() }
+const RX_ENGINE_IS_READY_EVENT = new CustomEvent('rxEngineIsReady', {detail: CONTXTFUL_API});
+
+function buildInitConfig(version, customer) {
+ return {
+ name: 'contxtful',
+ params: {
+ version,
+ customer,
+ },
+ };
+}
+
+describe('contxtfulRtdProvider', function () {
+ let sandbox = sinon.sandbox.create();
+ let loadExternalScriptTag;
+ let eventsEmitSpy;
+
+ beforeEach(() => {
+ loadExternalScriptTag = document.createElement('script');
+ loadExternalScriptStub.callsFake((_url, _moduleName) => loadExternalScriptTag);
+
+ CONTXTFUL_API.GetReceptivity.reset();
+
+ eventsEmitSpy = sandbox.spy(events, ['emit']);
+ });
+
+ afterEach(function () {
+ delete window.Contxtful;
+ sandbox.restore();
+ });
+
+ describe('extractParameters with invalid configuration', () => {
+ const {
+ params: { customer, version },
+ } = buildInitConfig(VERSION, CUSTOMER);
+ const theories = [
+ [
+ null,
+ 'params.version should be a non-empty string',
+ 'null object for config',
+ ],
+ [
+ {},
+ 'params.version should be a non-empty string',
+ 'empty object for config',
+ ],
+ [
+ { customer },
+ 'params.version should be a non-empty string',
+ 'customer only in config',
+ ],
+ [
+ { version },
+ 'params.customer should be a non-empty string',
+ 'version only in config',
+ ],
+ [
+ { customer, version: '' },
+ 'params.version should be a non-empty string',
+ 'empty string for version',
+ ],
+ [
+ { customer: '', version },
+ 'params.customer should be a non-empty string',
+ 'empty string for customer',
+ ],
+ [
+ { customer: '', version: '' },
+ 'params.version should be a non-empty string',
+ 'empty string for version & customer',
+ ],
+ ];
+
+ theories.forEach(([params, expectedErrorMessage, _description]) => {
+ const config = { name: 'contxtful', params };
+ it('throws the expected error', () => {
+ expect(() => contxtfulSubmodule.extractParameters(config)).to.throw(
+ expectedErrorMessage
+ );
+ });
+ });
+ });
+
+ describe('initialization with invalid config', function () {
+ it('returns false', () => {
+ expect(contxtfulSubmodule.init({})).to.be.false;
+ });
+ });
+
+ describe('initialization with valid config', function () {
+ it('returns true when initializing', () => {
+ const config = buildInitConfig(VERSION, CUSTOMER);
+ expect(contxtfulSubmodule.init(config)).to.be.true;
+ });
+
+ it('loads contxtful module script asynchronously', (done) => {
+ contxtfulSubmodule.init(buildInitConfig(VERSION, CUSTOMER));
+
+ setTimeout(() => {
+ expect(loadExternalScriptStub.calledOnce).to.be.true;
+ expect(loadExternalScriptStub.args[0][0]).to.equal(
+ CONTXTFUL_CONNECTOR_ENDPOINT
+ );
+ done();
+ }, 10);
+ });
+ });
+
+ describe('load external script return falsy', function () {
+ it('returns true when initializing', () => {
+ loadExternalScriptStub.callsFake(() => {});
+ const config = buildInitConfig(VERSION, CUSTOMER);
+ expect(contxtfulSubmodule.init(config)).to.be.true;
+ });
+ });
+
+ describe('rxEngine from external script', function () {
+ it('use rxEngine api to get receptivity', () => {
+ contxtfulSubmodule.init(buildInitConfig(VERSION, CUSTOMER));
+ loadExternalScriptTag.dispatchEvent(RX_ENGINE_IS_READY_EVENT);
+
+ contxtfulSubmodule.getTargetingData(['ad-slot']);
+
+ expect(CONTXTFUL_API.GetReceptivity.calledOnce).to.be.true;
+ });
+ });
+
+ describe('initial receptivity is not dispatched', function () {
+ it('does not initialize receptivity value', () => {
+ contxtfulSubmodule.init(buildInitConfig(VERSION, CUSTOMER));
+
+ let targetingData = contxtfulSubmodule.getTargetingData(['ad-slot']);
+ expect(targetingData).to.deep.equal({});
+ });
+ });
+
+ describe('initial receptivity is invalid', function () {
+ const theories = [
+ [new Event('initialReceptivity'), 'event without details'],
+ [new CustomEvent('initialReceptivity', { }), 'custom event without details'],
+ [new CustomEvent('initialReceptivity', { detail: {} }), 'custom event with invalid details'],
+ [new CustomEvent('initialReceptivity', { detail: { ReceptivityState: '' } }), 'custom event with details without ReceptivityState'],
+ ];
+
+ theories.forEach(([initialReceptivityEvent, _description]) => {
+ it('does not initialize receptivity value', () => {
+ contxtfulSubmodule.init(buildInitConfig(VERSION, CUSTOMER));
+ loadExternalScriptTag.dispatchEvent(initialReceptivityEvent);
+
+ let targetingData = contxtfulSubmodule.getTargetingData(['ad-slot']);
+ expect(targetingData).to.deep.equal({});
+ });
+ })
+ });
+
+ describe('getTargetingData', function () {
+ const theories = [
+ [undefined, {}, 'undefined ad-slots'],
+ [[], {}, 'empty ad-slots'],
+ [
+ ['ad-slot'],
+ { 'ad-slot': { ReceptivityState: 'INITIAL_RECEPTIVITY' } },
+ 'single ad-slot',
+ ],
+ [
+ ['ad-slot-1', 'ad-slot-2'],
+ {
+ 'ad-slot-1': { ReceptivityState: 'INITIAL_RECEPTIVITY' },
+ 'ad-slot-2': { ReceptivityState: 'INITIAL_RECEPTIVITY' },
+ },
+ 'many ad-slots',
+ ],
+ ];
+
+ theories.forEach(([adUnits, expected, _description]) => {
+ it('adds "ReceptivityState" to the adUnits', function () {
+ contxtfulSubmodule.init(buildInitConfig(VERSION, CUSTOMER));
+ loadExternalScriptTag.dispatchEvent(INITIAL_RECEPTIVITY_EVENT);
+
+ expect(contxtfulSubmodule.getTargetingData(adUnits)).to.deep.equal(
+ expected
+ );
+ });
+ });
+ });
+});
diff --git a/test/spec/modules/criteoBidAdapter_spec.js b/test/spec/modules/criteoBidAdapter_spec.js
index 9987df34f2b..36132fe963b 100755
--- a/test/spec/modules/criteoBidAdapter_spec.js
+++ b/test/spec/modules/criteoBidAdapter_spec.js
@@ -364,93 +364,6 @@ describe('The Criteo bidding adapter', function () {
});
it('should return false when given an invalid video bid request', function () {
- expect(spec.isBidRequestValid({
- bidder: 'criteo',
- mediaTypes: {
- video: {
- mimes: ['video/mpeg'],
- playerSize: [640, 480],
- protocols: [5, 6],
- maxduration: 30,
- api: [1, 2]
- }
- },
- params: {
- networkId: 456,
- video: {
- skip: 1,
- placement: 1,
- playbackmethod: 1
- }
- },
- })).to.equal(false);
-
- expect(spec.isBidRequestValid({
- bidder: 'criteo',
- mediaTypes: {
- video: {
- context: 'instream',
- mimes: ['video/mpeg'],
- playerSize: [640, 480],
- protocols: [5, 6],
- maxduration: 30,
- api: [1, 2]
- }
- },
- params: {
- networkId: 456,
- video: {
- skip: 1,
- placement: 2,
- playbackmethod: 1
- }
- },
- })).to.equal(false);
-
- expect(spec.isBidRequestValid({
- bidder: 'criteo',
- mediaTypes: {
- video: {
- context: 'outstream',
- mimes: ['video/mpeg'],
- playerSize: [640, 480],
- protocols: [5, 6],
- maxduration: 30,
- api: [1, 2]
- }
- },
- params: {
- networkId: 456,
- video: {
- skip: 1,
- placement: 1,
- playbackmethod: 1
- }
- },
- })).to.equal(false);
-
- expect(spec.isBidRequestValid({
- bidder: 'criteo',
- mediaTypes: {
- video: {
- context: 'adpod',
- mimes: ['video/mpeg'],
- playerSize: [640, 480],
- protocols: [5, 6],
- maxduration: 30,
- api: [1, 2]
- }
- },
- params: {
- networkId: 456,
- video: {
- skip: 1,
- placement: 1,
- playbackmethod: 1
- }
- },
- })).to.equal(false);
-
expect(spec.isBidRequestValid({
bidder: 'criteo',
mediaTypes: {
@@ -1993,6 +1906,22 @@ describe('The Criteo bidding adapter', function () {
const request = spec.buildRequests(bidRequests, bidderRequest);
expect(request.data.slots[0].ext).to.not.have.property('ae');
});
+
+ it('should properly transmit device.ext.cdep if available', function () {
+ const bidderRequest = {
+ ortb2: {
+ device: {
+ ext: {
+ cdep: 'cookieDeprecationLabel'
+ }
+ }
+ }
+ };
+ const bidRequests = [];
+ const request = spec.buildRequests(bidRequests, bidderRequest);
+ const ortbRequest = request.data;
+ expect(ortbRequest.device.ext.cdep).to.equal('cookieDeprecationLabel');
+ });
});
describe('interpretResponse', function () {
diff --git a/test/spec/modules/discoveryBidAdapter_spec.js b/test/spec/modules/discoveryBidAdapter_spec.js
index acfc519bef9..05216ff126c 100644
--- a/test/spec/modules/discoveryBidAdapter_spec.js
+++ b/test/spec/modules/discoveryBidAdapter_spec.js
@@ -1,5 +1,5 @@
import { expect } from 'chai';
-import { spec, getPmgUID, storage } from 'modules/discoveryBidAdapter.js';
+import { spec, getPmgUID, storage, getPageTitle, getPageDescription, getPageKeywords, getConnectionDownLink } from 'modules/discoveryBidAdapter.js';
import * as utils from 'src/utils.js';
describe('discovery:BidAdapterTests', function () {
@@ -218,3 +218,230 @@ describe('discovery:BidAdapterTests', function () {
});
});
});
+
+describe('discovery Bid Adapter Tests', function () {
+ describe('buildRequests', () => {
+ describe('getPageTitle function', function() {
+ let sandbox;
+
+ beforeEach(() => {
+ sandbox = sinon.createSandbox();
+ });
+
+ afterEach(() => {
+ sandbox.restore();
+ });
+
+ it('should return the top document title if available', function() {
+ const fakeTopDocument = {
+ title: 'Top Document Title',
+ querySelector: () => ({ content: 'Top Document Title test' })
+ };
+ const fakeTopWindow = {
+ document: fakeTopDocument
+ };
+ const result = getPageTitle({ top: fakeTopWindow });
+ expect(result).to.equal('Top Document Title');
+ });
+
+ it('should return the content of top og:title meta tag if title is empty', function() {
+ const ogTitleContent = 'Top OG Title Content';
+ const fakeTopWindow = {
+ document: {
+ title: '',
+ querySelector: sandbox.stub().withArgs('meta[property="og:title"]').returns({ content: ogTitleContent })
+ }
+ };
+
+ const result = getPageTitle({ top: fakeTopWindow });
+ expect(result).to.equal(ogTitleContent);
+ });
+
+ it('should return the document title if no og:title meta tag is present', function() {
+ document.title = 'Test Page Title';
+ sandbox.stub(document, 'querySelector').withArgs('meta[property="og:title"]').returns(null);
+
+ const result = getPageTitle({ top: undefined });
+ expect(result).to.equal('Test Page Title');
+ });
+
+ it('should return the content of og:title meta tag if present', function() {
+ document.title = '';
+ const ogTitleContent = 'Top OG Title Content';
+ sandbox.stub(document, 'querySelector').withArgs('meta[property="og:title"]').returns({ content: ogTitleContent });
+ const result = getPageTitle({ top: undefined });
+ expect(result).to.equal(ogTitleContent);
+ });
+
+ it('should return an empty string if no title or og:title meta tag is found', function() {
+ document.title = '';
+ sandbox.stub(document, 'querySelector').withArgs('meta[property="og:title"]').returns(null);
+ const result = getPageTitle({ top: undefined });
+ expect(result).to.equal('');
+ });
+
+ it('should handle exceptions when accessing top.document and fallback to current document', function() {
+ const fakeWindow = {
+ get top() {
+ throw new Error('Access denied');
+ }
+ };
+ const ogTitleContent = 'Current OG Title Content';
+ document.title = 'Current Document Title';
+ sandbox.stub(document, 'querySelector').withArgs('meta[property="og:title"]').returns({ content: ogTitleContent });
+ const result = getPageTitle(fakeWindow);
+ expect(result).to.equal('Current Document Title');
+ });
+ });
+
+ describe('getPageDescription function', function() {
+ let sandbox;
+
+ beforeEach(() => {
+ sandbox = sinon.createSandbox();
+ });
+
+ afterEach(() => {
+ sandbox.restore();
+ });
+
+ it('should return the top document description if available', function() {
+ const descriptionContent = 'Top Document Description';
+ const fakeTopDocument = {
+ querySelector: sandbox.stub().withArgs('meta[name="description"]').returns({ content: descriptionContent })
+ };
+ const fakeTopWindow = { document: fakeTopDocument };
+ const result = getPageDescription({ top: fakeTopWindow });
+ expect(result).to.equal(descriptionContent);
+ });
+
+ it('should return the top document og:description if description is not present', function() {
+ const ogDescriptionContent = 'Top OG Description';
+ const fakeTopDocument = {
+ querySelector: sandbox.stub().withArgs('meta[property="og:description"]').returns({ content: ogDescriptionContent })
+ };
+ const fakeTopWindow = { document: fakeTopDocument };
+ const result = getPageDescription({ top: fakeTopWindow });
+ expect(result).to.equal(ogDescriptionContent);
+ });
+
+ it('should return the current document description if top document is not accessible', function() {
+ const descriptionContent = 'Current Document Description';
+ sandbox.stub(document, 'querySelector')
+ .withArgs('meta[name="description"]').returns({ content: descriptionContent })
+ const fakeWindow = {
+ get top() {
+ throw new Error('Access denied');
+ }
+ };
+ const result = getPageDescription(fakeWindow);
+ expect(result).to.equal(descriptionContent);
+ });
+
+ it('should return the current document og:description if description is not present and top document is not accessible', function() {
+ const ogDescriptionContent = 'Current OG Description';
+ sandbox.stub(document, 'querySelector')
+ .withArgs('meta[property="og:description"]').returns({ content: ogDescriptionContent });
+
+ const fakeWindow = {
+ get top() {
+ throw new Error('Access denied');
+ }
+ };
+ const result = getPageDescription(fakeWindow);
+ expect(result).to.equal(ogDescriptionContent);
+ });
+ });
+
+ describe('getPageKeywords function', function() {
+ let sandbox;
+
+ beforeEach(() => {
+ sandbox = sinon.createSandbox();
+ });
+
+ afterEach(() => {
+ sandbox.restore();
+ });
+
+ it('should return the top document keywords if available', function() {
+ const keywordsContent = 'keyword1, keyword2, keyword3';
+ const fakeTopDocument = {
+ querySelector: sandbox.stub()
+ .withArgs('meta[name="keywords"]').returns({ content: keywordsContent })
+ };
+ const fakeTopWindow = { document: fakeTopDocument };
+
+ const result = getPageKeywords({ top: fakeTopWindow });
+ expect(result).to.equal(keywordsContent);
+ });
+
+ it('should return the current document keywords if top document is not accessible', function() {
+ const keywordsContent = 'keyword1, keyword2, keyword3';
+ sandbox.stub(document, 'querySelector')
+ .withArgs('meta[name="keywords"]').returns({ content: keywordsContent });
+
+ // 模拟顶层窗口访问异常
+ const fakeWindow = {
+ get top() {
+ throw new Error('Access denied');
+ }
+ };
+
+ const result = getPageKeywords(fakeWindow);
+ expect(result).to.equal(keywordsContent);
+ });
+
+ it('should return an empty string if no keywords meta tag is found', function() {
+ sandbox.stub(document, 'querySelector').withArgs('meta[name="keywords"]').returns(null);
+
+ const result = getPageKeywords();
+ expect(result).to.equal('');
+ });
+ });
+ describe('getConnectionDownLink function', function() {
+ let sandbox;
+
+ beforeEach(() => {
+ sandbox = sinon.createSandbox();
+ });
+
+ afterEach(() => {
+ sandbox.restore();
+ });
+
+ it('should return the downlink value as a string if available', function() {
+ const downlinkValue = 2.5;
+ const fakeNavigator = {
+ connection: {
+ downlink: downlinkValue
+ }
+ };
+
+ const result = getConnectionDownLink({ navigator: fakeNavigator });
+ expect(result).to.equal(downlinkValue.toString());
+ });
+
+ it('should return undefined if downlink is not available', function() {
+ const fakeNavigator = {
+ connection: {}
+ };
+
+ const result = getConnectionDownLink({ navigator: fakeNavigator });
+ expect(result).to.be.undefined;
+ });
+
+ it('should return undefined if connection is not available', function() {
+ const fakeNavigator = {};
+
+ const result = getConnectionDownLink({ navigator: fakeNavigator });
+ expect(result).to.be.undefined;
+ });
+
+ it('should handle cases where navigator is not defined', function() {
+ const result = getConnectionDownLink({});
+ expect(result).to.be.undefined;
+ });
+ });
+ });
+});
diff --git a/test/spec/modules/dsp_genieeBidAdapter_spec.js b/test/spec/modules/dsp_genieeBidAdapter_spec.js
new file mode 100644
index 00000000000..94ec1011fbf
--- /dev/null
+++ b/test/spec/modules/dsp_genieeBidAdapter_spec.js
@@ -0,0 +1,173 @@
+import { expect } from 'chai';
+import { spec } from 'modules/dsp_genieeBidAdapter.js';
+import { config } from 'src/config';
+
+describe('Geniee adapter tests', () => {
+ const validBidderRequest = {
+ code: 'sample_request',
+ bids: [{
+ bidId: 'bid-id',
+ bidder: 'dsp_geniee',
+ params: {
+ test: 1
+ }
+ }],
+ gdprConsent: {
+ gdprApplies: false
+ },
+ uspConsent: '1YNY'
+ };
+
+ describe('isBidRequestValid function test', () => {
+ it('valid', () => {
+ expect(spec.isBidRequestValid(validBidderRequest.bids[0])).equal(true);
+ });
+ });
+ describe('buildRequests function test', () => {
+ it('auction', () => {
+ const request = spec.buildRequests(validBidderRequest.bids, validBidderRequest);
+ const auction_id = request.data.id;
+ expect(request).deep.equal({
+ method: 'POST',
+ url: 'https://rt.gsspat.jp/prebid_auction',
+ data: {
+ at: 1,
+ id: auction_id,
+ imp: [
+ {
+ ext: {
+ test: 1
+ },
+ id: 'bid-id'
+ }
+ ],
+ test: 1
+ },
+ });
+ });
+ it('uncomfortable (gdpr)', () => {
+ validBidderRequest.gdprConsent.gdprApplies = true;
+ const request = spec.buildRequests(validBidderRequest.bids, validBidderRequest);
+ expect(request).deep.equal({
+ method: 'GET',
+ url: 'https://rt.gsspat.jp/prebid_uncomfortable',
+ });
+ validBidderRequest.gdprConsent.gdprApplies = false;
+ });
+ it('uncomfortable (usp)', () => {
+ validBidderRequest.uspConsent = '1YYY';
+ const request = spec.buildRequests(validBidderRequest.bids, validBidderRequest);
+ expect(request).deep.equal({
+ method: 'GET',
+ url: 'https://rt.gsspat.jp/prebid_uncomfortable',
+ });
+ validBidderRequest.uspConsent = '1YNY';
+ });
+ it('uncomfortable (coppa)', () => {
+ config.setConfig({ coppa: true });
+ const request = spec.buildRequests(validBidderRequest.bids, validBidderRequest);
+ expect(request).deep.equal({
+ method: 'GET',
+ url: 'https://rt.gsspat.jp/prebid_uncomfortable',
+ });
+ config.resetConfig();
+ });
+ it('uncomfortable (currency)', () => {
+ config.setConfig({ currency: { adServerCurrency: 'TWD' } });
+ const request = spec.buildRequests(validBidderRequest.bids, validBidderRequest);
+ expect(request).deep.equal({
+ method: 'GET',
+ url: 'https://rt.gsspat.jp/prebid_uncomfortable',
+ });
+ config.resetConfig();
+ });
+ });
+ describe('interpretResponse function test', () => {
+ it('sample bid', () => {
+ const request = spec.buildRequests(validBidderRequest.bids, validBidderRequest);
+ const auction_id = request.data.id;
+ const adm = "\n";
+ const serverResponse = {
+ body: {
+ id: auction_id,
+ cur: 'JPY',
+ seatbid: [{
+ bid: [{
+ id: '7b77235d599e06d289e58ddfa9390443e22d7071',
+ impid: 'bid-id',
+ price: 0.6666000000000001,
+ adid: '8405715',
+ adm: adm,
+ adomain: ['geniee.co.jp'],
+ iurl: 'http://img.gsspat.jp/e/068c8e1eafbf0cb6ac1ee95c36152bd2/04f4bd4e6b71f978d343d84ecede3877.png',
+ cid: '8405715',
+ crid: '1383823',
+ cat: ['IAB1'],
+ w: 300,
+ h: 250,
+ mtype: 1
+ }]
+ }]
+ }
+ };
+ const bids = spec.interpretResponse(serverResponse, request);
+ expect(bids).deep.equal([{
+ ad: adm,
+ cpm: 0.6666000000000001,
+ creativeId: '1383823',
+ creative_id: '1383823',
+ height: 250,
+ width: 300,
+ currency: 'JPY',
+ mediaType: 'banner',
+ meta: {
+ advertiserDomains: ['geniee.co.jp']
+ },
+ netRevenue: true,
+ requestId: 'bid-id',
+ seatBidId: '7b77235d599e06d289e58ddfa9390443e22d7071',
+ ttl: 300
+ }]);
+ });
+ it('no bid', () => {
+ const serverResponse = {};
+ const bids = spec.interpretResponse(serverResponse, validBidderRequest);
+ expect(bids).deep.equal([]);
+ });
+ });
+ describe('getUserSyncs function test', () => {
+ it('sync enabled', () => {
+ const syncOptions = {
+ iframeEnabled: true,
+ pixelEnabled: true
+ };
+ const serverResponses = [];
+ const syncs = spec.getUserSyncs(syncOptions, serverResponses);
+ expect(syncs).deep.equal([{
+ type: 'image',
+ url: 'https://rt.gsspat.jp/prebid_cs'
+ }]);
+ });
+ it('sync disabled (option false)', () => {
+ const syncOptions = {
+ iframeEnabled: false,
+ pixelEnabled: false
+ };
+ const serverResponses = [];
+ const syncs = spec.getUserSyncs(syncOptions, serverResponses);
+ expect(syncs).deep.equal([]);
+ });
+ it('sync disabled (gdpr)', () => {
+ const syncOptions = {
+ iframeEnabled: true,
+ pixelEnabled: true
+ };
+ const serverResponses = [];
+ const gdprConsent = {
+ gdprApplies: true
+ };
+ const syncs = spec.getUserSyncs(syncOptions, serverResponses, gdprConsent);
+ expect(syncs).deep.equal([]);
+ });
+ });
+});
diff --git a/test/spec/modules/geoedgeRtdProvider_spec.js b/test/spec/modules/geoedgeRtdProvider_spec.js
index b0307a60a3c..211a3efa3c6 100644
--- a/test/spec/modules/geoedgeRtdProvider_spec.js
+++ b/test/spec/modules/geoedgeRtdProvider_spec.js
@@ -1,18 +1,21 @@
import * as utils from '../../../src/utils.js';
import {loadExternalScript} from '../../../src/adloader.js';
-import {
+import * as geoedgeRtdModule from '../../../modules/geoedgeRtdProvider.js';
+import {server} from '../../../test/mocks/xhr.js';
+import * as events from '../../../src/events.js';
+import CONSTANTS from '../../../src/constants.json';
+
+let {
geoedgeSubmodule,
getClientUrl,
getInPageUrl,
htmlPlaceholder,
setWrapper,
getMacros,
- wrapper,
- WRAPPER_URL
-} from '../../../modules/geoedgeRtdProvider.js';
-import {server} from '../../../test/mocks/xhr.js';
-import * as events from '../../../src/events.js';
-import CONSTANTS from '../../../src/constants.json';
+ WRAPPER_URL,
+ preloadClient,
+ markAsLoaded
+} = geoedgeRtdModule;
let key = '123123123';
function makeConfig(gpt) {
@@ -65,13 +68,11 @@ describe('Geoedge RTD module', function () {
});
});
describe('init', function () {
- let insertElementStub;
-
before(function () {
- insertElementStub = sinon.stub(utils, 'insertElement');
+ sinon.spy(geoedgeRtdModule, 'preloadClient');
});
after(function () {
- utils.insertElement.restore();
+ geoedgeRtdModule.preloadClient.restore();
});
it('should return false when missing params or key', function () {
let missingParams = geoedgeSubmodule.init({});
@@ -87,14 +88,13 @@ describe('Geoedge RTD module', function () {
let isWrapperRequest = request && request.url && request.url && request.url === WRAPPER_URL;
expect(isWrapperRequest).to.equal(true);
});
- it('should preload the client', function () {
- let isLinkPreloadAsScript = arg => arg.tagName === 'LINK' && arg.rel === 'preload' && arg.as === 'script' && arg.href === getClientUrl(key);
- expect(insertElementStub.calledWith(sinon.match(isLinkPreloadAsScript))).to.equal(true);
+ it('should call preloadClient', function () {
+ expect(preloadClient.called);
});
it('should emit billable events with applicable winning bids', function (done) {
let counter = 0;
events.on(CONSTANTS.EVENTS.BILLABLE_EVENT, function (event) {
- if (event.vendor === 'geoedge' && event.type === 'impression') {
+ if (event.vendor === geoedgeSubmodule.name && event.type === 'impression') {
counter += 1;
}
expect(counter).to.equal(1);
@@ -104,7 +104,7 @@ describe('Geoedge RTD module', function () {
});
it('should load the in page code when gpt params is true', function () {
geoedgeSubmodule.init(makeConfig(true));
- let isInPageUrl = arg => arg == getInPageUrl(key);
+ let isInPageUrl = arg => arg === getInPageUrl(key);
expect(loadExternalScript.calledWith(sinon.match(isInPageUrl))).to.equal(true);
});
it('should set the window.grumi config object when gpt params is true', function () {
@@ -112,10 +112,27 @@ describe('Geoedge RTD module', function () {
expect(hasGrumiObj && window.grumi.key === key && window.grumi.fromPrebid).to.equal(true);
});
});
+ describe('preloadClient', function () {
+ let iframe;
+ preloadClient(key);
+ let loadExternalScriptCall = loadExternalScript.getCall(0);
+ it('should create an invisible iframe and insert it to the DOM', function () {
+ iframe = document.getElementById('grumiFrame');
+ expect(iframe && iframe.style.display === 'none');
+ });
+ it('should assign params object to the iframe\'s window', function () {
+ let grumi = iframe.contentWindow.grumi;
+ expect(grumi.key).to.equal(key);
+ });
+ it('should preload the client into the iframe', function () {
+ let isClientUrl = arg => arg === getClientUrl(key);
+ expect(loadExternalScriptCall.calledWithMatch(isClientUrl)).to.equal(true);
+ });
+ });
describe('setWrapper', function () {
it('should set the wrapper', function () {
setWrapper(mockWrapper);
- expect(wrapper).to.equal(mockWrapper);
+ expect(geoedgeRtdModule.wrapper).to.equal(mockWrapper);
});
});
describe('getMacros', function () {
diff --git a/test/spec/modules/insticatorBidAdapter_spec.js b/test/spec/modules/insticatorBidAdapter_spec.js
index e24bcb3b455..36b6dd8fbf2 100644
--- a/test/spec/modules/insticatorBidAdapter_spec.js
+++ b/test/spec/modules/insticatorBidAdapter_spec.js
@@ -179,6 +179,43 @@ describe('InsticatorBidAdapter', function () {
}
})).to.be.false;
});
+
+ it('should return false if video plcmt is not a number', () => {
+ expect(spec.isBidRequestValid({
+ ...bidRequest,
+ ...{
+ mediaTypes: {
+ video: {
+ mimes: [
+ 'video/mp4',
+ 'video/mpeg',
+ ],
+ w: 250,
+ h: 300,
+ plcmt: 'NaN',
+ },
+ }
+ }
+ })).to.be.false;
+ });
+
+ it('should return true if playerSize is present instead of w and h', () => {
+ expect(spec.isBidRequestValid({
+ ...bidRequest,
+ ...{
+ mediaTypes: {
+ video: {
+ mimes: [
+ 'video/mp4',
+ 'video/mpeg',
+ ],
+ playerSize: [250, 300],
+ placement: 1,
+ },
+ }
+ }
+ })).to.be.true;
+ });
});
describe('buildRequests', function () {
@@ -570,4 +607,87 @@ describe('InsticatorBidAdapter', function () {
expect(spec.getUserSyncs({}, [response])).to.have.length(0);
})
});
+
+ describe('Response with video Instream', function () {
+ const bidRequestVid = {
+ method: 'POST',
+ url: 'https://ex.ingage.tech/v1/openrtb',
+ options: {
+ contentType: 'application/json',
+ withCredentials: true,
+ },
+ data: '',
+ bidderRequest: {
+ bidderRequestId: '22edbae2733bf6',
+ auctionId: '74f78609-a92d-4cf1-869f-1b244bbfb5d2',
+ timeout: 300,
+ bids: [
+ {
+ bidder: 'insticator',
+ params: {
+ adUnitId: '1a2b3c4d5e6f1a2b3c4d'
+ },
+ adUnitCode: 'adunit-code-1',
+ mediaTypes: {
+ video: {
+ mimes: [
+ 'video/mp4',
+ 'video/mpeg',
+ ],
+ playerSize: [[250, 300]],
+ placement: 2,
+ plcmt: 2,
+ }
+ },
+ bidId: 'bid1',
+ }
+ ]
+ }
+ };
+
+ const bidResponseVid = {
+ body: {
+ id: '22edbae2733bf6',
+ bidid: 'foo9876',
+ cur: 'USD',
+ seatbid: [
+ {
+ seat: 'some-dsp',
+ bid: [
+ {
+ ad: '
',
+ impid: 'bid1',
+ crid: 'crid1',
+ price: 0.5,
+ w: 300,
+ h: 250,
+ adm: '
',
+ exp: 60,
+ adomain: ['test1.com'],
+ ext: {
+ meta: {
+ test: 1
+ }
+ },
+ }
+ ],
+ },
+ ]
+ }
+ };
+ const bidRequestWithVideo = utils.deepClone(bidRequestVid);
+
+ it('should have related properties for video Instream', function() {
+ const serverResponseWithInstream = utils.deepClone(bidResponseVid);
+ serverResponseWithInstream.body.seatbid[0].bid[0].vastXml = '
';
+ serverResponseWithInstream.body.seatbid[0].bid[0].mediaType = 'video';
+ const bidResponse = spec.interpretResponse(serverResponseWithInstream, bidRequestWithVideo)[0];
+ expect(bidResponse).to.have.any.keys('mediaType', 'vastXml', 'vastUrl');
+ expect(bidResponse).to.have.property('mediaType', 'video');
+ expect(bidResponse.width).to.equal(300);
+ expect(bidResponse.height).to.equal(250);
+ expect(bidResponse).to.have.property('vastXml', '
');
+ expect(bidResponse.vastUrl).to.match(/^data:text\/xml;charset=utf-8;base64,[\w+/=]+$/)
+ });
+ })
});
diff --git a/test/spec/modules/liveIntentIdSystem_spec.js b/test/spec/modules/liveIntentIdSystem_spec.js
index 4af88e1a894..3af598c5d4e 100644
--- a/test/spec/modules/liveIntentIdSystem_spec.js
+++ b/test/spec/modules/liveIntentIdSystem_spec.js
@@ -94,6 +94,16 @@ describe('LiveIntentId', function() {
}, 200);
});
+ it('should initialize LiveConnect and forward the prebid version when decode and emit an event', function(done) {
+ liveIntentIdSubmodule.decode({}, { params: {
+ ...defaultConfigParams
+ }});
+ setTimeout(() => {
+ expect(server.requests[0].url).to.contain('tv=$prebid.version$')
+ done();
+ }, 200);
+ });
+
it('should initialize LiveConnect with the config params when decode and emit an event', function (done) {
liveIntentIdSubmodule.decode({}, { params: {
...defaultConfigParams.params,
diff --git a/test/spec/modules/pangleBidAdapter_spec.js b/test/spec/modules/pangleBidAdapter_spec.js
index 94f5a6e4b1d..6d8f9a66bcf 100644
--- a/test/spec/modules/pangleBidAdapter_spec.js
+++ b/test/spec/modules/pangleBidAdapter_spec.js
@@ -1,6 +1,5 @@
import { expect } from 'chai';
import { spec } from 'modules/pangleBidAdapter.js';
-import { logInfo } from '../../../src/utils';
const REQUEST = [{
adUnitCode: 'adUnitCode1',
@@ -84,6 +83,7 @@ const RESPONSE = {
'cat': [],
'w': 300,
'h': 250,
+ 'mtype': 1,
'ext': {
'prebid': {
'type': 'banner'
@@ -186,26 +186,6 @@ describe('pangle bid adapter', function () {
expect(deviceType).to.equal(2);
});
});
-
- // describe('video', function () {
- // it('video config', function() {
- // logInfo(spec.buildRequests(VIDEO_REQUEST, DEFAULT_OPTIONS)[0].data, 'spec.buildRequests(videoConfig, DEFAULT_OPTIONS)[0].data.imp[0]');
- // const request = spec.buildRequests(VIDEO_REQUEST, DEFAULT_OPTIONS)[0];
-
- // expect(request).to.exist.and.to.be.a('object');
- // const payload = request.data;
- // expect(payload).to.exist.and.to.be.a('object');
- // const video = payload.imp[0].video;
- // expect(video).to.exist.and.to.be.a('object');
- // // console.log(video, 'video???')
- // // expect(url).to.equal('https://pangle.pangleglobal.com/api/ad/union/web_js/common/get_ads');
- // // assert.deepEqual(video, {
- // // h: 380,
- // // mimes: ['video/mp4'],
- // // w: 240
- // // })
- // })
- // })
});
describe('Pangle Adapter with video', function() {
@@ -247,6 +227,7 @@ describe('Pangle Adapter with video', function() {
],
'w': 640,
'h': 640,
+ 'mtype': 1,
'ext': {
'pangle': {
'adtype': 8
@@ -293,3 +274,114 @@ describe('Pangle Adapter with video', function() {
});
});
});
+
+describe('pangle multi-format ads', function () {
+ const bidderRequest = {
+ refererInfo: {
+ referer: 'https://example.com'
+ }
+ };
+ const multiRequest = [
+ {
+ bidId: '2820132fe18114',
+ mediaTypes: { banner: { sizes: [[300, 250]] }, video: { context: 'outstream', playerSize: [[300, 250]] } },
+ params: { token: 'test-token' }
+ }
+ ];
+ const videoResponse = {
+ 'headers': null,
+ 'body': {
+ 'id': '233f1693-68d1-470a-ad85-c156c3faaf6f',
+ 'seatbid': [
+ {
+ 'bid': [
+ {
+ 'id': '2820132fe18114',
+ 'impid': '2820132fe18114',
+ 'price': 0.03294,
+ 'nurl': 'https://api16-event-sg2.pangle.io/api/ad/union/openrtb/win/?req_id=233f1693-68d1-470a-ad85-c156c3faaf6fu1450&ttdsp_adx_index=256&rit=980589944&extra=oqveoB%2Bg4%2ByNz9L8wwu%2Fy%2FwKxQsGaKsJHuB4NMK77uqZ9%2FJKpnsVZculJX8%2FxrRBAtaktU1DRN%2Fy6TKAqibCbj%2FM3%2BZ6biAKQG%2BCyt4eIV0KVvri9jCCnaajbkN7YNJWJJw2lW6cJ6Va3SuJG9H7a%2FAJd2PMbhK7fXWhoW72TwgOcKHKBgjM6sNDISBKbWlZyY3L1PhKSX%2FM8LOvL6qahsb%2FDpEObIx24vhQLNWp28XY1L4UqeibuRjam3eCvN7nXoQq74KkJ45QQsTgvV4j6I6EbLOdjOi%2FURhWMDjUD1VCMpqUT%2B6L8ZROgrX9Tp53eJ3bFOczmSTOmDSazKMHa%2B3uZZ7JHcSx32eoY4hfYc99NOJmYBKXNKCmoXyJvS3PCM3PlAz97hKrDMGnVv1wAQ7QGDCbittF0vZwtsRAvvx2mWINNIB3%2FUB2PjhxFsoDA%2BWE2urVZwEdyu%2FJrCznJsMwenXjcbMD5jmUF5vDkkLS%2B7TMDIEawJPJKZ62pK35enrwGxCs6ePXi21rJJkA0bF8tgAdl4mU1illBIVO4kCL%2ByRASskHPjgg%2FcdFe9HP%2Fi8byjAprH%2BhRerN%2FRKFxC3xv8b75x2pb1g7dY%2FTj9IjT0evsBSPVwFNqtKmPId35IcY%2FSXiqPHh%2FrAHZzr5BPsTT19P49SlNMR9UZYTzViX1iJpcCL1UFjuDdrdff%2BhHCviXxo%2FkRmufEF3umHZwxbdDOPAghuZ0DtRCY6S1rnb%2FK9BbpsVKSndOtgfCwMHFwiPmdw1XjEXGc1eOWXY6qfSp90PIfL6WS7Neh3ba2qMv6WxG3HSOBYvrcCqVTsNxk4UdVm3qb1J0CMVByweTMo45usSkCTdvX3JuEB7tVA6%2BrEk57b3XJd5Phf2AN8hon%2F7lmcXE41kwMQuXq89ViwQmW0G247UFWOQx4t1cmBqFiP6qNA%2F%2BunkZDno1pmAsGnTv7Mz9xtpOaIqKl8BKrVQSTopZ9WcUVzdBUutF19mn1f43BvyA9gIEhcDJHOj&win_price=${AUCTION_PRICE}&auction_mwb=${AUCTION_BID_TO_WIN}&use_pb=1',
+ 'lurl': 'https://api16-event-sg2.pangle.io/api/ad/union/openrtb/loss/?req_id=233f1693-68d1-470a-ad85-c156c3faaf6fu1450&ttdsp_adx_index=256&rit=980589944&extra=oqveoB%2Bg4%2ByNz9L8wwu%2Fy%2FwKxQsGaKsJHuB4NMK77uqZ9%2FJKpnsVZculJX8%2FxrRBAtaktU1DRN%2Fy6TKAqibCbj%2FM3%2BZ6biAKQG%2BCyt4eIV0KVvri9jCCnaajbkN7YNJWJJw2lW6cJ6Va3SuJG9H7a%2FAJd2PMbhK7fXWhoW72TwgOcKHKBgjM6sNDISBKbWlZyY3L1PhKSX%2FM8LOvL6qahsb%2FDpEObIx24vhQLNWp28XY1L4UqeibuRjam3eCvN7nXoQq74KkJ45QQsTgvV4j6I6EbLOdjOi%2FURhWMDjUD1VCMpqUT%2B6L8ZROgrX9Tp53eJ3bFOczmSTOmDSazKMHa%2B3uZZ7JHcSx32eoY4hfYc99NOJmYBKXNKCmoXyJvS3PCM3PlAz97hKrDMGnVv1wAQ7QGDCbittF0vZwtsRAvvx2mWINNIB3%2FUB2PjhxFsoDA%2BWE2urVZwEdyu%2FJrCznJsMwenXjcbMD5jmUF5vDkkLS%2B7TMDIEawJPJKZ62pK35enrwGxCs6ePXi21rJJkA0bF8tgAdl4mU1illBIVO4kCL%2ByRASskHPjgg%2FcdFe9HP%2Fi8byjAprH%2BhRerN%2FRKFxC3xv8b75x2pb1g7dY%2FTj9IjT0evsBSPVwFNqtKmPId35IcY%2FSXiqPHh%2FrAHZzr5BPsTT19P49SlNMR9UZYTzViX1iJpcCL1UFjuDdrdff%2BhHCviXxo%2FkRmufEF3umHZwxbdDOPAghuZ0DtRCY6S1rnb%2FK9BbpsVKSndOtgfCwMHFwiPmdw1XjEXGc1eOWXY6qfSp90PIfL6WS7Neh3ba2qMv6WxG3HSOBYvrcCqVTsNxk4UdVm3qb1J0CMVByweTMo45usSkCTdvX3JuEB7tVA6%2BrEk57b3XJd5Phf2AN8hon%2F7lmcXE41kwMQuXq89ViwQmW0G247UFWOQx4t1cmBqFiP6qNA%2F%2BunkZDno1pmAsGnTv7Mz9xtpOaIqKl8BKrVQSTopZ9WcUVzdBUutF19mn1f43BvyA9gIEhcDJHOj&reason=${AUCTION_LOSS}&ad_slot_type=8&auction_mwb=${AUCTION_PRICE}&use_pb=1',
+ 'adm': '
',
+ 'adid': '1780626232977441',
+ 'adomain': [
+ 'swi.esxcmnb.com'
+ ],
+ 'iurl': 'https://p16-ttam-va.ibyteimg.com/origin/ad-site-i18n-sg/202310245d0d598b3ff5993c4f129a8b',
+ 'cid': '1780626232977441',
+ 'crid': '1780626232977441',
+ 'attr': [
+ 4
+ ],
+ 'w': 640,
+ 'h': 640,
+ 'mtype': 2,
+ 'ext': {
+ 'pangle': {
+ 'adtype': 8
+ },
+ 'event_notification_token': {
+ 'payload': '980589944:8:1450:7492'
+ }
+ }
+ }
+ ],
+ 'seat': 'pangle'
+ }
+ ]
+ }
+ };
+ const bannerResponse = {
+ 'headers': null,
+ 'body': {
+ 'id': '233f1693-68d1-470a-ad85-c156c3faaf6f',
+ 'seatbid': [
+ {
+ 'bid': [
+ {
+ 'id': '2820132fe18114',
+ 'impid': '2820132fe18114',
+ 'price': 0.03294,
+ 'nurl': 'https://api16-event-sg2.pangle.io/api/ad/union/openrtb/win/?req_id=233f1693-68d1-470a-ad85-c156c3faaf6fu1450&ttdsp_adx_index=256&rit=980589944&extra=oqveoB%2Bg4%2ByNz9L8wwu%2Fy%2FwKxQsGaKsJHuB4NMK77uqZ9%2FJKpnsVZculJX8%2FxrRBAtaktU1DRN%2Fy6TKAqibCbj%2FM3%2BZ6biAKQG%2BCyt4eIV0KVvri9jCCnaajbkN7YNJWJJw2lW6cJ6Va3SuJG9H7a%2FAJd2PMbhK7fXWhoW72TwgOcKHKBgjM6sNDISBKbWlZyY3L1PhKSX%2FM8LOvL6qahsb%2FDpEObIx24vhQLNWp28XY1L4UqeibuRjam3eCvN7nXoQq74KkJ45QQsTgvV4j6I6EbLOdjOi%2FURhWMDjUD1VCMpqUT%2B6L8ZROgrX9Tp53eJ3bFOczmSTOmDSazKMHa%2B3uZZ7JHcSx32eoY4hfYc99NOJmYBKXNKCmoXyJvS3PCM3PlAz97hKrDMGnVv1wAQ7QGDCbittF0vZwtsRAvvx2mWINNIB3%2FUB2PjhxFsoDA%2BWE2urVZwEdyu%2FJrCznJsMwenXjcbMD5jmUF5vDkkLS%2B7TMDIEawJPJKZ62pK35enrwGxCs6ePXi21rJJkA0bF8tgAdl4mU1illBIVO4kCL%2ByRASskHPjgg%2FcdFe9HP%2Fi8byjAprH%2BhRerN%2FRKFxC3xv8b75x2pb1g7dY%2FTj9IjT0evsBSPVwFNqtKmPId35IcY%2FSXiqPHh%2FrAHZzr5BPsTT19P49SlNMR9UZYTzViX1iJpcCL1UFjuDdrdff%2BhHCviXxo%2FkRmufEF3umHZwxbdDOPAghuZ0DtRCY6S1rnb%2FK9BbpsVKSndOtgfCwMHFwiPmdw1XjEXGc1eOWXY6qfSp90PIfL6WS7Neh3ba2qMv6WxG3HSOBYvrcCqVTsNxk4UdVm3qb1J0CMVByweTMo45usSkCTdvX3JuEB7tVA6%2BrEk57b3XJd5Phf2AN8hon%2F7lmcXE41kwMQuXq89ViwQmW0G247UFWOQx4t1cmBqFiP6qNA%2F%2BunkZDno1pmAsGnTv7Mz9xtpOaIqKl8BKrVQSTopZ9WcUVzdBUutF19mn1f43BvyA9gIEhcDJHOj&win_price=${AUCTION_PRICE}&auction_mwb=${AUCTION_BID_TO_WIN}&use_pb=1',
+ 'lurl': 'https://api16-event-sg2.pangle.io/api/ad/union/openrtb/loss/?req_id=233f1693-68d1-470a-ad85-c156c3faaf6fu1450&ttdsp_adx_index=256&rit=980589944&extra=oqveoB%2Bg4%2ByNz9L8wwu%2Fy%2FwKxQsGaKsJHuB4NMK77uqZ9%2FJKpnsVZculJX8%2FxrRBAtaktU1DRN%2Fy6TKAqibCbj%2FM3%2BZ6biAKQG%2BCyt4eIV0KVvri9jCCnaajbkN7YNJWJJw2lW6cJ6Va3SuJG9H7a%2FAJd2PMbhK7fXWhoW72TwgOcKHKBgjM6sNDISBKbWlZyY3L1PhKSX%2FM8LOvL6qahsb%2FDpEObIx24vhQLNWp28XY1L4UqeibuRjam3eCvN7nXoQq74KkJ45QQsTgvV4j6I6EbLOdjOi%2FURhWMDjUD1VCMpqUT%2B6L8ZROgrX9Tp53eJ3bFOczmSTOmDSazKMHa%2B3uZZ7JHcSx32eoY4hfYc99NOJmYBKXNKCmoXyJvS3PCM3PlAz97hKrDMGnVv1wAQ7QGDCbittF0vZwtsRAvvx2mWINNIB3%2FUB2PjhxFsoDA%2BWE2urVZwEdyu%2FJrCznJsMwenXjcbMD5jmUF5vDkkLS%2B7TMDIEawJPJKZ62pK35enrwGxCs6ePXi21rJJkA0bF8tgAdl4mU1illBIVO4kCL%2ByRASskHPjgg%2FcdFe9HP%2Fi8byjAprH%2BhRerN%2FRKFxC3xv8b75x2pb1g7dY%2FTj9IjT0evsBSPVwFNqtKmPId35IcY%2FSXiqPHh%2FrAHZzr5BPsTT19P49SlNMR9UZYTzViX1iJpcCL1UFjuDdrdff%2BhHCviXxo%2FkRmufEF3umHZwxbdDOPAghuZ0DtRCY6S1rnb%2FK9BbpsVKSndOtgfCwMHFwiPmdw1XjEXGc1eOWXY6qfSp90PIfL6WS7Neh3ba2qMv6WxG3HSOBYvrcCqVTsNxk4UdVm3qb1J0CMVByweTMo45usSkCTdvX3JuEB7tVA6%2BrEk57b3XJd5Phf2AN8hon%2F7lmcXE41kwMQuXq89ViwQmW0G247UFWOQx4t1cmBqFiP6qNA%2F%2BunkZDno1pmAsGnTv7Mz9xtpOaIqKl8BKrVQSTopZ9WcUVzdBUutF19mn1f43BvyA9gIEhcDJHOj&reason=${AUCTION_LOSS}&ad_slot_type=8&auction_mwb=${AUCTION_PRICE}&use_pb=1',
+ 'adm': '
',
+ 'adid': '1780626232977441',
+ 'adomain': [
+ 'swi.esxcmnb.com'
+ ],
+ 'iurl': 'https://p16-ttam-va.ibyteimg.com/origin/ad-site-i18n-sg/202310245d0d598b3ff5993c4f129a8b',
+ 'cid': '1780626232977441',
+ 'crid': '1780626232977441',
+ 'attr': [
+ 4
+ ],
+ 'w': 640,
+ 'h': 640,
+ 'mtype': 1,
+ 'ext': {
+ 'pangle': {
+ 'adtype': 8
+ },
+ 'event_notification_token': {
+ 'payload': '980589944:8:1450:7492'
+ }
+ }
+ }
+ ],
+ 'seat': 'pangle'
+ }
+ ]
+ }
+ };
+ it('should set mediaType to banner', function() {
+ const request = spec.buildRequests(multiRequest, bidderRequest)[0];
+ const interpretedResponse = spec.interpretResponse(bannerResponse, request);
+ const bid = interpretedResponse[0];
+ expect(bid.mediaType).to.equal('banner');
+ })
+ it('should set mediaType to video', function() {
+ const request = spec.buildRequests(multiRequest, bidderRequest)[0];
+ const interpretedResponse = spec.interpretResponse(videoResponse, request);
+ const bid = interpretedResponse[0];
+ expect(bid.mediaType).to.equal('video');
+ })
+});
diff --git a/test/spec/modules/priceFloors_spec.js b/test/spec/modules/priceFloors_spec.js
index f618e57e60d..a31f07fecef 100644
--- a/test/spec/modules/priceFloors_spec.js
+++ b/test/spec/modules/priceFloors_spec.js
@@ -773,6 +773,124 @@ describe('the price floors module', function () {
floorProvider: undefined
});
});
+ it('should not do floor stuff if floors.data is defined by noFloorSignalBidders[]', function() {
+ handleSetFloorsConfig({
+ ...basicFloorConfig,
+ data: {
+ ...basicFloorDataLow,
+ noFloorSignalBidders: ['someBidder', 'someOtherBidder']
+ }});
+ runStandardAuction();
+ validateBidRequests(false, {
+ skipped: false,
+ floorMin: undefined,
+ modelVersion: 'basic model',
+ modelWeight: 10,
+ modelTimestamp: undefined,
+ location: 'setConfig',
+ skipRate: 0,
+ fetchStatus: undefined,
+ floorProvider: undefined,
+ noFloorSignaled: true
+ })
+ });
+ it('should not do floor stuff if floors.enforcement is defined by noFloorSignalBidders[]', function() {
+ handleSetFloorsConfig({ ...basicFloorConfig,
+ enforcement: {
+ enforceJS: true,
+ noFloorSignalBidders: ['someBidder', 'someOtherBidder']
+ },
+ data: basicFloorDataLow
+ });
+ runStandardAuction();
+ validateBidRequests(false, {
+ skipped: false,
+ floorMin: undefined,
+ modelVersion: 'basic model',
+ modelWeight: 10,
+ modelTimestamp: undefined,
+ location: 'setConfig',
+ skipRate: 0,
+ fetchStatus: undefined,
+ floorProvider: undefined,
+ noFloorSignaled: true
+ })
+ });
+ it('should not do floor stuff and use first floors.data.noFloorSignalBidders if its defined betwen enforcement.noFloorSignalBidders', function() {
+ handleSetFloorsConfig({ ...basicFloorConfig,
+ enforcement: {
+ enforceJS: true,
+ noFloorSignalBidders: ['someBidder']
+ },
+ data: {
+ ...basicFloorDataLow,
+ noFloorSignalBidders: ['someBidder', 'someOtherBidder']
+ }
+ });
+ runStandardAuction();
+ validateBidRequests(false, {
+ skipped: false,
+ floorMin: undefined,
+ modelVersion: 'basic model',
+ modelWeight: 10,
+ modelTimestamp: undefined,
+ location: 'setConfig',
+ skipRate: 0,
+ fetchStatus: undefined,
+ floorProvider: undefined,
+ noFloorSignaled: true
+ })
+ });
+ it('it shouldn`t return floor stuff for bidder in the noFloorSignalBidders list', function() {
+ handleSetFloorsConfig({ ...basicFloorConfig,
+ enforcement: {
+ enforceJS: true,
+ },
+ data: {
+ ...basicFloorDataLow,
+ noFloorSignalBidders: ['someBidder']
+ }
+ });
+ runStandardAuction()
+ const bidRequestData = exposedAdUnits[0].bids.find(bid => bid.bidder === 'someBidder');
+ expect(bidRequestData.hasOwnProperty('getFloor')).to.equal(false);
+ sinon.assert.match(bidRequestData.floorData, {
+ skipped: false,
+ floorMin: undefined,
+ modelVersion: 'basic model',
+ modelWeight: 10,
+ modelTimestamp: undefined,
+ location: 'setConfig',
+ skipRate: 0,
+ fetchStatus: undefined,
+ floorProvider: undefined,
+ noFloorSignaled: true
+ });
+ })
+ it('it should return floor stuff if we defined wrong bidder name in data.noFloorSignalBidders', function() {
+ handleSetFloorsConfig({ ...basicFloorConfig,
+ enforcement: {
+ enforceJS: true,
+ },
+ data: {
+ ...basicFloorDataLow,
+ noFloorSignalBidders: ['randomBiider']
+ }
+ });
+ runStandardAuction();
+ validateBidRequests(true, {
+ skipped: false,
+ floorMin: undefined,
+ modelVersion: 'basic model',
+ modelWeight: 10,
+ modelTimestamp: undefined,
+ location: 'setConfig',
+ skipRate: 0,
+ fetchStatus: undefined,
+ floorProvider: undefined,
+ noFloorSignaled: false
+ })
+ });
it('should use adUnit level data if not setConfig or fetch has occured', function () {
handleSetFloorsConfig({
...basicFloorConfig,
diff --git a/test/spec/modules/seedtagBidAdapter_spec.js b/test/spec/modules/seedtagBidAdapter_spec.js
index fb666e89f73..516c5ec933a 100644
--- a/test/spec/modules/seedtagBidAdapter_spec.js
+++ b/test/spec/modules/seedtagBidAdapter_spec.js
@@ -2,10 +2,24 @@ import { expect } from 'chai';
import { spec, getTimeoutUrl } from 'modules/seedtagBidAdapter.js';
import * as utils from 'src/utils.js';
import { config } from '../../../src/config.js';
+import * as mockGpt from 'test/spec/integration/faker/googletag.js';
const PUBLISHER_ID = '0000-0000-01';
const ADUNIT_ID = '000000';
+const adUnitCode = '/19968336/header-bid-tag-0'
+
+// create a default adunit
+const slot = document.createElement('div');
+slot.id = adUnitCode;
+slot.style.width = '300px'
+slot.style.height = '250px'
+slot.style.position = 'absolute'
+slot.style.top = '10px'
+slot.style.left = '20px'
+
+document.body.appendChild(slot);
+
function getSlotConfigs(mediaTypes, params) {
return {
params: params,
@@ -25,7 +39,7 @@ function getSlotConfigs(mediaTypes, params) {
tid: 'd704d006-0d6e-4a09-ad6c-179e7e758096',
}
},
- adUnitCode: 'adunit-code',
+ adUnitCode: adUnitCode,
};
}
@@ -46,6 +60,13 @@ const createBannerSlotConfig = (placement, mediatypes) => {
};
describe('Seedtag Adapter', function () {
+ beforeEach(function () {
+ mockGpt.reset();
+ });
+
+ afterEach(function () {
+ mockGpt.enable();
+ });
describe('isBidRequestValid method', function () {
describe('returns true', function () {
describe('when banner slot config has all mandatory params', () => {
@@ -277,7 +298,7 @@ describe('Seedtag Adapter', function () {
expect(data.auctionStart).to.be.greaterThanOrEqual(now);
expect(data.ttfb).to.be.greaterThanOrEqual(0);
- expect(data.bidRequests[0].adUnitCode).to.equal('adunit-code');
+ expect(data.bidRequests[0].adUnitCode).to.equal(adUnitCode);
});
describe('GDPR params', function () {
@@ -374,6 +395,35 @@ describe('Seedtag Adapter', function () {
expect(videoBid.sizes[1][1]).to.equal(600);
expect(videoBid.requestCount).to.equal(1);
});
+
+ it('should have geom parameters if slot is available', function() {
+ const request = spec.buildRequests(validBidRequests, bidderRequest);
+ const data = JSON.parse(request.data);
+ const bidRequests = data.bidRequests;
+ const bannerBid = bidRequests[0];
+
+ // on some CI, the DOM is not initialized, so we need to check if the slot is available
+ const slot = document.getElementById(adUnitCode)
+ if (slot) {
+ expect(bannerBid).to.have.property('geom')
+
+ const params = [['width', 300], ['height', 250], ['top', 10], ['left', 20], ['scrollY', 0]]
+ params.forEach(([param, value]) => {
+ expect(bannerBid.geom).to.have.property(param)
+ expect(bannerBid.geom[param]).to.be.a('number')
+ expect(bannerBid.geom[param]).to.be.equal(value)
+ })
+
+ expect(bannerBid.geom).to.have.property('viewport')
+ const viewportParams = ['width', 'height']
+ viewportParams.forEach(param => {
+ expect(bannerBid.geom.viewport).to.have.property(param)
+ expect(bannerBid.geom.viewport[param]).to.be.a('number')
+ })
+ } else {
+ expect(bannerBid).to.not.have.property('geom')
+ }
+ })
});
describe('COPPA param', function () {
diff --git a/test/spec/modules/sharethroughBidAdapter_spec.js b/test/spec/modules/sharethroughBidAdapter_spec.js
index eb0b45dda11..6a63ae681e7 100644
--- a/test/spec/modules/sharethroughBidAdapter_spec.js
+++ b/test/spec/modules/sharethroughBidAdapter_spec.js
@@ -588,6 +588,43 @@ describe('sharethrough adapter spec', function () {
});
});
+ describe('cookie deprecation', () => {
+ it('should not add cdep if we do not get it in an impression request', () => {
+ const builtRequests = spec.buildRequests(bidRequests, {
+ auctionId: 'new-auction-id',
+ ortb2: {
+ device: {
+ ext: {
+ propThatIsNotCdep: 'value-we-dont-care-about',
+ },
+ },
+ },
+ });
+ const noCdep = builtRequests.every((builtRequest) => {
+ const ourCdepValue = builtRequest.data.device?.ext?.cdep;
+ return ourCdepValue === undefined;
+ });
+ expect(noCdep).to.be.true;
+ });
+
+ it('should add cdep if we DO get it in an impression request', () => {
+ const builtRequests = spec.buildRequests(bidRequests, {
+ auctionId: 'new-auction-id',
+ ortb2: {
+ device: {
+ ext: {
+ cdep: 'cdep-value',
+ },
+ },
+ },
+ });
+ const cdepPresent = builtRequests.every((builtRequest) => {
+ return builtRequest.data.device.ext.cdep === 'cdep-value';
+ });
+ expect(cdepPresent).to.be.true;
+ });
+ });
+
describe('first party data', () => {
const firstPartyData = {
site: {