diff --git a/.github/workflows/issue_tracker.yml b/.github/workflows/issue_tracker.yml index fa33ffe5c53..05d08b2b0d7 100644 --- a/.github/workflows/issue_tracker.yml +++ b/.github/workflows/issue_tracker.yml @@ -14,7 +14,7 @@ jobs: steps: - name: Generate token id: generate_token - uses: tibdex/github-app-token@36464acb844fc53b9b8b2401da68844f6b05ebb0 + uses: tibdex/github-app-token@f717b5ecd4534d3c4df4ce9b5c1c2214f0f7cd06 with: app_id: ${{ secrets.ISSUE_APP_ID }} private_key: ${{ secrets.ISSUE_APP_PEM }} diff --git a/modules/mabidderBidAdapter.js b/modules/mabidderBidAdapter.js new file mode 100644 index 00000000000..07a15fff809 --- /dev/null +++ b/modules/mabidderBidAdapter.js @@ -0,0 +1,60 @@ +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; +const BIDDER_CODE = 'mabidder'; +export const baseUrl = 'https://prebid.ecdrsvc.com/bid'; +export const spec = { + supportedMediaTypes: [BANNER], + code: BIDDER_CODE, + isBidRequestValid: function(bid) { + if (typeof bid.params === 'undefined') { + return false; + } + return !!(bid.params.ppid && bid.sizes && Array.isArray(bid.sizes) && Array.isArray(bid.sizes[0])) + }, + buildRequests: function(validBidRequests, bidderRequest) { + const fpd = bidderRequest.ortb2; + const bids = []; + validBidRequests.forEach(bidRequest => { + const sizes = []; + bidRequest.sizes.forEach(size => { + sizes.push({ + width: size[0], + height: size[1] + }); + }); + bids.push({ + bidId: bidRequest.bidId, + sizes: sizes, + ppid: bidRequest.params.ppid, + mediaType: BANNER + }) + }); + const req = { + url: baseUrl, + method: 'POST', + data: { + v: $$PREBID_GLOBAL$$.version, + bids: bids, + url: bidderRequest.refererInfo.page || '', + referer: bidderRequest.refererInfo.ref || '', + fpd: fpd || {} + } + }; + + return req; + }, + interpretResponse: function(serverResponse, request) { + const bidResponses = []; + if (serverResponse.body) { + const body = serverResponse.body; + if (!body || typeof body !== 'object' || !body.Responses || !body.Responses.length > 0) { + return []; + } + body.Responses.forEach((bidResponse) => { + bidResponses.push(bidResponse); + }); + } + return bidResponses; + } +} +registerBidder(spec); \ No newline at end of file diff --git a/modules/mabidderBidAdapter.md b/modules/mabidderBidAdapter.md new file mode 100644 index 00000000000..ee57cb8cab2 --- /dev/null +++ b/modules/mabidderBidAdapter.md @@ -0,0 +1,31 @@ +#Overview + +``` +Module Name: mabidder Bid Adapter +Module Type: Bidder Adapter +Maintainer: lmprebidadapter@loblaw.ca +``` + +# Description + +Module that connects to MediaAisle demand sources + +# Test Parameters +``` +var adUnits = [ + { + code: 'test_banner', + mediaTypes: { + banner: { + sizes: [300, 250] + } + }, + bids: [{ + bidder: 'mabidder', + params: { + ppid: 'test' + } + }], + } +]; +``` diff --git a/package-lock.json b/package-lock.json index 0e221a988fd..32369f0c66c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -42000,4 +42000,4 @@ "dev": true } } -} +} \ No newline at end of file diff --git a/test/spec/modules/mabidderBidAdapter_spec.js b/test/spec/modules/mabidderBidAdapter_spec.js new file mode 100644 index 00000000000..cd9599b375c --- /dev/null +++ b/test/spec/modules/mabidderBidAdapter_spec.js @@ -0,0 +1,125 @@ +import { expect } from 'chai' +import { baseUrl, spec } from 'modules/mabidderBidAdapter.js' +import { newBidder } from 'src/adapters/bidderFactory.js' +import { BANNER } from '../../../src/mediaTypes.js'; + +describe('mabidderBidAdapter', () => { + const adapter = newBidder(spec) + const bidRequestBanner = { + 'bidId': '12345', + 'bidder': 'mabidder', + 'sizes': [[300, 250]], + 'mediaTypes': { + 'banner': { + 'sizes': [[300, 250]] + } + }, + 'params': { + 'ppid': 'string1', + } + + } + + describe('inherited functions', () => { + it('exists and is a function', () => { + expect(adapter.callBids).to.exist.and.to.be.a('function') + }) + }) + + describe('isBidRequestValid', () => { + it('should return true when required params are found', () => { + expect(spec.isBidRequestValid(bidRequestBanner)).to.equal(true) + }) + + it('should return false when required params are not found', () => { + let bid = Object.assign({}, bidRequestBanner) + const ppid = bid.params.ppid + delete bid.params.ppid + expect(spec.isBidRequestValid(bid)).to.equal(false) + bid.params.ppid = ppid + + bid = Object.assign({}, bidRequestBanner) + const params = bidRequestBanner.params + delete bid.params + expect(spec.isBidRequestValid(bid)).to.equal(false) + bidRequestBanner.params = params + }) + }) + + describe('buildRequests', () => { + const bidRequests = [bidRequestBanner] + const req = spec.buildRequests(bidRequests, { + auctionId: '123', + refererInfo: { + referer: 'http://test.com/path.html' + } + }) + + it('sends bid request to ENDPOINT via POST', () => { + expect(req.method).to.equal('POST') + expect(req.url.indexOf('https://')).to.equal(0) + expect(req.url).to.equal(baseUrl) + }) + + it('contains prebid version parameter', () => { + expect(req.data.v).to.equal($$PREBID_GLOBAL$$.version) + }) + + it('sends the correct bid parameters for banner', () => { + expect(req.data.bids[0].bidId).to.equal(bidRequestBanner.bidId) + expect(req.data.bids[0].ppid).to.equal(bidRequestBanner.params.ppid) + expect(req.data.bids[0].sizes[0].width).to.equal(bidRequestBanner.sizes[0][0]) + expect(req.data.bids[0].sizes[0].height).to.equal(bidRequestBanner.sizes[0][1]) + }) + + it('accepts an optional fpd parameter', () => { + expect(req.data.fpd).to.exist.and.to.be.a('Object') + }) + }) + + describe('interpretResponse', () => { + it('handles banner request and should get correct bid response', () => { + const BIDDER_RESPONSE_BANNER = { + 'Responses': [{ + 'width': 300, + 'height': 250, + 'creativeId': '123abc', + 'ad': '', + 'cpm': 0.5, + 'requestId': 'abc123', + 'ttl': 60, + 'netRevenue': true, + 'currency': 'USD', + 'mediaType': BANNER, + 'meta': { + 'advertiserDomains': ['https://loblaws.ca'] + } + }] + } + const results = spec.interpretResponse({ body: BIDDER_RESPONSE_BANNER }, {}) + const response = results[0] + expect(results.length).to.equal(BIDDER_RESPONSE_BANNER.Responses.length) + expect(response).to.have.property('ad').equal('') + expect(response).to.have.property('requestId').equal('abc123') + expect(response).to.have.property('cpm').equal(0.5) + expect(response).to.have.property('currency').equal('USD') + expect(response).to.have.property('width').equal(300) + expect(response).to.have.property('height').equal(250) + expect(response).to.have.property('ttl').equal(60) + expect(response).to.have.property('creativeId').equal('123abc') + expect(response).to.have.property('mediaType').equal(BANNER) + expect(response).to.have.property('meta') + expect(response.meta).to.have.property('advertiserDomains') + expect(response.meta.advertiserDomains).to.be.an('array') + expect(response.meta.advertiserDomains[0]).equal('https://loblaws.ca') + }) + + it('handles no bid response by returning empty array', () => { + let result = spec.interpretResponse({ body: undefined }, {}) + expect(result).to.deep.equal([]) + + result = spec.interpretResponse({ body: '' }, {}) + expect(result).to.deep.equal([]) + }) + }) +})