diff --git a/modules/dasBidAdapter.js b/modules/dasBidAdapter.js index 76e70f38f9a..5203e126a1f 100644 --- a/modules/dasBidAdapter.js +++ b/modules/dasBidAdapter.js @@ -105,7 +105,7 @@ function buildUserIds(customParams) { function getNpaFromPubConsent(pubConsent) { const params = new URLSearchParams(pubConsent); - return params.get('npa') == '1'; + return params.get('npa') === '1'; } function buildOpenRTBRequest(bidRequests, bidderRequest) { @@ -113,7 +113,7 @@ function buildOpenRTBRequest(bidRequests, bidderRequest) { bidRequests[0].params, bidderRequest, ); - const imp = bidRequests.map((bid, index) => { + const imp = bidRequests.map((bid) => { const sizes = getAdUnitSizes(bid); const imp = { id: bid.bidId, @@ -270,11 +270,29 @@ export const spec = { buildRequests: function (validBidRequests, bidderRequest) { const data = buildOpenRTBRequest(validBidRequests, bidderRequest); - const jsonData = encodeURIComponent(JSON.stringify(data)); + const jsonData = JSON.stringify(data); + const baseUrl = getEndpoint(data.ext.network); + const fullUrl = `${baseUrl}?data=${encodeURIComponent(jsonData)}`; + + // Switch to POST if URL exceeds 8k characters + if (fullUrl.length > 8192) { + return { + method: 'POST', + url: baseUrl, + data: jsonData, + options: { + withCredentials: true, + crossOrigin: true, + customHeaders: { + 'Content-Type': 'text/plain' + } + }, + }; + } return { method: 'GET', - url: `${getEndpoint(data.ext.network)}?data=${jsonData}`, + url: fullUrl, options: { withCredentials: true, crossOrigin: true, diff --git a/test/spec/modules/dasBidAdapter_spec.js b/test/spec/modules/dasBidAdapter_spec.js index 714360cc205..07b86210c74 100644 --- a/test/spec/modules/dasBidAdapter_spec.js +++ b/test/spec/modules/dasBidAdapter_spec.js @@ -178,217 +178,303 @@ describe('dasBidAdapter', function () { expect(payload.imp[0].tagid).to.equal('slot1'); expect(payload.imp[0].banner.format[0]).to.deep.equal({ w: 300, h: 250 }); }); - }); - describe('interpretResponse', function () { - const serverResponse = { - body: { - seatbid: [{ - bid: [{ - impid: 'bid123', - price: 3.5, - w: 300, - h: 250, - adm: '', - crid: 'crid123', - mtype: 1, - adomain: ['advertiser.com'] - }] - }], - cur: 'USD' + it('should use GET method when URL is under 8192 characters', function () { + const request = spec.buildRequests(bidRequests, bidderRequest); + expect(request.method).to.equal('GET'); + expect(request.url).to.include('?data='); + expect(request.data).to.be.undefined; + }); + + it('should switch to POST method when URL exceeds 8192 characters', function () { + // Create a large bid request that will result in URL > 8k characters + const largeBidRequests = []; + for (let i = 0; i < 50; i++) { + largeBidRequests.push({ + bidId: `bid${i}`.repeat(20), // Make bid IDs longer + params: { + site: `site${i}`.repeat(50), + area: `area${i}`.repeat(50), + slot: `slot${i}`.repeat(50), + network: 'network1', + pageContext: { + du: `https://very-long-url-example-${i}.com`.repeat(10), + dr: `https://very-long-referrer-url-${i}.com`.repeat(10), + dv: `version-${i}`.repeat(20), + keyWords: Array(20).fill(`keyword${i}`), + capping: `cap${i}`.repeat(20), + keyValues: { + [`key${i}`]: `value${i}`.repeat(50) + } + }, + customParams: { + [`param${i}`]: `value${i}`.repeat(50) + } + }, + mediaTypes: { + banner: { + sizes: [[300, 250], [728, 90], [970, 250]] + } + } + }); } - }; - it('should return proper bid response', function () { - const bidResponses = spec.interpretResponse(serverResponse); - - expect(bidResponses).to.be.an('array').with.lengthOf(1); - expect(bidResponses[0]).to.deep.include({ - requestId: 'bid123', - cpm: 3.5, - currency: 'USD', - width: 300, - height: 250, - ad: '', - creativeId: 'crid123', - netRevenue: true, - ttl: 300, - mediaType: 'banner' - }); - expect(bidResponses[0].meta.advertiserDomains).to.deep.equal(['advertiser.com']); + const request = spec.buildRequests(largeBidRequests, bidderRequest); + + expect(request.method).to.equal('POST'); + expect(request.url).to.equal('https://csr.onet.pl/network1/bid'); + expect(request.data).to.be.a('string'); + + // Check if data is valid JSON (not URL-encoded form data) + const payload = JSON.parse(request.data); + expect(payload.id).to.equal('reqId123'); + expect(payload.imp).to.be.an('array'); + expect(request.options.customHeaders['Content-Type']).to.equal('text/plain'); }); - it('should return empty array when no valid responses', function () { - expect(spec.interpretResponse({ body: null })).to.be.an('array').that.is.empty; - expect(spec.interpretResponse({ body: {} })).to.be.an('array').that.is.empty; - expect(spec.interpretResponse({ body: { seatbid: [] } })).to.be.an('array').that.is.empty; + it('should create valid POST data format', function () { + // Create a request that will trigger POST + const largeBidRequests = Array(50).fill(0).map((_, i) => ({ + bidId: `bid${i}`.repeat(20), + params: { + site: `site${i}`.repeat(50), + area: `area${i}`.repeat(50), + slot: `slot${i}`.repeat(50), + network: 'network1', + pageContext: { + du: `https://very-long-url-example-${i}.com`.repeat(10), + dr: `https://very-long-referrer-url-${i}.com`.repeat(10), + keyWords: Array(10).fill(`keyword${i}`) + } + }, + mediaTypes: { + banner: { + sizes: [[300, 250]] + } + } + })); + + const request = spec.buildRequests(largeBidRequests, bidderRequest); + + expect(request.method).to.equal('POST'); + + // Parse the POST data as JSON (not URL-encoded) + const payload = JSON.parse(request.data); + expect(payload.id).to.equal('reqId123'); + expect(payload.imp).to.be.an('array').with.length(50); + expect(payload.ext.network).to.equal('network1'); }); - it('should return proper bid response for native', function () { - const nativeResponse = { + describe('interpretResponse', function () { + const serverResponse = { body: { seatbid: [{ bid: [{ impid: 'bid123', price: 3.5, - w: 1, - h: 1, - adm: JSON.stringify({ - fields: { - Body: 'Ruszyła sprzedaż mieszkań przy Metrze Dworzec Wileński', - Calltoaction: 'SPRAWDŹ', - Headline: 'Gotowe mieszkania w świetnej lokalizacji (test)', - Image: 'https://ocdn.eu/example.jpg', - Sponsorlabel: 'tak', - Thirdpartyclicktracker: '', - Thirdpartyimpressiontracker: '', - Thirdpartyimpressiontracker2: '', - borderColor: '#CECECE', - click: 'https://mieszkaniaprzymetrodworzec.pl', - responsive: 'nie' - }, - tplCode: '1746213/Native-In-Feed', - meta: { - inIFrame: false, - autoscale: 0, - width: '1', - height: '1', - adid: 'das,1778361,669261', - actioncount: 'https://csr.onet.pl/eclk/...', - slot: 'right2', - adclick: 'https://csr.onet.pl/clk/...', - container_wrapper: '
REKLAMA
', - prebid_native: true - } - }), - mtype: 4 + w: 300, + h: 250, + adm: '', + crid: 'crid123', + mtype: 1, + adomain: ['advertiser.com'] }] }], cur: 'USD' } }; - const bidResponses = spec.interpretResponse(nativeResponse); + it('should return proper bid response', function () { + const bidResponses = spec.interpretResponse(serverResponse); + + expect(bidResponses).to.be.an('array').with.lengthOf(1); + expect(bidResponses[0]).to.deep.include({ + requestId: 'bid123', + cpm: 3.5, + currency: 'USD', + width: 300, + height: 250, + ad: '', + creativeId: 'crid123', + netRevenue: true, + ttl: 300, + mediaType: 'banner' + }); + expect(bidResponses[0].meta.advertiserDomains).to.deep.equal(['advertiser.com']); + }); - expect(bidResponses).to.be.an('array').with.lengthOf(1); - expect(bidResponses[0]).to.deep.include({ - requestId: 'bid123', - cpm: 3.5, - currency: 'USD', - width: 1, - height: 1, - native: { - title: 'Gotowe mieszkania w świetnej lokalizacji (test)', - body: 'Ruszyła sprzedaż mieszkań przy Metrze Dworzec Wileński', - cta: 'SPRAWDŹ', - image: { - url: 'https://ocdn.eu/example.jpg', - width: '1', - height: '1' - }, - icon: { - url: '', - width: '1', - height: '1' - }, - clickUrl: 'https://csr.onet.pl/clk/...https://mieszkaniaprzymetrodworzec.pl', - body2: '', - sponsoredBy: '', - clickTrackers: [], - impressionTrackers: [], - javascriptTrackers: [], - sendTargetingKeys: false - }, - netRevenue: true, - ttl: 300, - mediaType: 'native' + it('should return empty array when no valid responses', function () { + expect(spec.interpretResponse({ body: null })).to.be.an('array').that.is.empty; + expect(spec.interpretResponse({ body: {} })).to.be.an('array').that.is.empty; + expect(spec.interpretResponse({ body: { seatbid: [] } })).to.be.an('array').that.is.empty; }); - expect(bidResponses[0]).to.not.have.property('ad'); + it('should return proper bid response for native', function () { + const nativeResponse = { + body: { + seatbid: [{ + bid: [{ + impid: 'bid123', + price: 3.5, + w: 1, + h: 1, + adm: JSON.stringify({ + fields: { + Body: 'Ruszyła sprzedaż mieszkań przy Metrze Dworzec Wileński', + Calltoaction: 'SPRAWDŹ', + Headline: 'Gotowe mieszkania w świetnej lokalizacji (test)', + Image: 'https://ocdn.eu/example.jpg', + Sponsorlabel: 'tak', + Thirdpartyclicktracker: '', + Thirdpartyimpressiontracker: '', + Thirdpartyimpressiontracker2: '', + borderColor: '#CECECE', + click: 'https://mieszkaniaprzymetrodworzec.pl', + responsive: 'nie' + }, + tplCode: '1746213/Native-In-Feed', + meta: { + inIFrame: false, + autoscale: 0, + width: '1', + height: '1', + adid: 'das,1778361,669261', + actioncount: 'https://csr.onet.pl/eclk/...', + slot: 'right2', + adclick: 'https://csr.onet.pl/clk/...', + container_wrapper: '
REKLAMA
', + prebid_native: true + } + }), + mtype: 4 + }] + }], + cur: 'USD' + } + }; + + const bidResponses = spec.interpretResponse(nativeResponse); + + expect(bidResponses).to.be.an('array').with.lengthOf(1); + expect(bidResponses[0]).to.deep.include({ + requestId: 'bid123', + cpm: 3.5, + currency: 'USD', + width: 1, + height: 1, + native: { + title: 'Gotowe mieszkania w świetnej lokalizacji (test)', + body: 'Ruszyła sprzedaż mieszkań przy Metrze Dworzec Wileński', + cta: 'SPRAWDŹ', + image: { + url: 'https://ocdn.eu/example.jpg', + width: '1', + height: '1' + }, + icon: { + url: '', + width: '1', + height: '1' + }, + clickUrl: 'https://csr.onet.pl/clk/...https://mieszkaniaprzymetrodworzec.pl', + body2: '', + sponsoredBy: '', + clickTrackers: [], + impressionTrackers: [], + javascriptTrackers: [], + sendTargetingKeys: false + }, + netRevenue: true, + ttl: 300, + mediaType: 'native' + }); + + expect(bidResponses[0]).to.not.have.property('ad'); + }); }); - }); - it('should return empty object when adm in a native response is not JSON', function () { - const nativeResponse = { - body: { - seatbid: [{ - bid: [{ - impid: 'bad1', - price: 2.0, - w: 1, - h: 1, - adm: 'not-a-json-string', - mtype: 4 - }] - }], - cur: 'USD' - } - }; + it('should return empty object when adm in a native response is not JSON', function () { + const nativeResponse = { + body: { + seatbid: [{ + bid: [{ + impid: 'bad1', + price: 2.0, + w: 1, + h: 1, + adm: 'not-a-json-string', + mtype: 4 + }] + }], + cur: 'USD' + } + }; - const bidResponses = spec.interpretResponse(nativeResponse); - expect(bidResponses[0].native).to.deep.equal({}); - }); + const bidResponses = spec.interpretResponse(nativeResponse); + expect(bidResponses[0].native).to.deep.equal({}); + }); - it('should return empty object when adm in a native response is missing required fields/meta', function () { - const nativeResponse = { - body: { - seatbid: [{ - bid: [{ - impid: 'bad2', - price: 2.0, - w: 1, - h: 1, - adm: JSON.stringify({ fields: {} }), - mtype: 4 - }] - }], - cur: 'USD' - } - }; + it('should return empty object when adm in a native response is missing required fields/meta', function () { + const nativeResponse = { + body: { + seatbid: [{ + bid: [{ + impid: 'bad2', + price: 2.0, + w: 1, + h: 1, + adm: JSON.stringify({ fields: {} }), + mtype: 4 + }] + }], + cur: 'USD' + } + }; - const bidResponses = spec.interpretResponse(nativeResponse); - expect(bidResponses[0].native).to.deep.equal({}); - }); + const bidResponses = spec.interpretResponse(nativeResponse); + expect(bidResponses[0].native).to.deep.equal({}); + }); - it('should return empty object when adm in a native response is empty JSON object', function () { - const nativeResponse = { - body: { - seatbid: [{ - bid: [{ - impid: 'bad3', - price: 2.0, - w: 1, - h: 1, - adm: JSON.stringify({}), - mtype: 4 - }] - }], - cur: 'USD' - } - }; + it('should return empty object when adm in a native response is empty JSON object', function () { + const nativeResponse = { + body: { + seatbid: [{ + bid: [{ + impid: 'bad3', + price: 2.0, + w: 1, + h: 1, + adm: JSON.stringify({}), + mtype: 4 + }] + }], + cur: 'USD' + } + }; - const bidResponses = spec.interpretResponse(nativeResponse); - expect(bidResponses[0].native).to.deep.equal({}); - }); + const bidResponses = spec.interpretResponse(nativeResponse); + expect(bidResponses[0].native).to.deep.equal({}); + }); - it('should return empty object when adm in a native response is null or missing', function () { - const nativeResponse = { - body: { - seatbid: [{ - bid: [{ - impid: 'bad4', - price: 2.0, - w: 1, - h: 1, - adm: null, - mtype: 4 - }] - }], - cur: 'USD' - } - }; + it('should return empty object when adm in a native response is null or missing', function () { + const nativeResponse = { + body: { + seatbid: [{ + bid: [{ + impid: 'bad4', + price: 2.0, + w: 1, + h: 1, + adm: null, + mtype: 4 + }] + }], + cur: 'USD' + } + }; - const bidResponses = spec.interpretResponse(nativeResponse); - expect(bidResponses[0].native).to.deep.equal({}); + const bidResponses = spec.interpretResponse(nativeResponse); + expect(bidResponses[0].native).to.deep.equal({}); + }); }); });