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"]