diff --git a/adapters/adoppler/adoppler.go b/adapters/adoppler/adoppler.go index c604bfeac06..77eedec1d71 100644 --- a/adapters/adoppler/adoppler.go +++ b/adapters/adoppler/adoppler.go @@ -6,13 +6,18 @@ import ( "fmt" "net/http" "net/url" + "text/template" + "github.com/golang/glog" "github.com/mxmCherry/openrtb" "github.com/prebid/prebid-server/adapters" "github.com/prebid/prebid-server/errortypes" + "github.com/prebid/prebid-server/macros" "github.com/prebid/prebid-server/openrtb_ext" ) +const DefaultClient = "app" + var bidHeaders http.Header = map[string][]string{ "Accept": {"application/json"}, "Content-Type": {"application/json;charset=utf-8"}, @@ -28,11 +33,17 @@ type adsImpExt struct { } type AdopplerAdapter struct { - endpoint string + endpoint *template.Template } func NewAdopplerBidder(endpoint string) *AdopplerAdapter { - return &AdopplerAdapter{endpoint} + t, err := template.New("endpoint").Parse(endpoint) + if err != nil { + glog.Fatalf("Unable to parse endpoint url template: %s", err) + return nil + } + + return &AdopplerAdapter{t} } func (ads *AdopplerAdapter) MakeRequests( @@ -65,8 +76,13 @@ func (ads *AdopplerAdapter) MakeRequests( continue } - uri := fmt.Sprintf("%s/processHeaderBid/%s", - ads.endpoint, url.PathEscape(ext.AdUnit)) + uri, err := ads.bidUri(ext) + if err != nil { + e := fmt.Sprintf("Unable to build bid URI: %s", + err.Error()) + errs = append(errs, &errortypes.BadInput{e}) + continue + } data := &adapters.RequestData{ Method: "POST", Uri: uri, @@ -172,6 +188,18 @@ func (ads *AdopplerAdapter) MakeBids( return adsResp, nil } +func (ads *AdopplerAdapter) bidUri(ext *openrtb_ext.ExtImpAdoppler) (string, error) { + params := macros.EndpointTemplateParams{} + params.AdUnit = url.PathEscape(ext.AdUnit) + if ext.Client == "" { + params.AccountID = DefaultClient + } else { + params.AccountID = url.PathEscape(ext.Client) + } + + return macros.ResolveMacros(*ads.endpoint, params) +} + func unmarshalExt(ext json.RawMessage) (*openrtb_ext.ExtImpAdoppler, error) { var bext adapters.ExtImpBidder err := json.Unmarshal(ext, &bext) diff --git a/adapters/adoppler/adoppler_test.go b/adapters/adoppler/adoppler_test.go index e7d908df4f1..646852a1b9b 100644 --- a/adapters/adoppler/adoppler_test.go +++ b/adapters/adoppler/adoppler_test.go @@ -7,6 +7,6 @@ import ( ) func TestJsonSamples(t *testing.T) { - bidder := NewAdopplerBidder("http://adoppler.com") + bidder := NewAdopplerBidder("http://{{.AccountID}}.trustedmarketplace.com/processHeaderBid/{{.AdUnit}}") adapterstest.RunJSONBidderTest(t, "adopplertest", bidder) } diff --git a/adapters/adoppler/adopplertest/exemplary/custom-client.json b/adapters/adoppler/adopplertest/exemplary/custom-client.json new file mode 100644 index 00000000000..6bb32f71546 --- /dev/null +++ b/adapters/adoppler/adopplertest/exemplary/custom-client.json @@ -0,0 +1,80 @@ +{ + "mockBidRequest":{ + "id":"req1", + "imp":[ + { + "id":"imp1", + "banner":{ + "w":100, + "h":200 + }, + "ext":{ + "bidder":{ + "adunit":"unit1", + "client":"client1" + } + } + } + ] + }, + "httpCalls":[ + { + "expectedRequest":{ + "uri":"http://client1.trustedmarketplace.com/processHeaderBid/unit1", + "body":{ + "id":"req1-unit1", + "imp":[ + { + "id":"imp1", + "banner":{ + "w":100, + "h":200 + }, + "ext":{ + "bidder":{ + "adunit":"unit1", + "client":"client1" + } + } + } + ] + } + }, + "mockResponse":{ + "status":200, + "body":{ + "id":"req1-unit1", + "seatbid":[ + { + "bid":[ + { + "id":"req1-unit1-bid1", + "impid":"imp1", + "price":0.12, + "adm":"An ad" + } + ] + } + ], + "cur":"USD" + } + } + } + ], + "expectedBidResponses":[ + { + "currency":"USD", + "bids":[ + { + "bid":{ + "id":"req1-unit1-bid1", + "impid":"imp1", + "price":0.12, + "adm":"An ad" + }, + "type":"banner" + } + ] + } + ] +} diff --git a/adapters/adoppler/adopplertest/exemplary/default-client.json b/adapters/adoppler/adopplertest/exemplary/default-client.json new file mode 100644 index 00000000000..25fb71970e0 --- /dev/null +++ b/adapters/adoppler/adopplertest/exemplary/default-client.json @@ -0,0 +1,78 @@ +{ + "mockBidRequest":{ + "id":"req1", + "imp":[ + { + "id":"imp1", + "banner":{ + "w":100, + "h":200 + }, + "ext":{ + "bidder":{ + "adunit":"unit1" + } + } + } + ] + }, + "httpCalls":[ + { + "expectedRequest":{ + "uri":"http://app.trustedmarketplace.com/processHeaderBid/unit1", + "body":{ + "id":"req1-unit1", + "imp":[ + { + "id":"imp1", + "banner":{ + "w":100, + "h":200 + }, + "ext":{ + "bidder":{ + "adunit":"unit1" + } + } + } + ] + } + }, + "mockResponse":{ + "status":200, + "body":{ + "id":"req1-unit1", + "seatbid":[ + { + "bid":[ + { + "id":"req1-unit1-bid1", + "impid":"imp1", + "price":0.12, + "adm":"An ad" + } + ] + } + ], + "cur":"USD" + } + } + } + ], + "expectedBidResponses":[ + { + "currency":"USD", + "bids":[ + { + "bid":{ + "id":"req1-unit1-bid1", + "impid":"imp1", + "price":0.12, + "adm":"An ad" + }, + "type":"banner" + } + ] + } + ] +} diff --git a/adapters/adoppler/adopplertest/exemplary/multibid.json b/adapters/adoppler/adopplertest/exemplary/multibid.json deleted file mode 100644 index 851f4c5b917..00000000000 --- a/adapters/adoppler/adopplertest/exemplary/multibid.json +++ /dev/null @@ -1,60 +0,0 @@ -{"mockBidRequest": {"id": "req1", - "imp":[{"id": "imp1", - "banner": {"w": 100, - "h": 200}, - "ext": {"bidder": {"adunit": "unit1"}}}, - {"id": "imp2", - "video": {"minduration": 120, - "mimes": ["video/mp4"]}, - "ext": {"bidder": {"adunit": "unit2"}}}, - {"id": "imp3", - "native": {"request": "{}"}, - "ext": {"bidder": {"adunit": "unit3"}}}]}, - "httpCalls": [{"expectedRequest": {"uri": "http://adoppler.com/processHeaderBid/unit1", - "body": {"id": "req1-unit1", - "imp": [{"id": "imp1", - "banner": {"w": 100, "h": 200}, - "ext": {"bidder": {"adunit": "unit1"}}}]}}, - "mockResponse": {"status": 200, - "body": {"id": "req1-imp1-resp1", - "seatbid": [{"bid": [{"id": "req1-imp1-bid1", - "impid": "imp1", - "price": 0.12, - "adm": "a banner"}]}], - "cur": "USD"}}}, - {"expectedRequest": {"uri": "http://adoppler.com/processHeaderBid/unit2", - "body": {"id": "req1-unit2", - "imp": [{"id": "imp2", - "video": {"minduration": 120, - "mimes": ["video/mp4"]}, - "ext": {"bidder": {"adunit": "unit2"}}}]}}, - "mockResponse": {"status": 200, - "body": {"id": "req1-imp2-resp2", - "seatbid": [{"bid": [{"id": "req1-imp2-bid1", - "impid": "imp2", - "price": 0.24, - "adm": "", - "cat": ["IAB1", "IAB2"], - "ext": {"ads": {"video": {"duration": 121}}}}]}], - "cur": "USD"}}}, - {"expectedRequest": {"uri": "http://adoppler.com/processHeaderBid/unit3", - "body": {"id": "req1-unit3", - "imp": [{"id": "imp3", - "native": {"request": "{}"}, - "ext": {"bidder": {"adunit": "unit3"}}}]}}, - "mockResponse": {"status": 204, - "body": ""}}], - "expectedBidResponses": [{"currency": "USD", - "bids": [{"bid": {"id": "req1-imp1-bid1", - "impid": "imp1", - "price": 0.12, - "adm": "a banner"}, - "type": "banner"}]}, - {"currency": "USD", - "bids": [{"bid": {"id": "req1-imp2-bid1", - "impid": "imp2", - "price": 0.24, - "adm": "", - "cat": ["IAB1", "IAB2"], - "ext": {"ads": {"video": {"duration": 121}}}}, - "type": "video"}]}]} diff --git a/adapters/adoppler/adopplertest/exemplary/multiimp.json b/adapters/adoppler/adopplertest/exemplary/multiimp.json new file mode 100644 index 00000000000..6eebbe43071 --- /dev/null +++ b/adapters/adoppler/adopplertest/exemplary/multiimp.json @@ -0,0 +1,207 @@ +{ + "mockBidRequest":{ + "id":"req1", + "imp":[ + { + "id":"imp1", + "banner":{ + "w":100, + "h":200 + }, + "ext":{ + "bidder":{ + "adunit":"unit1" + } + } + }, + { + "id":"imp2", + "video":{ + "minduration":120, + "mimes":[ + "video/mp4" + ] + }, + "ext":{ + "bidder":{ + "adunit":"unit2" + } + } + }, + { + "id":"imp3", + "native":{ + "request":"{}" + }, + "ext":{ + "bidder":{ + "adunit":"unit3" + } + } + } + ] + }, + "httpCalls":[ + { + "expectedRequest":{ + "uri":"http://app.trustedmarketplace.com/processHeaderBid/unit1", + "body":{ + "id":"req1-unit1", + "imp":[ + { + "id":"imp1", + "banner":{ + "w":100, + "h":200 + }, + "ext":{ + "bidder":{ + "adunit":"unit1" + } + } + } + ] + } + }, + "mockResponse":{ + "status":200, + "body":{ + "id":"req1-imp1-resp1", + "seatbid":[ + { + "bid":[ + { + "id":"req1-imp1-bid1", + "impid":"imp1", + "price":0.12, + "adm":"a banner" + } + ] + } + ], + "cur":"USD" + } + } + }, + { + "expectedRequest":{ + "uri":"http://app.trustedmarketplace.com/processHeaderBid/unit2", + "body":{ + "id":"req1-unit2", + "imp":[ + { + "id":"imp2", + "video":{ + "minduration":120, + "mimes":[ + "video/mp4" + ] + }, + "ext":{ + "bidder":{ + "adunit":"unit2" + } + } + } + ] + } + }, + "mockResponse":{ + "status":200, + "body":{ + "id":"req1-imp2-resp2", + "seatbid":[ + { + "bid":[ + { + "id":"req1-imp2-bid1", + "impid":"imp2", + "price":0.24, + "adm":"", + "cat":[ + "IAB1", + "IAB2" + ], + "ext":{ + "ads":{ + "video":{ + "duration":121 + } + } + } + } + ] + } + ], + "cur":"USD" + } + } + }, + { + "expectedRequest":{ + "uri":"http://app.trustedmarketplace.com/processHeaderBid/unit3", + "body":{ + "id":"req1-unit3", + "imp":[ + { + "id":"imp3", + "native":{ + "request":"{}" + }, + "ext":{ + "bidder":{ + "adunit":"unit3" + } + } + } + ] + } + }, + "mockResponse":{ + "status":204, + "body":"" + } + } + ], + "expectedBidResponses":[ + { + "currency":"USD", + "bids":[ + { + "bid":{ + "id":"req1-imp1-bid1", + "impid":"imp1", + "price":0.12, + "adm":"a banner" + }, + "type":"banner" + } + ] + }, + { + "currency":"USD", + "bids":[ + { + "bid":{ + "id":"req1-imp2-bid1", + "impid":"imp2", + "price":0.24, + "adm":"", + "cat":[ + "IAB1", + "IAB2" + ], + "ext":{ + "ads":{ + "video":{ + "duration":121 + } + } + } + }, + "type":"video" + } + ] + } + ] +} diff --git a/adapters/adoppler/adopplertest/exemplary/no-bid.json b/adapters/adoppler/adopplertest/exemplary/no-bid.json deleted file mode 100644 index 0e0f13586a8..00000000000 --- a/adapters/adoppler/adopplertest/exemplary/no-bid.json +++ /dev/null @@ -1,13 +0,0 @@ -{"mockBidRequest": {"id": "req1", - "imp":[{"id": "imp1", - "banner": {"w": 100, - "h": 200}, - "ext": {"bidder": {"adunit": "unit1"}}}]}, - "httpCalls": [{"expectedRequest": {"uri": "http://adoppler.com/processHeaderBid/unit1", - "body": {"id": "req1-unit1", - "imp": [{"id": "imp1", - "banner": {"w": 100, "h": 200}, - "ext": {"bidder": {"adunit": "unit1"}}}]}}, - "mockResponse": {"status": 204, - "body": ""}}], - "expectedBidResponses": []} diff --git a/adapters/adoppler/adopplertest/supplemental/bad-request.json b/adapters/adoppler/adopplertest/supplemental/bad-request.json index 3bdd5a5544e..ae515e01e18 100644 --- a/adapters/adoppler/adopplertest/supplemental/bad-request.json +++ b/adapters/adoppler/adopplertest/supplemental/bad-request.json @@ -1,15 +1,56 @@ -{"mockBidRequest": {"id": "req1", - "imp":[{"id": "imp1", - "banner": {"w": 100, - "h": 200}, - "ext": {"bidder": {"adunit": "unit1"}}}]}, - "httpCalls": [{"expectedRequest": {"uri": "http://adoppler.com/processHeaderBid/unit1", - "body": {"id": "req1-unit1", - "imp": [{"id": "imp1", - "banner": {"w": 100, "h": 200}, - "ext": {"bidder": {"adunit": "unit1"}}}]}}, - "mockResponse": {"status": 400, - "body": ""}}], - "expectedBidResponses": [], - "expectedMakeBidsErrors": [{"value": "bad request", - "comparison": "literal"}]} +{ + "mockBidRequest":{ + "id":"req1", + "imp":[ + { + "id":"imp1", + "banner":{ + "w":100, + "h":200 + }, + "ext":{ + "bidder":{ + "adunit":"unit1" + } + } + } + ] + }, + "httpCalls":[ + { + "expectedRequest":{ + "uri":"http://app.trustedmarketplace.com/processHeaderBid/unit1", + "body":{ + "id":"req1-unit1", + "imp":[ + { + "id":"imp1", + "banner":{ + "w":100, + "h":200 + }, + "ext":{ + "bidder":{ + "adunit":"unit1" + } + } + } + ] + } + }, + "mockResponse":{ + "status":400, + "body":"" + } + } + ], + "expectedBidResponses":[ + + ], + "expectedMakeBidsErrors":[ + { + "value":"bad request", + "comparison":"literal" + } + ] +} diff --git a/adapters/adoppler/adopplertest/supplemental/duplicate-imp.json b/adapters/adoppler/adopplertest/supplemental/duplicate-imp.json index 4382e36c54e..d6f17a6bb2c 100644 --- a/adapters/adoppler/adopplertest/supplemental/duplicate-imp.json +++ b/adapters/adoppler/adopplertest/supplemental/duplicate-imp.json @@ -1,38 +1,128 @@ -{"mockBidRequest": {"id": "req1", - "imp":[{"id": "imp1", - "banner": {"w": 100, - "h": 200}, - "ext": {"bidder": {"adunit": "unit1"}}}, - {"id": "imp1", - "banner": {"w": 100, - "h": 200}, - "ext": {"bidder": {"adunit": "unit2"}}}]}, - "httpCalls": [{"expectedRequest": {"uri": "http://adoppler.com/processHeaderBid/unit1", - "body": {"id": "req1-unit1", - "imp": [{"id": "imp1", - "banner": {"w": 100, "h": 200}, - "ext": {"bidder": {"adunit": "unit1"}}}]}}, - "mockResponse": {"status": 200, - "body": {"id": "req1-imp1-resp1", - "seatbid": [{"bid": [{"id": "req1-imp1-bid1", - "impid": "imp1", - "price": 0.12, - "adm": "a banner"}]}], - "cur": "USD"}}}, - {"expectedRequest": {"uri": "http://adoppler.com/processHeaderBid/unit2", - "body": {"id": "req1-unit2", - "imp": [{"id": "imp1", - "banner": {"w": 100, "h": 200}, - "ext": {"bidder": {"adunit": "unit2"}}}]}}, - "mockResponse": {"status": 200, - "body": {"id": "req1-imp1-resp1", - "seatbid": [{"bid": [{"id": "req1-imp1-bid1", - "impid": "imp1", - "price": 0.12, - "adm": "a banner"}]}], - "cur": "USD"}}}], - "expectedBidResponses": [], - "expectedMakeBidsErrors": [{"value": "duplicate $.imp.id imp1", - "comparison": "literal"}, - {"value": "duplicate $.imp.id imp1", - "comparison": "literal"}]} +{ + "mockBidRequest":{ + "id":"req1", + "imp":[ + { + "id":"imp1", + "banner":{ + "w":100, + "h":200 + }, + "ext":{ + "bidder":{ + "adunit":"unit1" + } + } + }, + { + "id":"imp1", + "banner":{ + "w":100, + "h":200 + }, + "ext":{ + "bidder":{ + "adunit":"unit2" + } + } + } + ] + }, + "httpCalls":[ + { + "expectedRequest":{ + "uri":"http://app.trustedmarketplace.com/processHeaderBid/unit1", + "body":{ + "id":"req1-unit1", + "imp":[ + { + "id":"imp1", + "banner":{ + "w":100, + "h":200 + }, + "ext":{ + "bidder":{ + "adunit":"unit1" + } + } + } + ] + } + }, + "mockResponse":{ + "status":200, + "body":{ + "id":"req1-imp1-resp1", + "seatbid":[ + { + "bid":[ + { + "id":"req1-imp1-bid1", + "impid":"imp1", + "price":0.12, + "adm":"a banner" + } + ] + } + ], + "cur":"USD" + } + } + }, + { + "expectedRequest":{ + "uri":"http://app.trustedmarketplace.com/processHeaderBid/unit2", + "body":{ + "id":"req1-unit2", + "imp":[ + { + "id":"imp1", + "banner":{ + "w":100, + "h":200 + }, + "ext":{ + "bidder":{ + "adunit":"unit2" + } + } + } + ] + } + }, + "mockResponse":{ + "status":200, + "body":{ + "id":"req1-imp1-resp1", + "seatbid":[ + { + "bid":[ + { + "id":"req1-imp1-bid1", + "impid":"imp1", + "price":0.12, + "adm":"a banner" + } + ] + } + ], + "cur":"USD" + } + } + } + ], + "expectedBidResponses":[ + + ], + "expectedMakeBidsErrors":[ + { + "value":"duplicate $.imp.id imp1", + "comparison":"literal" + }, + { + "value":"duplicate $.imp.id imp1", + "comparison":"literal" + } + ] +} diff --git a/adapters/adoppler/adopplertest/supplemental/invalid-impid.json b/adapters/adoppler/adopplertest/supplemental/invalid-impid.json index 2e6ecf4a96c..b5f062ac94a 100644 --- a/adapters/adoppler/adopplertest/supplemental/invalid-impid.json +++ b/adapters/adoppler/adopplertest/supplemental/invalid-impid.json @@ -1,20 +1,71 @@ -{"mockBidRequest": {"id": "req1", - "imp":[{"id": "imp1", - "banner": {"w": 100, - "h": 200}, - "ext": {"bidder": {"adunit": "unit1"}}}]}, - "httpCalls": [{"expectedRequest": {"uri": "http://adoppler.com/processHeaderBid/unit1", - "body": {"id": "req1-unit1", - "imp": [{"id": "imp1", - "banner": {"w": 100, "h": 200}, - "ext": {"bidder": {"adunit": "unit1"}}}]}}, - "mockResponse": {"status": 200, - "body": {"id": "req1-imp1-resp1", - "seatbid": [{"bid": [{"id": "req1-imp1-bid1", - "impid": "invalid", - "price": 0.12, - "adm": "a banner"}]}], - "cur": "USD"}}}], - "expectedBidResponses": [], - "expectedMakeBidsErrors": [{"value": "unknown impid: invalid", - "comparison": "literal"}]} +{ + "mockBidRequest":{ + "id":"req1", + "imp":[ + { + "id":"imp1", + "banner":{ + "w":100, + "h":200 + }, + "ext":{ + "bidder":{ + "adunit":"unit1" + } + } + } + ] + }, + "httpCalls":[ + { + "expectedRequest":{ + "uri":"http://app.trustedmarketplace.com/processHeaderBid/unit1", + "body":{ + "id":"req1-unit1", + "imp":[ + { + "id":"imp1", + "banner":{ + "w":100, + "h":200 + }, + "ext":{ + "bidder":{ + "adunit":"unit1" + } + } + } + ] + } + }, + "mockResponse":{ + "status":200, + "body":{ + "id":"req1-imp1-resp1", + "seatbid":[ + { + "bid":[ + { + "id":"req1-imp1-bid1", + "impid":"invalid", + "price":0.12, + "adm":"a banner" + } + ] + } + ], + "cur":"USD" + } + } + } + ], + "expectedBidResponses":[ + + ], + "expectedMakeBidsErrors":[ + { + "value":"unknown impid: invalid", + "comparison":"literal" + } + ] +} diff --git a/adapters/adoppler/adopplertest/supplemental/invalid-response.json b/adapters/adoppler/adopplertest/supplemental/invalid-response.json index 72420881aec..d0a7d2ef84b 100644 --- a/adapters/adoppler/adopplertest/supplemental/invalid-response.json +++ b/adapters/adoppler/adopplertest/supplemental/invalid-response.json @@ -1,15 +1,56 @@ -{"mockBidRequest": {"id": "req1", - "imp":[{"id": "imp1", - "banner": {"w": 100, - "h": 200}, - "ext": {"bidder": {"adunit": "unit1"}}}]}, - "httpCalls": [{"expectedRequest": {"uri": "http://adoppler.com/processHeaderBid/unit1", - "body": {"id": "req1-unit1", - "imp": [{"id": "imp1", - "banner": {"w": 100, "h": 200}, - "ext": {"bidder": {"adunit": "unit1"}}}]}}, - "mockResponse": {"status": 200, - "body": "invalid-json"}}], - "expectedBidResponses": [], - "expectedMakeBidsErrors": [{"value": "invalid body: json: cannot unmarshal string into Go value of type openrtb.BidResponse", - "comparison": "literal"}]} +{ + "mockBidRequest":{ + "id":"req1", + "imp":[ + { + "id":"imp1", + "banner":{ + "w":100, + "h":200 + }, + "ext":{ + "bidder":{ + "adunit":"unit1" + } + } + } + ] + }, + "httpCalls":[ + { + "expectedRequest":{ + "uri":"http://app.trustedmarketplace.com/processHeaderBid/unit1", + "body":{ + "id":"req1-unit1", + "imp":[ + { + "id":"imp1", + "banner":{ + "w":100, + "h":200 + }, + "ext":{ + "bidder":{ + "adunit":"unit1" + } + } + } + ] + } + }, + "mockResponse":{ + "status":200, + "body":"invalid-json" + } + } + ], + "expectedBidResponses":[ + + ], + "expectedMakeBidsErrors":[ + { + "value":"invalid body: json: cannot unmarshal string into Go value of type openrtb.BidResponse", + "comparison":"literal" + } + ] +} diff --git a/adapters/adoppler/adopplertest/supplemental/invalid-video-ext.json b/adapters/adoppler/adopplertest/supplemental/invalid-video-ext.json index d9cb6daa55d..c08cdca5cee 100644 --- a/adapters/adoppler/adopplertest/supplemental/invalid-video-ext.json +++ b/adapters/adoppler/adopplertest/supplemental/invalid-video-ext.json @@ -1,43 +1,145 @@ -{"mockBidRequest": {"id": "req1", - "imp":[{"id": "imp1", - "video": {"minduration": 120, - "mimes": ["video/mp4"]}, - "ext": {"bidder": {"adunit": "unit1"}}}, - {"id": "imp2", - "video": {"minduration": 120, - "mimes": ["video/mp4"]}, - "ext": {"bidder": {"adunit": "unit2"}}}]}, - "httpCalls": [{"expectedRequest": {"uri": "http://adoppler.com/processHeaderBid/unit1", - "body": {"id": "req1-unit1", - "imp": [{"id": "imp1", - "video": {"minduration": 120, - "mimes": ["video/mp4"]}, - "ext": {"bidder": {"adunit": "unit1"}}}]}}, - "mockResponse": {"status": 200, - "body": {"id": "req1-imp1-resp1", - "seatbid": [{"bid": [{"id": "req1-imp1-bid1", - "impid": "imp1", - "price": 0.24, - "adm": "", - "cat": ["IAB1", "IAB2"], - "ext": {}}]}], - "cur": "USD"}}}, - {"expectedRequest": {"uri": "http://adoppler.com/processHeaderBid/unit2", - "body": {"id": "req1-unit2", - "imp": [{"id": "imp2", - "video": {"minduration": 120, - "mimes": ["video/mp4"]}, - "ext": {"bidder": {"adunit": "unit2"}}}]}}, - "mockResponse": {"status": 200, - "body": {"id": "req1-imp2-resp2", - "seatbid": [{"bid": [{"id": "req1-imp2-bid2", - "impid": "imp2", - "price": 0.24, - "adm": "", - "cat": ["IAB1", "IAB2"], - "ext": ""}]}], - "cur": "USD"}}}], - "expectedMakeBidsErrors": [{"value": "$.seatbid.bid.ext.ads.video required", - "comparison": "literal"}, - {"value": "json: cannot unmarshal string into Go value of type struct { Ads *adoppler.adsImpExt \"json:\\\"ads\\\"\" }", - "comparison": "literal"}]} +{ + "mockBidRequest":{ + "id":"req1", + "imp":[ + { + "id":"imp1", + "video":{ + "minduration":120, + "mimes":[ + "video/mp4" + ] + }, + "ext":{ + "bidder":{ + "adunit":"unit1" + } + } + }, + { + "id":"imp2", + "video":{ + "minduration":120, + "mimes":[ + "video/mp4" + ] + }, + "ext":{ + "bidder":{ + "adunit":"unit2" + } + } + } + ] + }, + "httpCalls":[ + { + "expectedRequest":{ + "uri":"http://app.trustedmarketplace.com/processHeaderBid/unit1", + "body":{ + "id":"req1-unit1", + "imp":[ + { + "id":"imp1", + "video":{ + "minduration":120, + "mimes":[ + "video/mp4" + ] + }, + "ext":{ + "bidder":{ + "adunit":"unit1" + } + } + } + ] + } + }, + "mockResponse":{ + "status":200, + "body":{ + "id":"req1-imp1-resp1", + "seatbid":[ + { + "bid":[ + { + "id":"req1-imp1-bid1", + "impid":"imp1", + "price":0.24, + "adm":"", + "cat":[ + "IAB1", + "IAB2" + ], + "ext":{ + + } + } + ] + } + ], + "cur":"USD" + } + } + }, + { + "expectedRequest":{ + "uri":"http://app.trustedmarketplace.com/processHeaderBid/unit2", + "body":{ + "id":"req1-unit2", + "imp":[ + { + "id":"imp2", + "video":{ + "minduration":120, + "mimes":[ + "video/mp4" + ] + }, + "ext":{ + "bidder":{ + "adunit":"unit2" + } + } + } + ] + } + }, + "mockResponse":{ + "status":200, + "body":{ + "id":"req1-imp2-resp2", + "seatbid":[ + { + "bid":[ + { + "id":"req1-imp2-bid2", + "impid":"imp2", + "price":0.24, + "adm":"", + "cat":[ + "IAB1", + "IAB2" + ], + "ext":"" + } + ] + } + ], + "cur":"USD" + } + } + } + ], + "expectedMakeBidsErrors":[ + { + "value":"$.seatbid.bid.ext.ads.video required", + "comparison":"literal" + }, + { + "value":"json: cannot unmarshal string into Go value of type struct { Ads *adoppler.adsImpExt \"json:\\\"ads\\\"\" }", + "comparison":"literal" + } + ] +} diff --git a/adapters/adoppler/adopplertest/supplemental/missing-adunit.json b/adapters/adoppler/adopplertest/supplemental/missing-adunit.json index 82a6a95ed58..df9bbe5771d 100644 --- a/adapters/adoppler/adopplertest/supplemental/missing-adunit.json +++ b/adapters/adoppler/adopplertest/supplemental/missing-adunit.json @@ -1,9 +1,31 @@ -{"mockBidRequest": {"id": "req1", - "imp":[{"id": "imp1", - "banner": {"w": 100, - "h": 200}, - "ext": {"bidder": {}}}]}, - "httpCalls": [], - "expectedBidResponses": [], - "expectedMakeRequestsErrors": [{"value": "$.imp.ext.adoppler.adunit required", - "comparison": "literal"}]} +{ + "mockBidRequest":{ + "id":"req1", + "imp":[ + { + "id":"imp1", + "banner":{ + "w":100, + "h":200 + }, + "ext":{ + "bidder":{ + + } + } + } + ] + }, + "httpCalls":[ + + ], + "expectedBidResponses":[ + + ], + "expectedMakeRequestsErrors":[ + { + "value":"$.imp.ext.adoppler.adunit required", + "comparison":"literal" + } + ] +} diff --git a/adapters/adoppler/adopplertest/supplemental/no-bid.json b/adapters/adoppler/adopplertest/supplemental/no-bid.json new file mode 100644 index 00000000000..08a29481350 --- /dev/null +++ b/adapters/adoppler/adopplertest/supplemental/no-bid.json @@ -0,0 +1,50 @@ +{ + "mockBidRequest":{ + "id":"req1", + "imp":[ + { + "id":"imp1", + "banner":{ + "w":100, + "h":200 + }, + "ext":{ + "bidder":{ + "adunit":"unit1" + } + } + } + ] + }, + "httpCalls":[ + { + "expectedRequest":{ + "uri":"http://app.trustedmarketplace.com/processHeaderBid/unit1", + "body":{ + "id":"req1-unit1", + "imp":[ + { + "id":"imp1", + "banner":{ + "w":100, + "h":200 + }, + "ext":{ + "bidder":{ + "adunit":"unit1" + } + } + } + ] + } + }, + "mockResponse":{ + "status":204, + "body":"" + } + } + ], + "expectedBidResponses":[ + + ] +} diff --git a/adapters/adoppler/adopplertest/supplemental/server-error.json b/adapters/adoppler/adopplertest/supplemental/server-error.json index df23bac07df..604b83e74a6 100644 --- a/adapters/adoppler/adopplertest/supplemental/server-error.json +++ b/adapters/adoppler/adopplertest/supplemental/server-error.json @@ -1,15 +1,56 @@ -{"mockBidRequest": {"id": "req1", - "imp":[{"id": "imp1", - "banner": {"w": 100, - "h": 200}, - "ext": {"bidder": {"adunit": "unit1"}}}]}, - "httpCalls": [{"expectedRequest": {"uri": "http://adoppler.com/processHeaderBid/unit1", - "body": {"id": "req1-unit1", - "imp": [{"id": "imp1", - "banner": {"w": 100, "h": 200}, - "ext": {"bidder": {"adunit": "unit1"}}}]}}, - "mockResponse": {"status": 500, - "body": ""}}], - "expectedBidResponses": [], - "expectedMakeBidsErrors": [{"value": "unexpected status: 500", - "comparison": "literal"}]} +{ + "mockBidRequest":{ + "id":"req1", + "imp":[ + { + "id":"imp1", + "banner":{ + "w":100, + "h":200 + }, + "ext":{ + "bidder":{ + "adunit":"unit1" + } + } + } + ] + }, + "httpCalls":[ + { + "expectedRequest":{ + "uri":"http://app.trustedmarketplace.com/processHeaderBid/unit1", + "body":{ + "id":"req1-unit1", + "imp":[ + { + "id":"imp1", + "banner":{ + "w":100, + "h":200 + }, + "ext":{ + "bidder":{ + "adunit":"unit1" + } + } + } + ] + } + }, + "mockResponse":{ + "status":500, + "body":"" + } + } + ], + "expectedBidResponses":[ + + ], + "expectedMakeBidsErrors":[ + { + "value":"unexpected status: 500", + "comparison":"literal" + } + ] +} diff --git a/config/config.go b/config/config.go index c693b6f16f2..6d8fdbc070d 100755 --- a/config/config.go +++ b/config/config.go @@ -402,7 +402,11 @@ func validateAdapterEndpoint(endpoint string, adapterName string, errs configErr return append(errs, fmt.Errorf("Invalid endpoint template: %s for adapter: %s. %v", endpoint, adapterName, err)) } // Resolve macros (if any) in the endpoint URL - resolvedEndpoint, err := macros.ResolveMacros(*endpointTemplate, macros.EndpointTemplateParams{Host: dummyHost, PublisherID: dummyPublisherID, AccountID: dummyAccountID}) + resolvedEndpoint, err := macros.ResolveMacros(*endpointTemplate, macros.EndpointTemplateParams{ + Host: dummyHost, + PublisherID: dummyPublisherID, + AccountID: dummyAccountID, + }) if err != nil { return append(errs, fmt.Errorf("Unable to resolve endpoint: %s for adapter: %s. %v", endpoint, adapterName, err)) } @@ -928,7 +932,7 @@ func SetupViper(v *viper.Viper, filename string) { v.SetDefault("adapters.adman.endpoint", "http://pub.admanmedia.com/?c=o&m=ortb") v.SetDefault("adapters.admixer.endpoint", "http://inv-nets.admixer.net/pbs.aspx") v.SetDefault("adapters.adocean.endpoint", "https://{{.Host}}") - v.SetDefault("adapters.adoppler.endpoint", "http://app.trustedmarketplace.io/ads") + v.SetDefault("adapters.adoppler.endpoint", "http://{{.AccountID}}.trustedmarketplace.io/ads/processHeaderBid/{{.AdUnit}}") v.SetDefault("adapters.adpone.endpoint", "http://rtb.adpone.com/bid-request?src=prebid_server") v.SetDefault("adapters.adprime.endpoint", "http://delta.adprime.com/?c=o&m=ortb") v.SetDefault("adapters.adtarget.endpoint", "http://ghb.console.adtarget.com.tr/pbs/ortb") diff --git a/macros/macros.go b/macros/macros.go index a9f77ea95fa..5d6bd7af65e 100644 --- a/macros/macros.go +++ b/macros/macros.go @@ -12,6 +12,7 @@ type EndpointTemplateParams struct { ZoneID string SourceId string AccountID string + AdUnit string } // UserSyncTemplateParams specifies params for an user sync URL template diff --git a/openrtb_ext/imp_adoppler.go b/openrtb_ext/imp_adoppler.go index 4b3ba97ce05..9d4d5e5ca01 100644 --- a/openrtb_ext/imp_adoppler.go +++ b/openrtb_ext/imp_adoppler.go @@ -1,5 +1,6 @@ package openrtb_ext type ExtImpAdoppler struct { + Client string `json:"client"` AdUnit string `json:"adunit"` } diff --git a/static/bidder-params/adoppler.json b/static/bidder-params/adoppler.json index c2bdde4f60f..508eef478c0 100644 --- a/static/bidder-params/adoppler.json +++ b/static/bidder-params/adoppler.json @@ -7,6 +7,10 @@ "adunit": { "type": "string", "description": "AdUnit to bid against to." + }, + "client": { + "type": "string", + "description": "Client name." } }, "required": ["adunit"]