diff --git a/adapters/adagio/adagio.go b/adapters/adagio/adagio.go
new file mode 100644
index 00000000000..0da4d6ac9e4
--- /dev/null
+++ b/adapters/adagio/adagio.go
@@ -0,0 +1,139 @@
+package adagio
+
+import (
+ "bytes"
+ "compress/gzip"
+ "encoding/json"
+ "fmt"
+ "github.com/mxmCherry/openrtb/v15/openrtb2"
+ "github.com/prebid/prebid-server/adapters"
+ "github.com/prebid/prebid-server/config"
+ "github.com/prebid/prebid-server/errortypes"
+ "github.com/prebid/prebid-server/openrtb_ext"
+ "net/http"
+)
+
+// Builder builds a new instance of the Adagio adapter for the given bidder with the given config.
+func Builder(bidderName openrtb_ext.BidderName, config config.Adapter) (adapters.Bidder, error) {
+ bidder := &adapter{
+ endpoint: config.Endpoint,
+ }
+ return bidder, nil
+}
+
+type adapter struct {
+ endpoint string
+}
+
+type extBid struct {
+ Prebid *openrtb_ext.ExtBidPrebid
+}
+
+// MakeRequests prepares the HTTP requests which should be made to fetch bids.
+func (a *adapter) MakeRequests(request *openrtb2.BidRequest, _ *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
+ json, err := json.Marshal(request)
+ if err != nil {
+ return nil, []error{err}
+ }
+
+ headers := http.Header{}
+ headers.Add("Content-Type", "application/json;charset=utf-8")
+ headers.Add("Accept", "application/json")
+
+ if request.Device != nil {
+ if len(request.Device.IPv6) > 0 {
+ headers.Add("X-Forwarded-For", request.Device.IPv6)
+ }
+ if len(request.Device.IP) > 0 {
+ headers.Add("X-Forwarded-For", request.Device.IP)
+ }
+ }
+
+ if request.Test == 0 {
+ // Gzip the body
+ // Note: Gzipping could be handled natively later: https://github.com/prebid/prebid-server/issues/1812
+ var bodyBuf bytes.Buffer
+ gz := gzip.NewWriter(&bodyBuf)
+ if _, err = gz.Write(json); err == nil {
+ if err = gz.Close(); err == nil {
+ json = bodyBuf.Bytes()
+ headers.Add("Content-Encoding", "gzip")
+ // /!\ Go already sets the `Accept-Encoding: gzip` header. Never add it manually, or Go won't decompress the response.
+ //headers.Add("Accept-Encoding", "gzip")
+ }
+ }
+ }
+
+ requestToBidder := &adapters.RequestData{
+ Method: "POST",
+ Uri: a.endpoint,
+ Body: json,
+ Headers: headers,
+ }
+
+ return []*adapters.RequestData{requestToBidder}, nil
+}
+
+const unexpectedStatusCodeFormat = "Unexpected status code: %d. Run with request.debug = 1 for more info"
+
+// MakeBids unpacks the server's response into Bids.
+func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, _ *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) {
+ switch response.StatusCode {
+ case http.StatusOK:
+ break
+ case http.StatusNoContent:
+ return nil, nil
+ case http.StatusServiceUnavailable:
+ fallthrough
+ case http.StatusBadRequest:
+ fallthrough
+ case http.StatusUnauthorized:
+ fallthrough
+ case http.StatusForbidden:
+ err := &errortypes.BadInput{
+ Message: fmt.Sprintf(unexpectedStatusCodeFormat, response.StatusCode),
+ }
+ return nil, []error{err}
+ default:
+ err := &errortypes.BadServerResponse{
+ Message: fmt.Sprintf(unexpectedStatusCodeFormat, response.StatusCode),
+ }
+ return nil, []error{err}
+ }
+
+ var openRTBBidderResponse openrtb2.BidResponse
+ if err := json.Unmarshal(response.Body, &openRTBBidderResponse); err != nil {
+ return nil, []error{err}
+ }
+
+ bidsCapacity := len(internalRequest.Imp)
+ errs := make([]error, 0, bidsCapacity)
+ bidderResponse := adapters.NewBidderResponseWithBidsCapacity(bidsCapacity)
+ var typedBid *adapters.TypedBid
+ for _, seatBid := range openRTBBidderResponse.SeatBid {
+ for _, bid := range seatBid.Bid {
+ activeBid := bid
+
+ activeExt := &extBid{}
+ if err := json.Unmarshal(activeBid.Ext, activeExt); err != nil {
+ errs = append(errs, err)
+ }
+
+ var bidType openrtb_ext.BidType
+ if activeExt.Prebid != nil && activeExt.Prebid.Type != "" {
+ bidType = activeExt.Prebid.Type
+ } else {
+ err := &errortypes.BadServerResponse{
+ Message: fmt.Sprintf("Failed to find native/banner/video mediaType \"%s\" ", activeBid.ImpID),
+ }
+ errs = append(errs, err)
+ continue
+ }
+
+ typedBid = &adapters.TypedBid{Bid: &activeBid, BidType: bidType}
+ bidderResponse.Bids = append(bidderResponse.Bids, typedBid)
+ }
+ }
+
+ return bidderResponse, nil
+}
diff --git a/adapters/adagio/adagio_test.go b/adapters/adagio/adagio_test.go
new file mode 100644
index 00000000000..d5e25c7836d
--- /dev/null
+++ b/adapters/adagio/adagio_test.go
@@ -0,0 +1,75 @@
+package adagio
+
+import (
+ "encoding/json"
+ "github.com/mxmCherry/openrtb/v15/openrtb2"
+ "github.com/stretchr/testify/assert"
+ "testing"
+
+ "github.com/prebid/prebid-server/adapters/adapterstest"
+ "github.com/prebid/prebid-server/config"
+ "github.com/prebid/prebid-server/openrtb_ext"
+)
+
+func buildFakeBidRequest() openrtb2.BidRequest {
+ imp1 := openrtb2.Imp{
+ ID: "some-impression-id",
+ Banner: &openrtb2.Banner{},
+ Ext: json.RawMessage(`{"bidder": {"organizationId": "1000", "site": "site-name", "placement": "ban_atf"}}`),
+ }
+
+ fakeBidRequest := openrtb2.BidRequest{
+ ID: "some-request-id",
+ Imp: []openrtb2.Imp{imp1},
+ }
+
+ return fakeBidRequest
+}
+
+func TestJsonSamples(t *testing.T) {
+ bidder, buildErr := Builder(openrtb_ext.BidderAdagio, config.Adapter{
+ Endpoint: "http://localhost/prebid_server"})
+
+ if buildErr != nil {
+ t.Fatalf("Builder returned unexpected error %v", buildErr)
+ }
+
+ adapterstest.RunJSONBidderTest(t, "adagiotest", bidder)
+}
+
+func TestMakeRequests_NoGzip(t *testing.T) {
+ fakeBidRequest := buildFakeBidRequest()
+ fakeBidRequest.Test = 1 // Do not use Gzip in Test Mode.
+
+ bidder, buildErr := Builder(openrtb_ext.BidderAdagio, config.Adapter{
+ Endpoint: "http://localhost/prebid_server"})
+
+ if buildErr != nil {
+ t.Fatalf("Builder returned unexpected error %v", buildErr)
+ }
+
+ requestData, errs := bidder.MakeRequests(&fakeBidRequest, nil)
+
+ assert.Nil(t, errs)
+ assert.Equal(t, 1, len(requestData))
+
+ body := &openrtb2.BidRequest{}
+ err := json.Unmarshal(requestData[0].Body, body)
+ assert.NoError(t, err, "Request body unmarshalling error should be nil")
+ assert.Equal(t, 1, len(body.Imp))
+}
+
+func TestMakeRequests_Gzip(t *testing.T) {
+ fakeBidRequest := buildFakeBidRequest()
+
+ bidder, buildErr := Builder(openrtb_ext.BidderAdagio, config.Adapter{
+ Endpoint: "http://localhost/prebid_server"})
+
+ if buildErr != nil {
+ t.Fatalf("Builder returned unexpected error %v", buildErr)
+ }
+
+ requestData, errs := bidder.MakeRequests(&fakeBidRequest, nil)
+ assert.Empty(t, errs, "Got errors while making requests")
+ assert.Equal(t, []string{"gzip"}, requestData[0].Headers["Content-Encoding"])
+}
diff --git a/adapters/adagio/adagiotest/exemplary/banner-web.json b/adapters/adagio/adagiotest/exemplary/banner-web.json
new file mode 100644
index 00000000000..732b40d2c1d
--- /dev/null
+++ b/adapters/adagio/adagiotest/exemplary/banner-web.json
@@ -0,0 +1,155 @@
+{
+ "mockBidRequest": {
+ "test": 1,
+ "id": "some-request-id",
+ "device": {
+ "ua": "test-user-agent",
+ "ip": "123.123.123.123",
+ "language": "en",
+ "dnt": 0
+ },
+ "tmax": 1000,
+ "user": {
+ "buyeruid": "awesome-user"
+ },
+ "site": {
+ "page": "test.com",
+ "publisher": {
+ "id": "123456789"
+ }
+ },
+ "imp": [
+ {
+ "id": "some-impression-id",
+ "banner": {
+ "w":320,
+ "h":50
+ },
+ "ext": {
+ "bidder": {
+ "organizationId": "1000",
+ "site": "site-name",
+ "placement": "ban_atf"
+ }
+ }
+ }
+ ]
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "headers": {
+ "Content-Type": [
+ "application/json;charset=utf-8"
+ ],
+ "Accept": [
+ "application/json"
+ ],
+ "X-Forwarded-For": [
+ "123.123.123.123"
+ ]
+ },
+ "uri": "http://localhost/prebid_server",
+ "body": {
+ "test": 1,
+ "id": "some-request-id",
+ "device": {
+ "ua": "test-user-agent",
+ "ip": "123.123.123.123",
+ "language": "en",
+ "dnt": 0
+ },
+ "imp": [
+ {
+ "id": "some-impression-id",
+ "banner": {
+ "w":320,
+ "h":50
+ },
+ "ext": {
+ "bidder": {
+ "organizationId": "1000",
+ "site": "site-name",
+ "placement": "ban_atf"
+ }
+ }
+ }
+ ],
+ "site": {
+ "page": "test.com",
+ "publisher": {
+ "id": "123456789"
+ }
+ },
+ "user": {
+ "buyeruid": "awesome-user"
+ },
+ "tmax": 1000
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "awesome-resp-id",
+ "seatbid": [
+ {
+ "bid": [
+ {
+ "id": "a3ae1b4e2fc24a4fb45540082e98e161",
+ "impid": "some-impression-id",
+ "price": 3.5,
+ "adm": "awesome-markup",
+ "adomain": [
+ "awesome.com"
+ ],
+ "crid": "20",
+ "w": 320,
+ "h": 50,
+ "ext": {
+ "prebid": {
+ "type": "banner"
+ }
+ }
+ }
+ ],
+ "seat": "adagio"
+ }
+ ],
+ "cur": "USD",
+ "ext": {
+ "responsetimemillis": {
+ "adagio": 154
+ },
+ "tmaxrequest": 1000
+ }
+ }
+ }
+ }
+ ],
+ "expectedBidResponses": [
+ {
+ "bids":[
+ {
+ "bid": {
+ "id": "a3ae1b4e2fc24a4fb45540082e98e161",
+ "impid": "some-impression-id",
+ "price": 3.5,
+ "adm": "awesome-markup",
+ "crid": "20",
+ "adomain": [
+ "awesome.com"
+ ],
+ "w": 320,
+ "h": 50,
+ "ext": {
+ "prebid": {
+ "type": "banner"
+ }
+ }
+ },
+ "type": "banner"
+ }
+ ]
+ }
+ ]
+}
diff --git a/adapters/adagio/adagiotest/exemplary/multi-format.json b/adapters/adagio/adagiotest/exemplary/multi-format.json
new file mode 100644
index 00000000000..85e0be26131
--- /dev/null
+++ b/adapters/adagio/adagiotest/exemplary/multi-format.json
@@ -0,0 +1,165 @@
+{
+ "mockBidRequest": {
+ "test": 1,
+ "id": "some-request-id",
+ "device": {
+ "ua": "test-user-agent",
+ "ip": "123.123.123.123",
+ "language": "en",
+ "dnt": 0
+ },
+ "tmax": 1000,
+ "user": {
+ "buyeruid": "awesome-user"
+ },
+ "site": {
+ "page": "test.com",
+ "publisher": {
+ "id": "123456789"
+ }
+ },
+ "imp": [
+ {
+ "id": "multi-format-id",
+ "banner": {
+ "w":320,
+ "h":50
+ },
+ "video": {
+ "mimes": ["video\/mp4"],
+ "w": 640,
+ "h": 480
+ },
+ "ext": {
+ "bidder": {
+ "organizationId": "1000",
+ "site": "site-name",
+ "placement": "ban_atf"
+ }
+ }
+ }
+ ]
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "headers": {
+ "Content-Type": [
+ "application/json;charset=utf-8"
+ ],
+ "Accept": [
+ "application/json"
+ ],
+ "X-Forwarded-For": [
+ "123.123.123.123"
+ ]
+ },
+ "uri": "http://localhost/prebid_server",
+ "body": {
+ "test": 1,
+ "id": "some-request-id",
+ "device": {
+ "ua": "test-user-agent",
+ "ip": "123.123.123.123",
+ "language": "en",
+ "dnt": 0
+ },
+ "imp": [
+ {
+ "id": "multi-format-id",
+ "banner": {
+ "w":320,
+ "h":50
+ },
+ "video": {
+ "mimes": ["video\/mp4"],
+ "w": 640,
+ "h": 480
+ },
+ "ext": {
+ "bidder": {
+ "organizationId": "1000",
+ "site": "site-name",
+ "placement": "ban_atf"
+ }
+ }
+ }
+ ],
+ "site": {
+ "page": "test.com",
+ "publisher": {
+ "id": "123456789"
+ }
+ },
+ "user": {
+ "buyeruid": "awesome-user"
+ },
+ "tmax": 1000
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "awesome-resp-id",
+ "seatbid": [
+ {
+ "bid": [
+ {
+ "id": "a3ae1b4e2fc24a4fb45540082e98e161",
+ "impid": "multi-format-id",
+ "price": 3.5,
+ "adm": "awesome-markup",
+ "adomain": [
+ "awesome.com"
+ ],
+ "crid": "20",
+ "w": 320,
+ "h": 50,
+ "ext": {
+ "prebid": {
+ "type": "banner"
+ }
+ }
+ }
+ ],
+ "seat": "adagio"
+ }
+ ],
+ "cur": "USD",
+ "ext": {
+ "responsetimemillis": {
+ "adagio": 154
+ },
+ "tmaxrequest": 1000
+ }
+ }
+ }
+ }
+ ],
+ "expectedBidResponses": [
+ {
+ "bids":[
+ {
+ "bid": {
+ "id": "a3ae1b4e2fc24a4fb45540082e98e161",
+ "impid": "multi-format-id",
+ "price": 3.5,
+ "adm": "awesome-markup",
+ "crid": "20",
+ "adomain": [
+ "awesome.com"
+ ],
+ "w": 320,
+ "h": 50,
+ "ext": {
+ "prebid": {
+ "type": "banner"
+ }
+ }
+ },
+ "type": "banner"
+ }
+ ]
+ }
+ ]
+}
diff --git a/adapters/adagio/adagiotest/exemplary/multi-imp.json b/adapters/adagio/adagiotest/exemplary/multi-imp.json
new file mode 100644
index 00000000000..66af28ea559
--- /dev/null
+++ b/adapters/adagio/adagiotest/exemplary/multi-imp.json
@@ -0,0 +1,222 @@
+{
+ "mockBidRequest": {
+ "test": 1,
+ "id": "some-request-id",
+ "device": {
+ "ua": "test-user-agent",
+ "ip": "123.123.123.123",
+ "language": "en",
+ "dnt": 0
+ },
+ "tmax": 1000,
+ "user": {
+ "buyeruid": "awesome-user"
+ },
+ "site": {
+ "page": "test.com",
+ "publisher": {
+ "id": "123456789"
+ }
+ },
+ "imp": [
+ {
+ "id": "banner-impression-id",
+ "banner": {
+ "w":320,
+ "h":50
+ },
+ "ext": {
+ "bidder": {
+ "organizationId": "1000",
+ "site": "site-name",
+ "placement": "ban_atf"
+ }
+ }
+ },
+ {
+ "id": "video-impression-id",
+ "video": {
+ "mimes": ["video\/mp4"],
+ "w": 640,
+ "h": 480
+ },
+ "ext": {
+ "bidder": {
+ "organizationId": "1000",
+ "site": "site-name",
+ "placement": "in_article"
+ }
+ }
+ }
+ ]
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "headers": {
+ "Content-Type": [
+ "application/json;charset=utf-8"
+ ],
+ "Accept": [
+ "application/json"
+ ],
+ "X-Forwarded-For": [
+ "123.123.123.123"
+ ]
+ },
+ "uri": "http://localhost/prebid_server",
+ "body": {
+ "test": 1,
+ "id": "some-request-id",
+ "device": {
+ "ua": "test-user-agent",
+ "ip": "123.123.123.123",
+ "language": "en",
+ "dnt": 0
+ },
+ "imp": [
+ {
+ "id": "banner-impression-id",
+ "banner": {
+ "w":320,
+ "h":50
+ },
+ "ext": {
+ "bidder": {
+ "organizationId": "1000",
+ "site": "site-name",
+ "placement": "ban_atf"
+ }
+ }
+ },
+ {
+ "id": "video-impression-id",
+ "video": {
+ "mimes": ["video\/mp4"],
+ "w": 640,
+ "h": 480
+ },
+ "ext": {
+ "bidder": {
+ "organizationId": "1000",
+ "site": "site-name",
+ "placement": "in_article"
+ }
+ }
+ }
+ ],
+ "site": {
+ "page": "test.com",
+ "publisher": {
+ "id": "123456789"
+ }
+ },
+ "user": {
+ "buyeruid": "awesome-user"
+ },
+ "tmax": 1000
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "awesome-resp-id",
+ "seatbid": [
+ {
+ "bid": [
+ {
+ "id": "a3ae1b4e2fc24a4fb45540082e98e161",
+ "impid": "banner-impression-id",
+ "price": 3.5,
+ "adm": "awesome-markup",
+ "adomain": [
+ "awesome.com"
+ ],
+ "crid": "20",
+ "w": 320,
+ "h": 50,
+ "ext": {
+ "prebid": {
+ "type": "banner"
+ }
+ }
+ },
+ {
+ "id": "b4ae1b4e2fc24a4fb45540082e98e162",
+ "impid": "video-impression-id",
+ "price": 3.5,
+ "adm": "awesome-markup",
+ "adomain": [
+ "awesome.com"
+ ],
+ "crid": "20",
+ "w": 640,
+ "h": 480,
+ "ext": {
+ "prebid": {
+ "type": "video"
+ }
+ }
+ }
+ ],
+ "seat": "adagio"
+ }
+ ],
+ "cur": "USD",
+ "ext": {
+ "responsetimemillis": {
+ "adagio": 154
+ },
+ "tmaxrequest": 1000
+ }
+ }
+ }
+ }
+ ],
+ "expectedBidResponses": [
+ {
+ "bids":[
+ {
+ "bid": {
+ "id": "a3ae1b4e2fc24a4fb45540082e98e161",
+ "impid": "banner-impression-id",
+ "price": 3.5,
+ "adm": "awesome-markup",
+ "crid": "20",
+ "adomain": [
+ "awesome.com"
+ ],
+ "w": 320,
+ "h": 50,
+ "ext": {
+ "prebid": {
+ "type": "banner"
+ }
+ }
+ },
+ "type": "banner"
+ },
+ {
+ "bid": {
+ "id": "b4ae1b4e2fc24a4fb45540082e98e162",
+ "impid": "video-impression-id",
+ "price": 3.5,
+ "adm": "awesome-markup",
+ "crid": "20",
+ "adomain": [
+ "awesome.com"
+ ],
+ "w": 640,
+ "h": 480,
+ "ext": {
+ "prebid": {
+ "type": "video"
+ }
+ }
+ },
+ "type": "video"
+ }
+ ]
+ }
+ ]
+}
diff --git a/adapters/adagio/adagiotest/exemplary/native-web.json b/adapters/adagio/adagiotest/exemplary/native-web.json
new file mode 100644
index 00000000000..0085aaddc64
--- /dev/null
+++ b/adapters/adagio/adagiotest/exemplary/native-web.json
@@ -0,0 +1,151 @@
+{
+ "mockBidRequest": {
+ "test": 1,
+ "id": "some-request-id",
+ "device": {
+ "ua": "test-user-agent",
+ "ipv6": "2607:fb90:f27:4512:d800:cb23:a603:e245",
+ "language": "en",
+ "dnt": 0
+ },
+ "tmax": 1000,
+ "user": {
+ "buyeruid": "awesome-user"
+ },
+ "site": {
+ "page": "test.com",
+ "publisher": {
+ "id": "123456789"
+ }
+ },
+ "imp": [
+ {
+ "id": "some-impression-id",
+ "native": {
+ "ver":"1.1",
+ "request":"{\"adunit\":2,\"assets\":[{\"id\":3,\"img\":{\"h\":120,\"hmin\":0,\"type\":3,\"w\":180,\"wmin\":0},\"required\":1},{\"id\":0,\"required\":1,\"title\":{\"len\":25}},{\"data\":{\"len\":25,\"type\":1},\"id\":4,\"required\":1},{\"data\":{\"len\":140,\"type\":2},\"id\":6,\"required\":1}],\"context\":1,\"layout\":1,\"contextsubtype\":11,\"plcmtcnt\":1,\"plcmttype\":2,\"ver\":\"1.1\",\"ext\":{\"banner\":{\"w\":320,\"h\":50}}}"
+ },
+ "ext": {
+ "bidder": {
+ "organizationId": "1000",
+ "site": "site-name",
+ "placement": "in_article"
+ }
+ }
+ }
+ ]
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "headers": {
+ "Content-Type": [
+ "application/json;charset=utf-8"
+ ],
+ "Accept": [
+ "application/json"
+ ],
+ "X-Forwarded-For": [
+ "2607:fb90:f27:4512:d800:cb23:a603:e245"
+ ]
+ },
+ "uri": "http://localhost/prebid_server",
+ "body": {
+ "test": 1,
+ "id": "some-request-id",
+ "device": {
+ "ua": "test-user-agent",
+ "ipv6": "2607:fb90:f27:4512:d800:cb23:a603:e245",
+ "language": "en",
+ "dnt": 0
+ },
+ "imp": [
+ {
+ "id": "some-impression-id",
+ "native": {
+ "ver":"1.1",
+ "request":"{\"adunit\":2,\"assets\":[{\"id\":3,\"img\":{\"h\":120,\"hmin\":0,\"type\":3,\"w\":180,\"wmin\":0},\"required\":1},{\"id\":0,\"required\":1,\"title\":{\"len\":25}},{\"data\":{\"len\":25,\"type\":1},\"id\":4,\"required\":1},{\"data\":{\"len\":140,\"type\":2},\"id\":6,\"required\":1}],\"context\":1,\"layout\":1,\"contextsubtype\":11,\"plcmtcnt\":1,\"plcmttype\":2,\"ver\":\"1.1\",\"ext\":{\"banner\":{\"w\":320,\"h\":50}}}"
+ },
+ "ext": {
+ "bidder": {
+ "organizationId": "1000",
+ "site": "site-name",
+ "placement": "in_article"
+ }
+ }
+ }
+ ],
+ "site": {
+ "page": "test.com",
+ "publisher": {
+ "id": "123456789"
+ }
+ },
+ "user": {
+ "buyeruid": "awesome-user"
+ },
+ "tmax": 1000
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "awesome-resp-id",
+ "seatbid": [
+ {
+ "bid": [
+ {
+ "id": "a3ae1b4e2fc24a4fb45540082e98e161",
+ "impid": "some-impression-id",
+ "price": 3.5,
+ "adm": "awesome-markup",
+ "adomain": [
+ "awesome.com"
+ ],
+ "crid": "20",
+ "ext": {
+ "prebid": {
+ "type": "native"
+ }
+ }
+ }
+ ],
+ "seat": "adagio"
+ }
+ ],
+ "cur": "USD",
+ "ext": {
+ "responsetimemillis": {
+ "acuityads": 154
+ },
+ "tmaxrequest": 1000
+ }
+ }
+ }
+ }
+ ],
+ "expectedBidResponses": [
+ {
+ "bids":[
+ {
+ "bid": {
+ "id": "a3ae1b4e2fc24a4fb45540082e98e161",
+ "impid": "some-impression-id",
+ "price": 3.5,
+ "adm": "awesome-markup",
+ "crid": "20",
+ "adomain": [
+ "awesome.com"
+ ],
+ "ext": {
+ "prebid": {
+ "type": "native"
+ }
+ }
+ },
+ "type": "native"
+ }
+ ]
+ }
+ ]
+}
diff --git a/adapters/adagio/adagiotest/exemplary/video-web.json b/adapters/adagio/adagiotest/exemplary/video-web.json
new file mode 100644
index 00000000000..353420ee962
--- /dev/null
+++ b/adapters/adagio/adagiotest/exemplary/video-web.json
@@ -0,0 +1,175 @@
+{
+ "mockBidRequest": {
+ "test": 1,
+ "id": "some-request-id",
+ "device": {
+ "ua": "test-user-agent",
+ "ip": "123.123.123.123",
+ "language": "en",
+ "dnt": 0
+ },
+ "tmax": 1000,
+ "user": {
+ "buyeruid": "awesome-user"
+ },
+ "site": {
+ "page": "test.com",
+ "publisher": {
+ "id": "123456789"
+ }
+ },
+ "imp": [
+ {
+ "id": "some-impression-id",
+ "video": {
+ "mimes": [
+ "video\/mp4"
+ ],
+ "w": 640,
+ "h": 480,
+ "minduration": 120,
+ "maxduration": 150
+ },
+ "ext": {
+ "bidder": {
+ "organizationId": "1000",
+ "site": "site-name",
+ "placement": "in_article"
+ }
+ }
+ }
+ ]
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "headers": {
+ "Content-Type": [
+ "application/json;charset=utf-8"
+ ],
+ "Accept": [
+ "application/json"
+ ],
+ "X-Forwarded-For": [
+ "123.123.123.123"
+ ]
+ },
+ "uri": "http://localhost/prebid_server",
+ "body": {
+ "test": 1,
+ "id": "some-request-id",
+ "device": {
+ "ua": "test-user-agent",
+ "ip": "123.123.123.123",
+ "language": "en",
+ "dnt": 0
+ },
+ "imp": [
+ {
+ "id": "some-impression-id",
+ "video": {
+ "mimes": [
+ "video\/mp4"
+ ],
+ "minduration": 120,
+ "maxduration": 150,
+ "w": 640,
+ "h": 480
+ },
+ "ext": {
+ "bidder": {
+ "organizationId": "1000",
+ "site": "site-name",
+ "placement": "in_article"
+ }
+ }
+ }
+ ],
+ "site": {
+ "page": "test.com",
+ "publisher": {
+ "id": "123456789"
+ }
+ },
+ "user": {
+ "buyeruid": "awesome-user"
+ },
+ "tmax": 1000
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "awesome-resp-id",
+ "seatbid": [
+ {
+ "bid": [
+ {
+ "id": "a3ae1b4e2fc24a4fb45540082e98e161",
+ "impid": "some-impression-id",
+ "price": 3.5,
+ "adm": "awesome-markup",
+ "adomain": [
+ "awesome.com"
+ ],
+ "crid": "20",
+ "w": 1280,
+ "h": 720,
+ "ext": {
+ "adagio": {
+ "outstream": {
+ "bvwUrl": "https://cool.io"
+ }
+ },
+ "prebid": {
+ "type": "video"
+ }
+ }
+ }
+ ],
+ "seat": "adagio"
+ }
+ ],
+ "cur": "USD",
+ "ext": {
+ "responsetimemillis": {
+ "adagio": 154
+ },
+ "tmaxrequest": 1000
+ }
+ }
+ }
+ }
+ ],
+ "expectedBidResponses": [
+ {
+ "bids": [
+ {
+ "bid": {
+ "id": "a3ae1b4e2fc24a4fb45540082e98e161",
+ "impid": "some-impression-id",
+ "price": 3.5,
+ "adm": "awesome-markup",
+ "adomain": [
+ "awesome.com"
+ ],
+ "crid": "20",
+ "w": 1280,
+ "h": 720,
+ "ext": {
+ "adagio": {
+ "outstream": {
+ "bvwUrl": "https://cool.io"
+ }
+ },
+ "prebid": {
+ "type": "video"
+ }
+ }
+ },
+ "type":"video"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/adapters/adagio/adagiotest/params/race/banner.json b/adapters/adagio/adagiotest/params/race/banner.json
new file mode 100644
index 00000000000..66694466d84
--- /dev/null
+++ b/adapters/adagio/adagiotest/params/race/banner.json
@@ -0,0 +1,5 @@
+{
+ "organizationId": "1000",
+ "site": "site-name",
+ "placement": "ban_atf"
+}
diff --git a/adapters/adagio/adagiotest/params/race/native.json b/adapters/adagio/adagiotest/params/race/native.json
new file mode 100644
index 00000000000..4affd5b232c
--- /dev/null
+++ b/adapters/adagio/adagiotest/params/race/native.json
@@ -0,0 +1,5 @@
+{
+ "organizationId": "1000",
+ "site": "site-name",
+ "placement": "in_article"
+}
diff --git a/adapters/adagio/adagiotest/params/race/video.json b/adapters/adagio/adagiotest/params/race/video.json
new file mode 100644
index 00000000000..4affd5b232c
--- /dev/null
+++ b/adapters/adagio/adagiotest/params/race/video.json
@@ -0,0 +1,5 @@
+{
+ "organizationId": "1000",
+ "site": "site-name",
+ "placement": "in_article"
+}
diff --git a/adapters/adagio/adagiotest/supplemental/response-miss-ext-bid-type.json b/adapters/adagio/adagiotest/supplemental/response-miss-ext-bid-type.json
new file mode 100644
index 00000000000..7b1267f6d50
--- /dev/null
+++ b/adapters/adagio/adagiotest/supplemental/response-miss-ext-bid-type.json
@@ -0,0 +1,130 @@
+{
+ "mockBidRequest": {
+ "test": 1,
+ "id": "some-request-id",
+ "device": {
+ "ua": "test-user-agent",
+ "ip": "123.123.123.123",
+ "language": "en",
+ "dnt": 0
+ },
+ "tmax": 1000,
+ "user": {
+ "buyeruid": "awesome-user"
+ },
+ "site": {
+ "page": "test.com",
+ "publisher": {
+ "id": "123456789"
+ }
+ },
+ "imp": [
+ {
+ "id": "some-impression-id",
+ "banner": {
+ "w": 320,
+ "h": 50
+ },
+ "ext": {
+ "bidder": {
+ "organizationId": "1000",
+ "site": "site-name",
+ "placement": "ban_atf"
+ }
+ }
+ }
+ ]
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "headers": {
+ "Content-Type": [
+ "application/json;charset=utf-8"
+ ],
+ "Accept": [
+ "application/json"
+ ],
+ "X-Forwarded-For": [
+ "123.123.123.123"
+ ]
+ },
+ "uri": "http://localhost/prebid_server",
+ "body": {
+ "test": 1,
+ "id": "some-request-id",
+ "device": {
+ "ua": "test-user-agent",
+ "ip": "123.123.123.123",
+ "language": "en",
+ "dnt": 0
+ },
+ "imp": [
+ {
+ "id": "some-impression-id",
+ "banner": {
+ "w": 320,
+ "h": 50
+ },
+ "ext": {
+ "bidder": {
+ "organizationId": "1000",
+ "site": "site-name",
+ "placement": "ban_atf"
+ }
+ }
+ }
+ ],
+ "site": {
+ "page": "test.com",
+ "publisher": {
+ "id": "123456789"
+ }
+ },
+ "user": {
+ "buyeruid": "awesome-user"
+ },
+ "tmax": 1000
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "awesome-resp-id",
+ "seatbid": [
+ {
+ "bid": [
+ {
+ "id": "a3ae1b4e2fc24a4fb45540082e98e161",
+ "impid": "some-impression-id",
+ "price": 3.5,
+ "adm": "awesome-markup",
+ "adomain": [
+ "awesome.com"
+ ],
+ "crid": "20",
+ "w": 320,
+ "h": 50,
+ "ext": {}
+ }
+ ],
+ "seat": "adagio"
+ }
+ ],
+ "cur": "USD",
+ "ext": {
+ "responsetimemillis": {
+ "adagio": 154
+ },
+ "tmaxrequest": 1000
+ }
+ }
+ }
+ }
+ ],
+ "expectedBidResponses": [
+ {
+ "bids": []
+ }
+ ]
+}
diff --git a/adapters/adagio/adagiotest/supplemental/status-204.json b/adapters/adagio/adagiotest/supplemental/status-204.json
new file mode 100644
index 00000000000..4d604a01fb9
--- /dev/null
+++ b/adapters/adagio/adagiotest/supplemental/status-204.json
@@ -0,0 +1,62 @@
+{
+ "mockBidRequest": {
+ "test": 1,
+ "id": "some-request-id",
+ "imp": [
+ {
+ "id": "some-impression-id",
+ "banner": {
+ "w": 320,
+ "h": 50
+ },
+ "ext": {
+ "bidder": {
+ "organizationId": "1000",
+ "site": "site-name",
+ "placement": "ban_atf"
+ }
+ }
+ }
+ ]
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "headers": {
+ "Content-Type": [
+ "application/json;charset=utf-8"
+ ],
+ "Accept": [
+ "application/json"
+ ]
+ },
+ "uri": "http://localhost/prebid_server",
+ "body": {
+ "test": 1,
+ "id": "some-request-id",
+ "imp": [
+ {
+ "id": "some-impression-id",
+ "banner": {
+ "w": 320,
+ "h": 50
+ },
+ "ext": {
+ "bidder": {
+ "organizationId": "1000",
+ "site": "site-name",
+ "placement": "ban_atf"
+ }
+ }
+ }
+ ]
+ }
+ },
+ "mockResponse": {
+ "status": 204,
+ "body": {}
+ }
+ }
+ ],
+ "expectedBidResponses": []
+}
diff --git a/adapters/adagio/adagiotest/supplemental/status-400.json b/adapters/adagio/adagiotest/supplemental/status-400.json
new file mode 100644
index 00000000000..093c5458c0a
--- /dev/null
+++ b/adapters/adagio/adagiotest/supplemental/status-400.json
@@ -0,0 +1,67 @@
+{
+ "mockBidRequest": {
+ "test": 1,
+ "id": "some-request-id",
+ "imp": [
+ {
+ "id": "some-impression-id",
+ "banner": {
+ "w": 320,
+ "h": 50
+ },
+ "ext": {
+ "bidder": {
+ "organizationId": "1000",
+ "site": "site-name",
+ "placement": "ban_atf"
+ }
+ }
+ }
+ ]
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "headers": {
+ "Content-Type": [
+ "application/json;charset=utf-8"
+ ],
+ "Accept": [
+ "application/json"
+ ]
+ },
+ "uri": "http://localhost/prebid_server",
+ "body": {
+ "test": 1,
+ "id": "some-request-id",
+ "imp": [
+ {
+ "id": "some-impression-id",
+ "banner": {
+ "w": 320,
+ "h": 50
+ },
+ "ext": {
+ "bidder": {
+ "organizationId": "1000",
+ "site": "site-name",
+ "placement": "ban_atf"
+ }
+ }
+ }
+ ]
+ }
+ },
+ "mockResponse": {
+ "status": 400,
+ "body": "bad request"
+ }
+ }
+ ],
+ "expectedMakeBidsErrors": [
+ {
+ "value": "Unexpected status code: 400. Run with request.debug = 1 for more info",
+ "comparison": "literal"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/adapters/adagio/adagiotest/supplemental/status-401.json b/adapters/adagio/adagiotest/supplemental/status-401.json
new file mode 100644
index 00000000000..a33aca203d0
--- /dev/null
+++ b/adapters/adagio/adagiotest/supplemental/status-401.json
@@ -0,0 +1,67 @@
+{
+ "mockBidRequest": {
+ "test": 1,
+ "id": "some-request-id",
+ "imp": [
+ {
+ "id": "some-impression-id",
+ "banner": {
+ "w": 320,
+ "h": 50
+ },
+ "ext": {
+ "bidder": {
+ "organizationId": "1000",
+ "site": "site-name",
+ "placement": "ban_atf"
+ }
+ }
+ }
+ ]
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "headers": {
+ "Content-Type": [
+ "application/json;charset=utf-8"
+ ],
+ "Accept": [
+ "application/json"
+ ]
+ },
+ "uri": "http://localhost/prebid_server",
+ "body": {
+ "test": 1,
+ "id": "some-request-id",
+ "imp": [
+ {
+ "id": "some-impression-id",
+ "banner": {
+ "w": 320,
+ "h": 50
+ },
+ "ext": {
+ "bidder": {
+ "organizationId": "1000",
+ "site": "site-name",
+ "placement": "ban_atf"
+ }
+ }
+ }
+ ]
+ }
+ },
+ "mockResponse": {
+ "status": 401,
+ "body": "unauthorized"
+ }
+ }
+ ],
+ "expectedMakeBidsErrors": [
+ {
+ "value": "Unexpected status code: 401. Run with request.debug = 1 for more info",
+ "comparison": "literal"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/adapters/adagio/adagiotest/supplemental/status-403.json b/adapters/adagio/adagiotest/supplemental/status-403.json
new file mode 100644
index 00000000000..59c5a9cbf6b
--- /dev/null
+++ b/adapters/adagio/adagiotest/supplemental/status-403.json
@@ -0,0 +1,67 @@
+{
+ "mockBidRequest": {
+ "test": 1,
+ "id": "some-request-id",
+ "imp": [
+ {
+ "id": "some-impression-id",
+ "banner": {
+ "w": 320,
+ "h": 50
+ },
+ "ext": {
+ "bidder": {
+ "organizationId": "1000",
+ "site": "site-name",
+ "placement": "ban_atf"
+ }
+ }
+ }
+ ]
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "headers": {
+ "Content-Type": [
+ "application/json;charset=utf-8"
+ ],
+ "Accept": [
+ "application/json"
+ ]
+ },
+ "uri": "http://localhost/prebid_server",
+ "body": {
+ "test": 1,
+ "id": "some-request-id",
+ "imp": [
+ {
+ "id": "some-impression-id",
+ "banner": {
+ "w": 320,
+ "h": 50
+ },
+ "ext": {
+ "bidder": {
+ "organizationId": "1000",
+ "site": "site-name",
+ "placement": "ban_atf"
+ }
+ }
+ }
+ ]
+ }
+ },
+ "mockResponse": {
+ "status": 403,
+ "body": "forbidden"
+ }
+ }
+ ],
+ "expectedMakeBidsErrors": [
+ {
+ "value": "Unexpected status code: 403. Run with request.debug = 1 for more info",
+ "comparison": "literal"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/adapters/adagio/adagiotest/supplemental/status-500.json b/adapters/adagio/adagiotest/supplemental/status-500.json
new file mode 100644
index 00000000000..0077d7457f9
--- /dev/null
+++ b/adapters/adagio/adagiotest/supplemental/status-500.json
@@ -0,0 +1,68 @@
+{
+ "mockBidRequest": {
+ "test": 1,
+ "debug": 1,
+ "id": "some-request-id",
+ "imp": [
+ {
+ "id": "some-impression-id",
+ "banner": {
+ "w": 320,
+ "h": 50
+ },
+ "ext": {
+ "bidder": {
+ "organizationId": "1000",
+ "site": "site-name",
+ "placement": "ban_atf"
+ }
+ }
+ }
+ ]
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "headers": {
+ "Content-Type": [
+ "application/json;charset=utf-8"
+ ],
+ "Accept": [
+ "application/json"
+ ]
+ },
+ "uri": "http://localhost/prebid_server",
+ "body": {
+ "test": 1,
+ "id": "some-request-id",
+ "imp": [
+ {
+ "id": "some-impression-id",
+ "banner": {
+ "w": 320,
+ "h": 50
+ },
+ "ext": {
+ "bidder": {
+ "organizationId": "1000",
+ "site": "site-name",
+ "placement": "ban_atf"
+ }
+ }
+ }
+ ]
+ }
+ },
+ "mockResponse": {
+ "status": 500,
+ "body": "internal error"
+ }
+ }
+ ],
+ "expectedMakeBidsErrors": [
+ {
+ "value": "Unexpected status code: 500. Run with request.debug = 1 for more info",
+ "comparison": "literal"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/adapters/adagio/adagiotest/supplemental/status-503.json b/adapters/adagio/adagiotest/supplemental/status-503.json
new file mode 100644
index 00000000000..d2a52893de5
--- /dev/null
+++ b/adapters/adagio/adagiotest/supplemental/status-503.json
@@ -0,0 +1,67 @@
+{
+ "mockBidRequest": {
+ "test": 1,
+ "id": "some-request-id",
+ "imp": [
+ {
+ "id": "some-impression-id",
+ "banner": {
+ "w": 320,
+ "h": 50
+ },
+ "ext": {
+ "bidder": {
+ "organizationId": "1000",
+ "site": "site-name",
+ "placement": "ban_atf"
+ }
+ }
+ }
+ ]
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "headers": {
+ "Content-Type": [
+ "application/json;charset=utf-8"
+ ],
+ "Accept": [
+ "application/json"
+ ]
+ },
+ "uri": "http://localhost/prebid_server",
+ "body": {
+ "test": 1,
+ "id": "some-request-id",
+ "imp": [
+ {
+ "id": "some-impression-id",
+ "banner": {
+ "w": 320,
+ "h": 50
+ },
+ "ext": {
+ "bidder": {
+ "organizationId": "1000",
+ "site": "site-name",
+ "placement": "ban_atf"
+ }
+ }
+ }
+ ]
+ }
+ },
+ "mockResponse": {
+ "status": 503,
+ "body": "Service unavailable"
+ }
+ }
+ ],
+ "expectedMakeBidsErrors": [
+ {
+ "value": "Unexpected status code: 503. Run with request.debug = 1 for more info",
+ "comparison": "literal"
+ }
+ ]
+}
diff --git a/adapters/adagio/adagiotest/supplemental/status-504.json b/adapters/adagio/adagiotest/supplemental/status-504.json
new file mode 100644
index 00000000000..1b779d5c83f
--- /dev/null
+++ b/adapters/adagio/adagiotest/supplemental/status-504.json
@@ -0,0 +1,67 @@
+{
+ "mockBidRequest": {
+ "test": 1,
+ "id": "some-request-id",
+ "imp": [
+ {
+ "id": "some-impression-id",
+ "banner": {
+ "w": 320,
+ "h": 50
+ },
+ "ext": {
+ "bidder": {
+ "organizationId": "1000",
+ "site": "site-name",
+ "placement": "ban_atf"
+ }
+ }
+ }
+ ]
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "headers": {
+ "Content-Type": [
+ "application/json;charset=utf-8"
+ ],
+ "Accept": [
+ "application/json"
+ ]
+ },
+ "uri": "http://localhost/prebid_server",
+ "body": {
+ "test": 1,
+ "id": "some-request-id",
+ "imp": [
+ {
+ "id": "some-impression-id",
+ "banner": {
+ "w": 320,
+ "h": 50
+ },
+ "ext": {
+ "bidder": {
+ "organizationId": "1000",
+ "site": "site-name",
+ "placement": "ban_atf"
+ }
+ }
+ }
+ ]
+ }
+ },
+ "mockResponse": {
+ "status": 504,
+ "body": "gateway timeout"
+ }
+ }
+ ],
+ "expectedMakeBidsErrors": [
+ {
+ "value": "Unexpected status code: 504. Run with request.debug = 1 for more info",
+ "comparison": "literal"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/adapters/adagio/params_test.go b/adapters/adagio/params_test.go
new file mode 100644
index 00000000000..ee8f702e451
--- /dev/null
+++ b/adapters/adagio/params_test.go
@@ -0,0 +1,57 @@
+package adagio
+
+import (
+ "encoding/json"
+ "testing"
+
+ "github.com/prebid/prebid-server/openrtb_ext"
+)
+
+var validParams = []string{
+ `{ "organizationId": "1234", "site": "adagio-io", "placement": "ban_atf" }`,
+ `{ "organizationId": "1234", "site": "adagio-io", "placement": "ban_atf", "_unknown": "ban_atf"}`,
+ `{ "organizationId": "1234", "site": "adagio-io", "placement": "ban_atf", "features": {"a": "a", "b": "b"}}`,
+}
+
+func TestValidParams(t *testing.T) {
+ validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params")
+ if err != nil {
+ t.Fatalf("Failed to fetch the json-schemas. %v", err)
+ }
+
+ for _, validParam := range validParams {
+ if err := validator.Validate(openrtb_ext.BidderAdagio, json.RawMessage(validParam)); err != nil {
+ t.Errorf("Schema rejected Adagio params: %s", validParam)
+ }
+ }
+}
+
+var invalidParams = []string{
+ ``,
+ `null`,
+ `true`,
+ `5`,
+ `4.2`,
+ `[]`,
+ `{}`,
+ `{"adCode": "string", "seatCode": 5, "originalPublisherid": "string"}`,
+ `{ "organizationId": "", "site": "", "placement": "" }`,
+ `{ "organizationId": "", "site": "2", "placement": "3" }`,
+ `{ "organizationId": "1", "site": "", "placement": "3" }`,
+ `{ "organizationId": "1", "site": "2", "placement": "" }`,
+ `{ "organizationId": 1, "site": "2", "placement": "3" }`,
+ `{ "organizationId": "1234", "site": "adagio-io", "placement": "ban_atf", "features": {"a": "a", "notastring": true}}`,
+}
+
+func TestInvalidParams(t *testing.T) {
+ validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params")
+ if err != nil {
+ t.Fatalf("Failed to fetch the json-schemas. %v", err)
+ }
+
+ for _, invalidParam := range invalidParams {
+ if err := validator.Validate(openrtb_ext.BidderAdagio, json.RawMessage(invalidParam)); err == nil {
+ t.Errorf("Schema allowed unexpected params: %s", invalidParam)
+ }
+ }
+}
diff --git a/adapters/adagio/usersync.go b/adapters/adagio/usersync.go
new file mode 100644
index 00000000000..a7230feaada
--- /dev/null
+++ b/adapters/adagio/usersync.go
@@ -0,0 +1,12 @@
+package adagio
+
+import (
+ "text/template"
+
+ "github.com/prebid/prebid-server/adapters"
+ "github.com/prebid/prebid-server/usersync"
+)
+
+func NewAdagioSyncer(tmpl *template.Template) usersync.Usersyncer {
+ return adapters.NewSyncer("adagio", tmpl, adapters.SyncTypeRedirect)
+}
diff --git a/adapters/adagio/usersync_test.go b/adapters/adagio/usersync_test.go
new file mode 100644
index 00000000000..cd4195e16df
--- /dev/null
+++ b/adapters/adagio/usersync_test.go
@@ -0,0 +1,34 @@
+package adagio
+
+import (
+ "testing"
+ "text/template"
+
+ "github.com/prebid/prebid-server/privacy"
+ "github.com/prebid/prebid-server/privacy/ccpa"
+ "github.com/prebid/prebid-server/privacy/gdpr"
+ "github.com/stretchr/testify/assert"
+)
+
+func TestAdagioSyncer(t *testing.T) {
+ syncURL := "https://mp.4dex.io/sync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect=http%3A%2F%2Flocalhost%3A8000%2Fsetuid%3Fbidder%3Dadagio%26uid%3D%5BUID%5D"
+ syncURLTemplate := template.Must(
+ template.New("sync-template").Parse(syncURL),
+ )
+
+ syncer := NewAdagioSyncer(syncURLTemplate)
+ syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{
+ GDPR: gdpr.Policy{
+ Signal: "0",
+ Consent: "ANDFJDS",
+ },
+ CCPA: ccpa.Policy{
+ Consent: "1-YY",
+ },
+ })
+
+ assert.NoError(t, err)
+ assert.Equal(t, "https://mp.4dex.io/sync?gdpr=0&gdpr_consent=ANDFJDS&us_privacy=1-YY&redirect=http%3A%2F%2Flocalhost%3A8000%2Fsetuid%3Fbidder%3Dadagio%26uid%3D%5BUID%5D", syncInfo.URL)
+ assert.Equal(t, "redirect", syncInfo.Type)
+ assert.Equal(t, false, syncInfo.SupportCORS)
+}
diff --git a/adapters/admixer/admixer.go b/adapters/admixer/admixer.go
index ec49950a17e..5008b0ce5c6 100644
--- a/adapters/admixer/admixer.go
+++ b/adapters/admixer/admixer.go
@@ -100,14 +100,17 @@ func preprocess(imp *openrtb2.Imp) error {
}
//don't use regexp due to possible performance reduce
- if len(admixerExt.ZoneId) != 36 {
+ if len(admixerExt.ZoneId) < 32 || len(admixerExt.ZoneId) > 36 {
return &errortypes.BadInput{
Message: "ZoneId must be UUID/GUID",
}
}
imp.TagID = admixerExt.ZoneId
- imp.BidFloor = admixerExt.CustomBidFloor
+
+ if imp.BidFloor == 0 && admixerExt.CustomBidFloor > 0 {
+ imp.BidFloor = admixerExt.CustomBidFloor
+ }
imp.Ext = nil
diff --git a/adapters/admixer/admixertest/exemplary/optional-params.json b/adapters/admixer/admixertest/exemplary/optional-params.json
index 8ef112bbdb5..b93aa9c8154 100644
--- a/adapters/admixer/admixertest/exemplary/optional-params.json
+++ b/adapters/admixer/admixertest/exemplary/optional-params.json
@@ -44,6 +44,76 @@
}
}
}
+ },
+ {
+ "id": "test-imp-id",
+ "bidfloor": 0.5,
+ "banner": {
+ "format": [
+ {
+ "w": 728,
+ "h": 90
+ }
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "zone": "2eb6bd58-865c-47ce-af7f-a918108c3fd2",
+ "customParams": {
+ "foo": [
+ "bar",
+ "baz"
+ ]
+ }
+ }
+ }
+ },
+ {
+ "id": "test-imp-id",
+ "bidfloor": 0.5,
+ "banner": {
+ "format": [
+ {
+ "w": 728,
+ "h": 90
+ }
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "zone": "2eb6bd58-865c-47ce-af7f-a918108c3fd2",
+ "customParams": {
+ "foo": [
+ "bar",
+ "baz"
+ ]
+ }
+ },
+ "customFloor": 0.9
+ }
+ },
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "format": [
+ {
+ "w": 728,
+ "h": 90
+ }
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "customFloor": 0.9,
+ "zone": "2eb6bd58-865c-47ce-af7f-a918108c3fd2",
+ "customParams": {
+ "foo": [
+ "bar",
+ "baz"
+ ]
+ }
+ }
+ }
}
]
},
@@ -92,6 +162,69 @@
]
}
}
+ },
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "format": [
+ {
+ "w": 728,
+ "h": 90
+ }
+ ]
+ },
+ "tagid": "2eb6bd58-865c-47ce-af7f-a918108c3fd2",
+ "bidfloor": 0.5,
+ "ext": {
+ "customParams": {
+ "foo": [
+ "bar",
+ "baz"
+ ]
+ }
+ }
+ },
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "format": [
+ {
+ "w": 728,
+ "h": 90
+ }
+ ]
+ },
+ "tagid": "2eb6bd58-865c-47ce-af7f-a918108c3fd2",
+ "bidfloor": 0.5,
+ "ext": {
+ "customParams": {
+ "foo": [
+ "bar",
+ "baz"
+ ]
+ }
+ }
+ },
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "format": [
+ {
+ "w": 728,
+ "h": 90
+ }
+ ]
+ },
+ "tagid": "2eb6bd58-865c-47ce-af7f-a918108c3fd2",
+ "bidfloor": 0.9,
+ "ext": {
+ "customParams": {
+ "foo": [
+ "bar",
+ "baz"
+ ]
+ }
+ }
}
]
}
diff --git a/adapters/admixer/params_test.go b/adapters/admixer/params_test.go
index 71cccb6a3da..11f3feb0657 100644
--- a/adapters/admixer/params_test.go
+++ b/adapters/admixer/params_test.go
@@ -44,6 +44,8 @@ var validParams = []string{
`{"zone": "9FF668A2-4122-462E-AAF8-36EA3A54BA21", "customFloor": 0.1}`,
`{"zone": "9FF668A2-4122-462E-AAF8-36EA3A54BA21", "customParams": {"foo": "bar"}}`,
`{"zone": "9ff668a2-4122-462e-aaf8-36ea3a54ba21", "customFloor": 0.1, "customParams": {"foo": ["bar", "baz"]}}`,
+ `{"zone": "9FF668A24122462EAAF836EA3A54BA21"}`,
+ `{"zone": "9FF668A24122462EAAF836EA3A54BA212"}`,
}
var invalidParams = []string{
@@ -54,4 +56,6 @@ var invalidParams = []string{
`{"zone": "123", "customFloor": "0.1"}`,
`{"zone": "9FF668A2-4122-462E-AAF8-36EA3A54BA21", "customFloor": -0.1}`,
`{"zone": "9FF668A2-4122-462E-AAF8-36EA3A54BA21", "customParams": "foo: bar"}`,
+ `{"zone": "9FF668A24122462EAAF836EA3A54BA2"}`,
+ `{"zone": "9FF668A24122462EAAF836EA3A54BA2112336"}`,
}
diff --git a/adapters/axonix/axonix.go b/adapters/axonix/axonix.go
index d3016235319..268b0e3ee2f 100644
--- a/adapters/axonix/axonix.go
+++ b/adapters/axonix/axonix.go
@@ -4,25 +4,39 @@ import (
"encoding/json"
"fmt"
"net/http"
+ "net/url"
+ "text/template"
"github.com/mxmCherry/openrtb/v15/openrtb2"
"github.com/prebid/prebid-server/adapters"
"github.com/prebid/prebid-server/config"
"github.com/prebid/prebid-server/errortypes"
+ "github.com/prebid/prebid-server/macros"
"github.com/prebid/prebid-server/openrtb_ext"
)
type adapter struct {
- URI string
+ EndpointTemplate template.Template
}
func Builder(bidderName openrtb_ext.BidderName, config config.Adapter) (adapters.Bidder, error) {
+ endpoint, err := template.New("endpointTemplate").Parse(config.Endpoint)
+ if err != nil {
+ return nil, fmt.Errorf("unable to parse endpoint url template: %v", err)
+ }
bidder := &adapter{
- URI: config.Endpoint,
+ EndpointTemplate: *endpoint,
}
return bidder, nil
}
+func (a *adapter) getEndpoint(ext *openrtb_ext.ExtImpAxonix) (string, error) {
+ endpointParams := macros.EndpointTemplateParams{
+ AccountID: url.PathEscape(ext.SupplyId),
+ }
+ return macros.ResolveMacros(a.EndpointTemplate, endpointParams)
+}
+
func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
var errors []error
@@ -44,9 +58,10 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte
return nil, errors
}
- thisURI := a.URI
- if len(thisURI) == 0 {
- thisURI = "https://openrtb-us-east-1.axonix.com/supply/prebid-server/" + axonixExt.SupplyId
+ endpoint, err := a.getEndpoint(&axonixExt)
+ if err != nil {
+ errors = append(errors, err)
+ return nil, errors
}
requestJSON, err := json.Marshal(request)
@@ -60,7 +75,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte
requestData := &adapters.RequestData{
Method: "POST",
- Uri: thisURI,
+ Uri: endpoint,
Body: requestJSON,
Headers: headers,
}
diff --git a/adapters/axonix/axonix_test.go b/adapters/axonix/axonix_test.go
index 6c4a3eb34d6..fcac320075f 100644
--- a/adapters/axonix/axonix_test.go
+++ b/adapters/axonix/axonix_test.go
@@ -1,6 +1,7 @@
package axonix
import (
+ "github.com/stretchr/testify/assert"
"testing"
"github.com/prebid/prebid-server/adapters/adapterstest"
@@ -8,9 +9,10 @@ import (
"github.com/prebid/prebid-server/openrtb_ext"
)
-func TestJsonSamplesWithConfiguredURI(t *testing.T) {
+func TestJsonSamples(t *testing.T) {
bidder, buildErr := Builder(openrtb_ext.BidderAxonix, config.Adapter{
- Endpoint: "https://openrtb-us-east-1.axonix.com/supply/prebid-server/24cc9034-f861-47b8-a6a8-b7e0968c00b8"})
+ Endpoint: "https://axonix.com/supply/prebid-server/{{.AccountID}}",
+ })
if buildErr != nil {
t.Fatalf("Builder returned unexpected error %v", buildErr)
@@ -19,12 +21,8 @@ func TestJsonSamplesWithConfiguredURI(t *testing.T) {
adapterstest.RunJSONBidderTest(t, "axonixtest", bidder)
}
-func TestJsonSamplesWithHardcodedURI(t *testing.T) {
- bidder, buildErr := Builder(openrtb_ext.BidderAxonix, config.Adapter{})
+func TestEndpointTemplateMalformed(t *testing.T) {
+ _, buildErr := Builder(openrtb_ext.BidderAxonix, config.Adapter{Endpoint: "{{Malformed}}"})
- if buildErr != nil {
- t.Fatalf("Builder returned unexpected error %v", buildErr)
- }
-
- adapterstest.RunJSONBidderTest(t, "axonixtest", bidder)
+ assert.Error(t, buildErr)
}
diff --git a/adapters/axonix/axonixtest/exemplary/banner-and-video.json b/adapters/axonix/axonixtest/exemplary/banner-and-video.json
index 1755cd0ef22..04b640826dc 100644
--- a/adapters/axonix/axonixtest/exemplary/banner-and-video.json
+++ b/adapters/axonix/axonixtest/exemplary/banner-and-video.json
@@ -18,7 +18,7 @@
},
"ext": {
"bidder": {
- "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8"
+ "supplyId": "supply-test"
}
}
},
@@ -32,7 +32,7 @@
},
"ext": {
"bidder": {
- "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8"
+ "supplyId": "supply-test"
}
}
}
@@ -41,7 +41,7 @@
"httpCalls": [
{
"expectedRequest": {
- "uri": "https://openrtb-us-east-1.axonix.com/supply/prebid-server/24cc9034-f861-47b8-a6a8-b7e0968c00b8",
+ "uri": "https://axonix.com/supply/prebid-server/supply-test",
"body": {
"id": "test-request-id",
"imp": [
@@ -61,7 +61,7 @@
},
"ext": {
"bidder": {
- "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8"
+ "supplyId": "supply-test"
}
}
},
@@ -75,7 +75,7 @@
},
"ext": {
"bidder": {
- "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8"
+ "supplyId": "supply-test"
}
}
}
diff --git a/adapters/axonix/axonixtest/exemplary/banner-video-native.json b/adapters/axonix/axonixtest/exemplary/banner-video-native.json
index 3944eb358b9..5dd5775004a 100644
--- a/adapters/axonix/axonixtest/exemplary/banner-video-native.json
+++ b/adapters/axonix/axonixtest/exemplary/banner-video-native.json
@@ -18,7 +18,7 @@
},
"ext": {
"bidder": {
- "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8"
+ "supplyId": "supply-test"
}
}
},
@@ -30,7 +30,7 @@
},
"ext": {
"bidder": {
- "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8"
+ "supplyId": "supply-test"
}
}
},
@@ -44,7 +44,7 @@
},
"ext": {
"bidder": {
- "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8"
+ "supplyId": "supply-test"
}
}
}
@@ -53,7 +53,7 @@
"httpCalls": [
{
"expectedRequest": {
- "uri": "https://openrtb-us-east-1.axonix.com/supply/prebid-server/24cc9034-f861-47b8-a6a8-b7e0968c00b8",
+ "uri": "https://axonix.com/supply/prebid-server/supply-test",
"body": {
"id": "test-request-id",
"imp": [
@@ -73,7 +73,7 @@
},
"ext": {
"bidder": {
- "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8"
+ "supplyId": "supply-test"
}
}
},
@@ -85,7 +85,7 @@
},
"ext": {
"bidder": {
- "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8"
+ "supplyId": "supply-test"
}
}
},
@@ -99,7 +99,7 @@
},
"ext": {
"bidder": {
- "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8"
+ "supplyId": "supply-test"
}
}
}
diff --git a/adapters/axonix/axonixtest/exemplary/simple-banner.json b/adapters/axonix/axonixtest/exemplary/simple-banner.json
index 581e59b9b9e..40441a46425 100644
--- a/adapters/axonix/axonixtest/exemplary/simple-banner.json
+++ b/adapters/axonix/axonixtest/exemplary/simple-banner.json
@@ -18,7 +18,7 @@
},
"ext": {
"bidder": {
- "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8"
+ "supplyId": "supply-test"
}
}
}
@@ -28,7 +28,7 @@
"httpCalls": [
{
"expectedRequest": {
- "uri": "https://openrtb-us-east-1.axonix.com/supply/prebid-server/24cc9034-f861-47b8-a6a8-b7e0968c00b8",
+ "uri": "https://axonix.com/supply/prebid-server/supply-test",
"body": {
"id": "test-request-id",
"imp": [
@@ -48,7 +48,7 @@
},
"ext": {
"bidder": {
- "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8"
+ "supplyId": "supply-test"
}
}
}
diff --git a/adapters/axonix/axonixtest/exemplary/simple-video.json b/adapters/axonix/axonixtest/exemplary/simple-video.json
index c15d7876470..56964b13565 100644
--- a/adapters/axonix/axonixtest/exemplary/simple-video.json
+++ b/adapters/axonix/axonixtest/exemplary/simple-video.json
@@ -12,7 +12,7 @@
},
"ext":{
"bidder":{
- "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8"
+ "supplyId": "supply-test"
}
}
}
@@ -22,7 +22,7 @@
"httpCalls": [
{
"expectedRequest": {
- "uri": "https://openrtb-us-east-1.axonix.com/supply/prebid-server/24cc9034-f861-47b8-a6a8-b7e0968c00b8",
+ "uri": "https://axonix.com/supply/prebid-server/supply-test",
"body": {
"id": "test-request-id",
"imp": [
@@ -36,7 +36,7 @@
},
"ext": {
"bidder": {
- "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8"
+ "supplyId": "supply-test"
}
}
}
diff --git a/adapters/axonix/axonixtest/params/race/banner.json b/adapters/axonix/axonixtest/params/race/banner.json
index 7217c9c394f..136be9b1517 100644
--- a/adapters/axonix/axonixtest/params/race/banner.json
+++ b/adapters/axonix/axonixtest/params/race/banner.json
@@ -1,3 +1,3 @@
{
- "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8"
+ "supplyId": "supply-test"
}
diff --git a/adapters/axonix/axonixtest/params/race/video.json b/adapters/axonix/axonixtest/params/race/video.json
index 7217c9c394f..136be9b1517 100644
--- a/adapters/axonix/axonixtest/params/race/video.json
+++ b/adapters/axonix/axonixtest/params/race/video.json
@@ -1,3 +1,3 @@
{
- "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8"
+ "supplyId": "supply-test"
}
diff --git a/adapters/axonix/axonixtest/supplemental/bad-response-no-body.json b/adapters/axonix/axonixtest/supplemental/bad-response-no-body.json
index f89f40f122d..a4704990ef6 100644
--- a/adapters/axonix/axonixtest/supplemental/bad-response-no-body.json
+++ b/adapters/axonix/axonixtest/supplemental/bad-response-no-body.json
@@ -12,7 +12,7 @@
},
"ext":{
"bidder":{
- "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8"
+ "supplyId": "supply-test"
}
}
}
@@ -22,7 +22,7 @@
"httpCalls": [
{
"expectedRequest": {
- "uri": "https://openrtb-us-east-1.axonix.com/supply/prebid-server/24cc9034-f861-47b8-a6a8-b7e0968c00b8",
+ "uri": "https://axonix.com/supply/prebid-server/supply-test",
"body": {
"id": "test-request-id",
"imp": [
@@ -36,7 +36,7 @@
},
"ext": {
"bidder": {
- "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8"
+ "supplyId": "supply-test"
}
}
}
diff --git a/adapters/axonix/axonixtest/supplemental/status-bad-request.json b/adapters/axonix/axonixtest/supplemental/status-bad-request.json
index d64a855e348..7483da19834 100644
--- a/adapters/axonix/axonixtest/supplemental/status-bad-request.json
+++ b/adapters/axonix/axonixtest/supplemental/status-bad-request.json
@@ -12,7 +12,7 @@
},
"ext":{
"bidder":{
- "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8"
+ "supplyId": "supply-test"
}
}
}
@@ -22,7 +22,7 @@
"httpCalls": [
{
"expectedRequest": {
- "uri": "https://openrtb-us-east-1.axonix.com/supply/prebid-server/24cc9034-f861-47b8-a6a8-b7e0968c00b8",
+ "uri": "https://axonix.com/supply/prebid-server/supply-test",
"body": {
"id": "test-request-id",
"imp": [
@@ -36,7 +36,7 @@
},
"ext": {
"bidder": {
- "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8"
+ "supplyId": "supply-test"
}
}
}
diff --git a/adapters/axonix/axonixtest/supplemental/status-no-content.json b/adapters/axonix/axonixtest/supplemental/status-no-content.json
index 96dd899c1fb..7d4cd79589d 100644
--- a/adapters/axonix/axonixtest/supplemental/status-no-content.json
+++ b/adapters/axonix/axonixtest/supplemental/status-no-content.json
@@ -12,7 +12,7 @@
},
"ext":{
"bidder":{
- "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8"
+ "supplyId": "supply-test"
}
}
}
@@ -22,7 +22,7 @@
"httpCalls": [
{
"expectedRequest": {
- "uri": "https://openrtb-us-east-1.axonix.com/supply/prebid-server/24cc9034-f861-47b8-a6a8-b7e0968c00b8",
+ "uri": "https://axonix.com/supply/prebid-server/supply-test",
"body": {
"id": "test-request-id",
"imp": [
@@ -36,7 +36,7 @@
},
"ext": {
"bidder": {
- "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8"
+ "supplyId": "supply-test"
}
}
}
diff --git a/adapters/axonix/axonixtest/supplemental/unexpected-status-code.json b/adapters/axonix/axonixtest/supplemental/unexpected-status-code.json
index e7a7be7847e..fe0f7141bc8 100644
--- a/adapters/axonix/axonixtest/supplemental/unexpected-status-code.json
+++ b/adapters/axonix/axonixtest/supplemental/unexpected-status-code.json
@@ -12,7 +12,7 @@
},
"ext":{
"bidder":{
- "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8"
+ "supplyId": "supply-test"
}
}
}
@@ -22,7 +22,7 @@
"httpCalls": [
{
"expectedRequest": {
- "uri": "https://openrtb-us-east-1.axonix.com/supply/prebid-server/24cc9034-f861-47b8-a6a8-b7e0968c00b8",
+ "uri": "https://axonix.com/supply/prebid-server/supply-test",
"body": {
"id": "test-request-id",
"imp": [
@@ -36,7 +36,7 @@
},
"ext": {
"bidder": {
- "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8"
+ "supplyId": "supply-test"
}
}
}
diff --git a/adapters/axonix/axonixtest/supplemental/valid-extension.json b/adapters/axonix/axonixtest/supplemental/valid-extension.json
index 372f24d4f76..c174d245bc8 100644
--- a/adapters/axonix/axonixtest/supplemental/valid-extension.json
+++ b/adapters/axonix/axonixtest/supplemental/valid-extension.json
@@ -12,7 +12,7 @@
},
"ext":{
"bidder":{
- "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8"
+ "supplyId": "supply-test"
}
}
}
@@ -22,7 +22,7 @@
"httpCalls": [
{
"expectedRequest": {
- "uri": "https://openrtb-us-east-1.axonix.com/supply/prebid-server/24cc9034-f861-47b8-a6a8-b7e0968c00b8",
+ "uri": "https://axonix.com/supply/prebid-server/supply-test",
"body": {
"id": "test-request-id",
"imp": [
@@ -36,7 +36,7 @@
},
"ext": {
"bidder": {
- "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8"
+ "supplyId": "supply-test"
}
}
}
diff --git a/adapters/axonix/axonixtest/supplemental/valid-with-device.json b/adapters/axonix/axonixtest/supplemental/valid-with-device.json
index 62f4ea06b5a..50d48410e8a 100644
--- a/adapters/axonix/axonixtest/supplemental/valid-with-device.json
+++ b/adapters/axonix/axonixtest/supplemental/valid-with-device.json
@@ -16,7 +16,7 @@
},
"ext": {
"bidder": {
- "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8"
+ "supplyId": "supply-test"
}
}
}
@@ -25,7 +25,7 @@
"httpCalls": [
{
"expectedRequest": {
- "uri": "https://openrtb-us-east-1.axonix.com/supply/prebid-server/24cc9034-f861-47b8-a6a8-b7e0968c00b8",
+ "uri": "https://axonix.com/supply/prebid-server/supply-test",
"body": {
"id": "test-request-id",
"device": {
@@ -43,7 +43,7 @@
},
"ext": {
"bidder": {
- "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8"
+ "supplyId": "supply-test"
}
}
}
diff --git a/adapters/axonix/params_test.go b/adapters/axonix/params_test.go
index e9c0cc5b83e..22b17a862f0 100644
--- a/adapters/axonix/params_test.go
+++ b/adapters/axonix/params_test.go
@@ -40,7 +40,7 @@ func TestInvalidParams(t *testing.T) {
}
var validParams = []string{
- `{"supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8"}`,
+ `{"supplyId": "test-supply"}`,
`{"supplyId": "test"}`,
}
diff --git a/adapters/inmobi/inmobi.go b/adapters/inmobi/inmobi.go
index a23472e8892..63baa8a4ba5 100644
--- a/adapters/inmobi/inmobi.go
+++ b/adapters/inmobi/inmobi.go
@@ -124,6 +124,9 @@ func getMediaTypeForImp(impId string, imps []openrtb2.Imp) openrtb_ext.BidType {
if imp.Video != nil {
mediaType = openrtb_ext.BidTypeVideo
}
+ if imp.Native != nil {
+ mediaType = openrtb_ext.BidTypeNative
+ }
break
}
}
diff --git a/adapters/inmobi/inmobitest/exemplary/simple-app-native.json b/adapters/inmobi/inmobitest/exemplary/simple-app-native.json
new file mode 100644
index 00000000000..3a5bfd38412
--- /dev/null
+++ b/adapters/inmobi/inmobitest/exemplary/simple-app-native.json
@@ -0,0 +1,105 @@
+{
+ "mockBidRequest": {
+ "app": {
+ "bundle": "com.example.app"
+ },
+ "id": "req-id",
+ "device": {
+ "ifa": "9d8fe0a9-c0dd-4482-b16b-5709b00c608d",
+ "ip": "1.1.1.1",
+ "ua": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G960F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36"
+ },
+ "imp": [
+ {
+ "ext": {
+ "bidder": {
+ "plc": "1618933962959"
+ }
+ },
+ "native": {
+ "request": "{\"ver\":\"1.2\",\"context\":2,\"contextsubtype\":20,\"plcmttype\":11,\"plcmtcnt\":1,\"aurlsupport\":1,\"durlsupport\":1,\"assets\":[{\"id\":123,\"required\":1,\"title\":{\"len\":140}},{\"id\":128,\"required\":0,\"img\":{\"wmin\":836,\"hmin\":627,\"type\":3}}]}"
+ },
+ "id": "imp-id"
+ }
+ ]
+ },
+ "httpCalls": [{
+ "expectedRequest": {
+ "uri": "https://api.w.inmobi.com/showad/openrtb/bidder/prebid",
+ "body": {
+ "app": {
+ "bundle": "com.example.app"
+ },
+ "id": "req-id",
+ "device": {
+ "ifa": "9d8fe0a9-c0dd-4482-b16b-5709b00c608d",
+ "ip": "1.1.1.1",
+ "ua": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G960F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36"
+ },
+ "imp": [
+ {
+ "ext": {
+ "bidder": {
+ "plc": "1618933962959"
+ }
+ },
+ "native": {
+ "request": "{\"ver\":\"1.2\",\"context\":2,\"contextsubtype\":20,\"plcmttype\":11,\"plcmtcnt\":1,\"aurlsupport\":1,\"durlsupport\":1,\"assets\":[{\"id\":123,\"required\":1,\"title\":{\"len\":140}},{\"id\":128,\"required\":0,\"img\":{\"wmin\":836,\"hmin\":627,\"type\":3}}]}"
+ },
+ "id": "imp-id"
+ }
+ ]
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "req-id",
+ "seatbid": [
+ {
+ "bid": [
+ {
+ "ext": {
+ "prebid": {
+ "meta": {
+ "networkName": "inmobi"
+ }
+ }
+ },
+ "nurl": "https://some.event.url/params",
+ "crid": "123456789",
+ "adomain": [],
+ "price": 2.0,
+ "id": "1234",
+ "adm": "native-json",
+ "impid": "imp-id"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }],
+
+ "expectedBidResponses": [{
+ "currency": "USD",
+ "bids": [{
+ "bid": {
+ "id": "1234",
+ "impid": "imp-id",
+ "price": 2.0,
+ "adm": "native-json",
+ "crid": "123456789",
+ "nurl": "https://some.event.url/params",
+ "ext": {
+ "prebid": {
+ "meta": {
+ "networkName": "inmobi"
+ }
+ }
+ }
+ },
+ "type": "native"
+ }]
+ }]
+}
diff --git a/adapters/ix/params_test.go b/adapters/ix/params_test.go
new file mode 100644
index 00000000000..9246a43a725
--- /dev/null
+++ b/adapters/ix/params_test.go
@@ -0,0 +1,59 @@
+package ix
+
+import (
+ "encoding/json"
+ "testing"
+
+ "github.com/prebid/prebid-server/openrtb_ext"
+)
+
+func TestValidParams(t *testing.T) {
+ validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params")
+ if err != nil {
+ t.Fatalf("Failed to fetch the json-schemas. %v", err)
+ }
+
+ for _, validParam := range validParams {
+ if err := validator.Validate(openrtb_ext.BidderIx, json.RawMessage(validParam)); err != nil {
+ t.Errorf("Schema rejected ix params: %s", validParam)
+ }
+ }
+}
+
+func TestInvalidParams(t *testing.T) {
+ validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params")
+ if err != nil {
+ t.Fatalf("Failed to fetch the json-schemas. %v", err)
+ }
+
+ for _, invalidParam := range invalidParams {
+ if err := validator.Validate(openrtb_ext.BidderIx, json.RawMessage(invalidParam)); err == nil {
+ t.Errorf("Schema allowed unexpected params: %s", invalidParam)
+ }
+ }
+}
+
+var validParams = []string{
+ `{"siteid":"1234"}`,
+ `{"siteID":"12345"}`,
+ `{"siteId":"123456"}`,
+ `{"siteid":"1234567", "size": [640,480]}`,
+}
+
+var invalidParams = []string{
+ `{"siteid":""}`,
+ `{"siteID":""}`,
+ `{"siteId":""}`,
+ `{"siteid":"1234", "siteID":"12345"}`,
+ `{"siteid":"1234", "siteId":"123456"}`,
+ `{"siteid":123}`,
+ `{"siteids":"123"}`,
+ `{"notaparam":"123"}`,
+ `{"siteid":"123", "size": [1,2,3]}`,
+ `null`,
+ `true`,
+ `0`,
+ `abc`,
+ `[]`,
+ `{}`,
+}
diff --git a/adapters/smaato/smaato.go b/adapters/smaato/smaato.go
index c50efffc994..c84dd356a59 100644
--- a/adapters/smaato/smaato.go
+++ b/adapters/smaato/smaato.go
@@ -17,7 +17,7 @@ import (
"github.com/prebid/prebid-server/util/timeutil"
)
-const clientVersion = "prebid_server_0.3"
+const clientVersion = "prebid_server_0.4"
type adMarkupType string
@@ -160,24 +160,53 @@ func (adapter *adapter) makeIndividualRequests(request *openrtb2.BidRequest) ([]
errors := make([]error, 0, len(imps))
for _, imp := range imps {
- request.Imp = []openrtb2.Imp{imp}
- if err := prepareIndividualRequest(request); err != nil {
- errors = append(errors, err)
- continue
- }
-
- requestData, err := adapter.makeRequest(request)
+ impsByMediaType, err := splitImpressionsByMediaType(&imp)
if err != nil {
errors = append(errors, err)
continue
}
- requests = append(requests, requestData)
+ for _, impByMediaType := range impsByMediaType {
+ request.Imp = []openrtb2.Imp{impByMediaType}
+ if err := prepareIndividualRequest(request); err != nil {
+ errors = append(errors, err)
+ continue
+ }
+
+ requestData, err := adapter.makeRequest(request)
+ if err != nil {
+ errors = append(errors, err)
+ continue
+ }
+
+ requests = append(requests, requestData)
+ }
}
return requests, errors
}
+func splitImpressionsByMediaType(imp *openrtb2.Imp) ([]openrtb2.Imp, error) {
+ if imp.Banner == nil && imp.Video == nil {
+ return nil, &errortypes.BadInput{Message: "Invalid MediaType. Smaato only supports Banner and Video."}
+ }
+
+ imps := make([]openrtb2.Imp, 0, 2)
+
+ if imp.Banner != nil {
+ impCopy := *imp
+ impCopy.Video = nil
+ imps = append(imps, impCopy)
+ }
+
+ if imp.Video != nil {
+ imp.Banner = nil
+ imps = append(imps, *imp)
+ }
+
+ return imps, nil
+}
+
func (adapter *adapter) makePodRequests(request *openrtb2.BidRequest) ([]*adapters.RequestData, []error) {
pods, orderedKeys, errors := groupImpressionsByPod(request.Imp)
requests := make([]*adapters.RequestData, 0, len(pods))
@@ -436,7 +465,7 @@ func setImpForAdspace(imp *openrtb2.Imp) error {
return nil
}
- return &errortypes.BadInput{Message: "Invalid MediaType. Smaato only supports Banner and Video."}
+ return nil
}
func setImpForAdBreak(imps []openrtb2.Imp) error {
diff --git a/adapters/smaato/smaatotest/exemplary/multiple-impressions.json b/adapters/smaato/smaatotest/exemplary/multiple-impressions.json
index e86fea8eb04..c30a9a6a39e 100644
--- a/adapters/smaato/smaatotest/exemplary/multiple-impressions.json
+++ b/adapters/smaato/smaatotest/exemplary/multiple-impressions.json
@@ -31,6 +31,7 @@
}
]
},
+ "bidfloor": 0.00123,
"ext": {
"bidder": {
"publisherId": "1100042525",
@@ -65,6 +66,7 @@
"rewarded": 0
}
},
+ "bidfloor": 0.00456,
"ext": {
"bidder": {
"publisherId": "1100042526",
@@ -114,6 +116,7 @@
{
"id": "1C86242D-9535-47D6-9576-7B1FE87F282C",
"tagid": "130563103",
+ "bidfloor": 0.00123,
"banner": {
"h": 50,
"w": 320,
@@ -159,7 +162,7 @@
"keywords": "power tools"
},
"ext": {
- "client": "prebid_server_0.3"
+ "client": "prebid_server_0.4"
}
}
},
@@ -208,6 +211,7 @@
{
"id": "postbid_iframe",
"tagid": "130563104",
+ "bidfloor": 0.00456,
"video": {
"w": 1024,
"h": 768,
@@ -264,7 +268,7 @@
"keywords": "power tools"
},
"ext": {
- "client": "prebid_server_0.3"
+ "client": "prebid_server_0.4"
}
}
},
diff --git a/adapters/smaato/smaatotest/exemplary/multiple-media-types.json b/adapters/smaato/smaatotest/exemplary/multiple-media-types.json
new file mode 100644
index 00000000000..a7d97666778
--- /dev/null
+++ b/adapters/smaato/smaatotest/exemplary/multiple-media-types.json
@@ -0,0 +1,348 @@
+{
+ "mockBidRequest": {
+ "id": "1C86242D-9535-47D6-9576-7B1FE87F282C",
+ "site": {
+ "publisher": {
+ "id": "1100042525"
+ },
+ "page": "http://localhost:3000/server.html?pbjs_debug=true&endpoint=http://localhost:3000/bidder",
+ "ext": {
+ "data": {
+ "keywords": "power tools",
+ "search": "drill",
+ "content": {
+ "userrating": 4
+ }
+ }
+ }
+ },
+ "imp": [
+ {
+ "id": "1C86242D-9535-47D6-9576-7B1FE87F282C",
+ "banner": {
+ "format": [
+ {
+ "w": 320,
+ "h": 50
+ },
+ {
+ "w": 320,
+ "h": 250
+ }
+ ]
+ },
+ "video": {
+ "mimes": [
+ "video/mp4",
+ "video/quicktime",
+ "video/3gpp",
+ "video/x-m4v"
+ ],
+ "minduration": 5,
+ "maxduration": 30,
+ "protocols": [
+ 7
+ ],
+ "w": 1024,
+ "h": 768,
+ "startdelay": 0,
+ "linearity": 1,
+ "skip": 1,
+ "skipmin": 5,
+ "api": [
+ 7
+ ],
+ "ext": {
+ "rewarded": 0
+ }
+ },
+ "bidfloor": 0.00123,
+ "ext": {
+ "bidder": {
+ "publisherId": "1100042525",
+ "adspaceId": "130563103"
+ }
+ }
+ }
+ ],
+ "device": {
+ "ua": "test-user-agent",
+ "ip": "123.123.123.123",
+ "language": "en",
+ "dnt": 0
+ },
+ "user": {
+ "ext": {
+ "consent": "gdprConsentString",
+ "data": {
+ "keywords": "a,b",
+ "gender": "M",
+ "yob": 1984,
+ "geo": {
+ "country": "ca"
+ }
+ }
+ }
+ },
+ "regs": {
+ "coppa": 1,
+ "ext": {
+ "gdpr": 1,
+ "us_privacy": "uspConsentString"
+ }
+ }
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "headers": {
+ "Content-Type": ["application/json;charset=utf-8"],
+ "Accept": ["application/json"]
+ },
+ "uri": "https://prebid/bidder",
+ "body": {
+ "id": "1C86242D-9535-47D6-9576-7B1FE87F282C",
+ "imp": [
+ {
+ "id": "1C86242D-9535-47D6-9576-7B1FE87F282C",
+ "tagid": "130563103",
+ "bidfloor": 0.00123,
+ "banner": {
+ "h": 50,
+ "w": 320,
+ "format": [
+ {
+ "w": 320,
+ "h": 50
+ },
+ {
+ "w": 320,
+ "h": 250
+ }
+ ]
+ }
+ }
+ ],
+ "user": {
+ "ext": {
+ "consent": "gdprConsentString"
+ },
+ "gender": "M",
+ "keywords": "a,b",
+ "yob": 1984
+ },
+ "device": {
+ "ua": "test-user-agent",
+ "ip": "123.123.123.123",
+ "language": "en",
+ "dnt": 0
+ },
+ "regs": {
+ "coppa": 1,
+ "ext": {
+ "gdpr": 1,
+ "us_privacy": "uspConsentString"
+ }
+ },
+ "site": {
+ "publisher": {
+ "id": "1100042525"
+ },
+ "page": "http://localhost:3000/server.html?pbjs_debug=true&endpoint=http://localhost:3000/bidder",
+ "keywords": "power tools"
+ },
+ "ext": {
+ "client": "prebid_server_0.4"
+ }
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "5ebea288-f13a-4754-be6d-4ade66c68877",
+ "seatbid": [
+ {
+ "seat": "CM6523",
+ "bid": [
+ {
+ "adm": "{\"image\":{\"img\":{\"url\":\"//prebid-test.smaatolabs.net/img/320x50.jpg\",\"w\":350,\"h\":50,\"ctaurl\":\"//prebid-test.smaatolabs.net/track/ctaurl/1\"},\"impressiontrackers\":[\"//prebid-test.smaatolabs.net/track/imp/1\",\"//prebid-test.smaatolabs.net/track/imp/2\"],\"clicktrackers\":[\"//prebid-test.smaatolabs.net/track/click/1\",\"//prebid-test.smaatolabs.net/track/click/2\"]}}",
+ "adomain": [
+ "smaato.com"
+ ],
+ "bidderName": "smaato",
+ "cid": "CM6523",
+ "crid": "CR69381",
+ "id": "6906aae8-7f74-4edd-9a4f-f49379a3cadd",
+ "impid": "1C86242D-9535-47D6-9576-7B1FE87F282C",
+ "iurl": "https://bidstalkcreatives.s3.amazonaws.com/1x1.png",
+ "nurl": "https://ets-eu-west-1.track.smaato.net/v1/view?sessionId=e4e17adb-9599-42b1-bb5f-a1f1b3bee572&adSourceId=6906aae8-7f74-4edd-9a4f-f49379a3cadd&originalRequestTime=1552310449698&expires=1552311350698&winurl=ama8JbpJVpFWxvEja5viE3cLXFu58qRI8dGUh23xtsOn3N2-5UU0IwkgNEmR82pI37fcMXejL5IWTNAoW6Cnsjf-Dxl_vx2dUqMrVEevX-Vdx2VVnf-D5f73gZhvi4t36iPL8Dsw4aACekoLvVOV7-eXDjz7GHy60QFqcwKf5g2AlKPOInyZ6vJg_fn4qA9argvCRgwVybXE9Ndm2W0v8La4uFYWpJBOUveDDUrSQfzal7RsYvLb_OyaMlPHdrd_bwA9qqZWuyJXd-L9lxr7RQ%3D%3D%7CMw3kt91KJR0Uy5L-oNztAg%3D%3D&dpid=4XVofb_lH-__hr2JNGhKfg%3D%3D%7Cr9ciCU1cx3zmHXihItKO0g%3D%3D",
+ "price": 0.01,
+ "w": 350,
+ "h": 50
+ }
+ ]
+ }
+ ],
+ "bidid": "04db8629-179d-4bcd-acce-e54722969006",
+ "cur": "USD"
+ }
+ }
+ },
+ {
+ "expectedRequest": {
+ "headers": {
+ "Content-Type": ["application/json;charset=utf-8"],
+ "Accept": ["application/json"]
+ },
+ "uri": "https://prebid/bidder",
+ "body": {
+ "id": "1C86242D-9535-47D6-9576-7B1FE87F282C",
+ "imp": [
+ {
+ "id": "1C86242D-9535-47D6-9576-7B1FE87F282C",
+ "tagid": "130563103",
+ "bidfloor": 0.00123,
+ "video": {
+ "w": 1024,
+ "h": 768,
+ "ext": {
+ "rewarded": 0
+ },
+ "mimes": [
+ "video/mp4",
+ "video/quicktime",
+ "video/3gpp",
+ "video/x-m4v"
+ ],
+ "minduration": 5,
+ "startdelay": 0,
+ "linearity": 1,
+ "maxduration": 30,
+ "skip": 1,
+ "protocols": [
+ 7
+ ],
+ "skipmin": 5,
+ "api": [
+ 7
+ ]
+ }
+ }
+ ],
+ "user": {
+ "ext": {
+ "consent": "gdprConsentString"
+ },
+ "gender": "M",
+ "keywords": "a,b",
+ "yob": 1984
+ },
+ "device": {
+ "ua": "test-user-agent",
+ "ip": "123.123.123.123",
+ "language": "en",
+ "dnt": 0
+ },
+ "regs": {
+ "coppa": 1,
+ "ext": {
+ "gdpr": 1,
+ "us_privacy": "uspConsentString"
+ }
+ },
+ "site": {
+ "publisher": {
+ "id": "1100042525"
+ },
+ "page": "http://localhost:3000/server.html?pbjs_debug=true&endpoint=http://localhost:3000/bidder",
+ "keywords": "power tools"
+ },
+ "ext": {
+ "client": "prebid_server_0.4"
+ }
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "5ebea288-f13a-4754-be6d-4ade66c68877",
+ "seatbid": [
+ {
+ "seat": "CM6523",
+ "bid": [
+ {
+ "adm": "