diff --git a/modules/papyrusBidAdapter.js b/modules/papyrusBidAdapter.js new file mode 100644 index 000000000000..1ece7fc74606 --- /dev/null +++ b/modules/papyrusBidAdapter.js @@ -0,0 +1,77 @@ +import * as utils from 'src/utils'; +import {registerBidder} from 'src/adapters/bidderFactory'; + +const PAPYRUS_ENDPOINT = '//prebid.papyrus.global'; +const PAPYRUS_CODE = 'papyrus'; + +export const spec = { + code: PAPYRUS_CODE, + + /** + * Determines whether or not the given bid request is valid. Valid bid request must have placementId and hbid + * + * @param {BidRequest} bid The bid params to validate. + * @return boolean True if this is a valid bid, and false otherwise. + */ + isBidRequestValid: bid => { + return !!(bid && bid.params && bid.params.address && bid.params.placementId); + }, + + /** + * Make a server request from the list of BidRequests. + * + * @param {BidRequest[]} validBidRequests - an array of bids + * @return ServerRequest Info describing the request to the server. + */ + buildRequests: function(validBidRequests) { + const bidParams = []; + utils._each(validBidRequests, function(bid) { + bidParams.push({ + address: bid.params.address, + placementId: bid.params.placementId, + bidId: bid.bidId, + transactionId: bid.transactionId, + sizes: utils.parseSizesInput(bid.sizes) + }); + }); + + return { + method: 'POST', + url: PAPYRUS_ENDPOINT, + data: bidParams + }; + }, + + /** + * Unpack the response from the server into a list of bids. + * + * @param {*} serverResponse A successful response from the server. + * @return {Bid[]} An array of bids which were nested inside the server. + */ + interpretResponse: function(serverResponse, request) { + const bidResponses = []; + + if (serverResponse && serverResponse.body && serverResponse.body.bids) { + serverResponse.body.bids.forEach(bid => { + const bidResponse = { + requestId: bid.id, + creativeId: bid.id, + adId: bid.id, + transactionId: bid.transactionId, + cpm: bid.cpm, + width: bid.width, + height: bid.height, + currency: bid.currency, + netRevenue: true, + ttl: 300, + ad: bid.ad + } + bidResponses.push(bidResponse); + }); + } + + return bidResponses; + } +}; + +registerBidder(spec); diff --git a/modules/papyrusBidAdapter.md b/modules/papyrusBidAdapter.md new file mode 100644 index 000000000000..98a42e542eca --- /dev/null +++ b/modules/papyrusBidAdapter.md @@ -0,0 +1,41 @@ +# Overview + +``` +Module Name: Papyrus Bid Adapter +Module Type: Bidder Adapter +Maintainer: alexander.holodov@papyrus.global +``` + +# Description + +Connect to Papyrus system for bids. + +Papyrus bid adapter supports Banner. + +Please contact to info@papyrus.global for +further details + +# Test Parameters +``` + var adUnits = [ + { + code: 'test-div', + mediaTypes: { + banner: { + sizes: [ + [320, 50] + ] + } + }, + bids: [ + { + bidder: 'papyrus', + params: { + address: '0xd7e2a771c5dcd5df7f789477356aecdaeee6c985', + placementId: 'b57e55fd18614b0591893e9fff41fbea' + } + } + ] + } + ]; +``` diff --git a/test/spec/modules/papyrusBidAdapter_spec.js b/test/spec/modules/papyrusBidAdapter_spec.js new file mode 100644 index 000000000000..a61a1c55269a --- /dev/null +++ b/test/spec/modules/papyrusBidAdapter_spec.js @@ -0,0 +1,115 @@ +import { expect } from 'chai'; +import { spec } from 'modules/papyrusBidAdapter'; + +const ENDPOINT = '//prebid.papyrus.global'; +const BIDDER_CODE = 'papyrus'; + +describe('papyrus Adapter', () => { + describe('isBidRequestValid', () => { + let validBidReq = { + bidder: BIDDER_CODE, + params: { + address: '0xd7e2a771c5dcd5df7f789477356aecdaeee6c985', + placementId: 'b57e55fd18614b0591893e9fff41fbea' + } + }; + + it('should return true when required params found', () => { + expect(spec.isBidRequestValid(validBidReq)).to.equal(true); + }); + + let invalidBidReq = { + bidder: BIDDER_CODE, + params: { + 'placementId': '' + } + }; + + it('should not validate incorrect bid request', () => { + expect(spec.isBidRequestValid(invalidBidReq)).to.equal(false); + }); + }); + + describe('buildRequests', () => { + let bidRequests = [ + { + bidder: BIDDER_CODE, + params: { + address: '0xd7e2a771c5dcd5df7f789477356aecdaeee6c985', + placementId: 'b57e55fd18614b0591893e9fff41fbea' + }, + 'adUnitCode': 'adunit-code', + 'sizes': [[300, 250], [300, 600]], + 'bidId': '30b31c1838de1e', + 'bidderRequestId': '22edbae2733bf6', + 'auctionId': '1d1a030790a475', + } + ]; + + it('sends bid request to ENDPOINT via POST', () => { + const request = spec.buildRequests(bidRequests); + expect(request.url).to.equal(ENDPOINT); + expect(request.method).to.equal('POST'); + }); + + it('sends valid bids count', () => { + const request = spec.buildRequests(bidRequests); + expect(request.data.length).to.equal(1); + }); + + it('sends all bid parameters', () => { + const request = spec.buildRequests(bidRequests); + expect(request.data[0]).to.have.all.keys(['address', 'placementId', 'sizes', 'bidId', 'transactionId']); + }); + + it('sedns valid sizes parameter', () => { + const request = spec.buildRequests(bidRequests); + expect(request.data[0].sizes[0]).to.equal('300x250'); + }); + }); + + describe('interpretResponse', () => { + let bidRequests = [ + { + bidder: BIDDER_CODE, + params: { + address: '0xd7e2a771c5dcd5df7f789477356aecdaeee6c985', + placementId: 'b57e55fd18614b0591893e9fff41fbea' + }, + 'adUnitCode': 'adunit-code', + 'sizes': [[300, 250], [300, 600]], + 'bidId': '30b31c1838de1e', + 'bidderRequestId': '22edbae2733bf6', + 'auctionId': '1d1a030790a475', + } + ]; + + let bidResponse = { + bids: [ + { + id: '1036e9746c-d186-49ae-90cb-2796d0f9b223', + adm: 'test adm', + cpm: 100, + height: 250, + width: 300 + } + ] + }; + + it('should build bid array', () => { + const request = spec.buildRequests(bidRequests); + const result = spec.interpretResponse({body: bidResponse}, request[0]); + expect(result.length).to.equal(1); + }); + + it('should have all relevant fields', () => { + const request = spec.buildRequests(bidRequests); + const result = spec.interpretResponse({body: bidResponse}, request[0]); + const bid = result[0]; + + expect(bid.cpm).to.equal(bidResponse.bids[0].cpm); + expect(bid.width).to.equal(bidResponse.bids[0].width); + expect(bid.height).to.equal(bidResponse.bids[0].height); + }); + }); +});