diff --git a/adapters/33across/usersync_test.go b/adapters/33across/usersync_test.go
index f4bb28150de..a5e301b1082 100644
--- a/adapters/33across/usersync_test.go
+++ b/adapters/33across/usersync_test.go
@@ -5,20 +5,30 @@ import (
"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 Test33AcrossSyncer(t *testing.T) {
- syncURL := "https://ic.tynt.com/r/d?m=xch&rt=html&ri=123&ru=%2Fsetuid%3Fbidder%3D33across%26uid%3D33XUSERID33X&id=zzz000000000002zzz"
+ syncURL := "https://ic.tynt.com/r/d?m=xch&rt=html&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&ru=%2Fsetuid%3Fbidder%3D33across%26uid%3D33XUSERID33X&id=zzz000000000002zzz"
syncURLTemplate := template.Must(
template.New("sync-template").Parse(syncURL),
)
syncer := New33AcrossSyncer(syncURLTemplate)
- syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{})
+ syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{
+ GDPR: gdpr.Policy{
+ Signal: "A",
+ Consent: "B",
+ },
+ CCPA: ccpa.Policy{
+ Value: "C",
+ },
+ })
assert.NoError(t, err)
- assert.Equal(t, "https://ic.tynt.com/r/d?m=xch&rt=html&ri=123&ru=%2Fsetuid%3Fbidder%3D33across%26uid%3D33XUSERID33X&id=zzz000000000002zzz", syncInfo.URL)
+ assert.Equal(t, "https://ic.tynt.com/r/d?m=xch&rt=html&gdpr=A&gdpr_consent=B&us_privacy=C&ru=%2Fsetuid%3Fbidder%3D33across%26uid%3D33XUSERID33X&id=zzz000000000002zzz", syncInfo.URL)
assert.Equal(t, "iframe", syncInfo.Type)
assert.EqualValues(t, 58, syncer.GDPRVendorID())
assert.False(t, syncInfo.SupportCORS)
diff --git a/adapters/adform/adform_test.go b/adapters/adform/adform_test.go
index e59bd951858..63646f5f7f5 100644
--- a/adapters/adform/adform_test.go
+++ b/adapters/adform/adform_test.go
@@ -21,6 +21,8 @@ import (
"github.com/prebid/prebid-server/adapters"
"github.com/prebid/prebid-server/config"
"github.com/prebid/prebid-server/openrtb_ext"
+
+ "github.com/stretchr/testify/assert"
)
func TestJsonSamples(t *testing.T) {
@@ -597,3 +599,77 @@ func TestPriceTypeUrlParameterCreation(t *testing.T) {
}
}
}
+
+// Asserts that toOpenRtbBidResponse() creates a *adapters.BidderResponse with
+// the currency of the last valid []*adformBid element and the expected number of bids
+func TestToOpenRtbBidResponse(t *testing.T) {
+ expectedBids := 3
+ lastCurrency, anotherCurrency, emptyCurrency := "EUR", "USD", ""
+
+ request := &openrtb.BidRequest{
+ ID: "test-request-id",
+ Imp: []openrtb.Imp{
+ {
+ ID: "banner-imp-no1",
+ Ext: json.RawMessage(`{"bidder1": { "mid": "32341" }}`),
+ Banner: &openrtb.Banner{},
+ },
+ {
+ ID: "banner-imp-no2",
+ Ext: json.RawMessage(`{"bidder1": { "mid": "32342" }}`),
+ Banner: &openrtb.Banner{},
+ },
+ {
+ ID: "banner-imp-no3",
+ Ext: json.RawMessage(`{"bidder1": { "mid": "32343" }}`),
+ Banner: &openrtb.Banner{},
+ },
+ {
+ ID: "banner-imp-no4",
+ Ext: json.RawMessage(`{"bidder1": { "mid": "32344" }}`),
+ Banner: &openrtb.Banner{},
+ },
+ },
+ Device: &openrtb.Device{UA: "ua", IP: "ip"},
+ User: &openrtb.User{BuyerUID: "buyerUID"},
+ }
+
+ testAdformBids := []*adformBid{
+ {
+ ResponseType: "banner",
+ Banner: "banner-content1",
+ Price: 1.23,
+ Currency: anotherCurrency,
+ Width: 300,
+ Height: 200,
+ DealId: "dealId1",
+ CreativeId: "creativeId1",
+ },
+ {},
+ {
+ ResponseType: "banner",
+ Banner: "banner-content3",
+ Price: 1.24,
+ Currency: emptyCurrency,
+ Width: 300,
+ Height: 200,
+ DealId: "dealId3",
+ CreativeId: "creativeId3",
+ },
+ {
+ ResponseType: "banner",
+ Banner: "banner-content4",
+ Price: 1.25,
+ Currency: lastCurrency,
+ Width: 300,
+ Height: 200,
+ DealId: "dealId4",
+ CreativeId: "creativeId4",
+ },
+ }
+
+ actualBidResponse := toOpenRtbBidResponse(testAdformBids, request)
+
+ assert.Equalf(t, expectedBids, len(actualBidResponse.Bids), "bid count")
+ assert.Equalf(t, lastCurrency, actualBidResponse.Currency, "currency")
+}
diff --git a/adapters/adkernel/usersync_test.go b/adapters/adkernel/usersync_test.go
index bd09c361a03..0d539d11ee0 100644
--- a/adapters/adkernel/usersync_test.go
+++ b/adapters/adkernel/usersync_test.go
@@ -5,12 +5,13 @@ import (
"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 TestAdkernelAdnSyncer(t *testing.T) {
- syncURL := "https://sync.adkernel.com/user-sync?t=image&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&r=https%3A%2F%2Flocalhost%3A8888%2Fsetuid%3Fbidder%3Dadkernel%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%7BUID%7D"
+ syncURL := "https://sync.adkernel.com/user-sync?t=image&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r=https%3A%2F%2Flocalhost%3A8888%2Fsetuid%3Fbidder%3Dadkernel%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%7BUID%7D"
syncURLTemplate := template.Must(
template.New("sync-template").Parse(syncURL),
)
@@ -21,10 +22,13 @@ func TestAdkernelAdnSyncer(t *testing.T) {
Signal: "1",
Consent: "BONciguONcjGKADACHENAOLS1rAHDAFAAEAASABQAMwAeACEAFw",
},
+ CCPA: ccpa.Policy{
+ Value: "1NYN",
+ },
})
assert.NoError(t, err)
- assert.Equal(t, "https://sync.adkernel.com/user-sync?t=image&gdpr=1&gdpr_consent=BONciguONcjGKADACHENAOLS1rAHDAFAAEAASABQAMwAeACEAFw&r=https%3A%2F%2Flocalhost%3A8888%2Fsetuid%3Fbidder%3Dadkernel%26gdpr%3D1%26gdpr_consent%3DBONciguONcjGKADACHENAOLS1rAHDAFAAEAASABQAMwAeACEAFw%26uid%3D%7BUID%7D", syncInfo.URL)
+ assert.Equal(t, "https://sync.adkernel.com/user-sync?t=image&gdpr=1&gdpr_consent=BONciguONcjGKADACHENAOLS1rAHDAFAAEAASABQAMwAeACEAFw&us_privacy=1NYN&r=https%3A%2F%2Flocalhost%3A8888%2Fsetuid%3Fbidder%3Dadkernel%26gdpr%3D1%26gdpr_consent%3DBONciguONcjGKADACHENAOLS1rAHDAFAAEAASABQAMwAeACEAFw%26uid%3D%7BUID%7D", syncInfo.URL)
assert.Equal(t, "redirect", syncInfo.Type)
assert.EqualValues(t, adkernelGDPRVendorID, syncer.GDPRVendorID())
assert.Equal(t, false, syncInfo.SupportCORS)
diff --git a/adapters/adkernelAdn/usersync_test.go b/adapters/adkernelAdn/usersync_test.go
index 007cacce29c..ecc759bdf70 100644
--- a/adapters/adkernelAdn/usersync_test.go
+++ b/adapters/adkernelAdn/usersync_test.go
@@ -5,12 +5,13 @@ import (
"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 TestAdkernelAdnSyncer(t *testing.T) {
- syncURL := "https://tag.adkernel.com/syncr?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&r=https%3A%2F%2Flocalhost%3A8888%2Fsetuid%3Fbidder%3DadkernelAdn%26uid%3D%7BUID%7D"
+ syncURL := "https://tag.adkernel.com/syncr?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r=https%3A%2F%2Flocalhost%3A8888%2Fsetuid%3Fbidder%3DadkernelAdn%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%7BUID%7D"
syncURLTemplate := template.Must(
template.New("sync-template").Parse(syncURL),
)
@@ -21,10 +22,13 @@ func TestAdkernelAdnSyncer(t *testing.T) {
Signal: "1",
Consent: "BONciguONcjGKADACHENAOLS1rAHDAFAAEAASABQAMwAeACEAFw",
},
+ CCPA: ccpa.Policy{
+ Value: "1NYN",
+ },
})
assert.NoError(t, err)
- assert.Equal(t, "https://tag.adkernel.com/syncr?gdpr=1&gdpr_consent=BONciguONcjGKADACHENAOLS1rAHDAFAAEAASABQAMwAeACEAFw&r=https%3A%2F%2Flocalhost%3A8888%2Fsetuid%3Fbidder%3DadkernelAdn%26uid%3D%7BUID%7D", syncInfo.URL)
+ assert.Equal(t, "https://tag.adkernel.com/syncr?gdpr=1&gdpr_consent=BONciguONcjGKADACHENAOLS1rAHDAFAAEAASABQAMwAeACEAFw&us_privacy=1NYN&r=https%3A%2F%2Flocalhost%3A8888%2Fsetuid%3Fbidder%3DadkernelAdn%26gdpr%3D1%26gdpr_consent%3DBONciguONcjGKADACHENAOLS1rAHDAFAAEAASABQAMwAeACEAFw%26uid%3D%7BUID%7D", syncInfo.URL)
assert.Equal(t, "redirect", syncInfo.Type)
assert.EqualValues(t, adkernelGDPRVendorID, syncer.GDPRVendorID())
assert.Equal(t, false, syncInfo.SupportCORS)
diff --git a/adapters/adpone/adpone.go b/adapters/adpone/adpone.go
index 345a4988580..b1822a0ac07 100644
--- a/adapters/adpone/adpone.go
+++ b/adapters/adpone/adpone.go
@@ -3,9 +3,10 @@ package adpone
import (
"encoding/json"
"fmt"
- "github.com/prebid/prebid-server/openrtb_ext"
"net/http"
+ "github.com/prebid/prebid-server/openrtb_ext"
+
"github.com/mxmCherry/openrtb"
"github.com/prebid/prebid-server/adapters"
"github.com/prebid/prebid-server/errortypes"
diff --git a/adapters/adtelligent/adtelligenttest/supplemental/audio.json b/adapters/adtelligent/adtelligenttest/supplemental/audio.json
index aa9a40bcc99..d8904251e11 100644
--- a/adapters/adtelligent/adtelligenttest/supplemental/audio.json
+++ b/adapters/adtelligent/adtelligenttest/supplemental/audio.json
@@ -9,7 +9,7 @@
},
"ext": {
"bidder": {
- "placementId": 10433394
+ "placementId": 1
}
}
}
diff --git a/adapters/adtelligent/adtelligenttest/supplemental/native.json b/adapters/adtelligent/adtelligenttest/supplemental/native.json
index 90ddff2f679..00fb3984bc7 100644
--- a/adapters/adtelligent/adtelligenttest/supplemental/native.json
+++ b/adapters/adtelligent/adtelligenttest/supplemental/native.json
@@ -9,7 +9,7 @@
},
"ext": {
"bidder": {
- "placementId": 10433394
+ "placementId": 1
}
}
}
diff --git a/adapters/applogy/applogy.go b/adapters/applogy/applogy.go
new file mode 100644
index 00000000000..a1215e24940
--- /dev/null
+++ b/adapters/applogy/applogy.go
@@ -0,0 +1,160 @@
+package applogy
+
+import (
+ "encoding/json"
+ "errors"
+ "net/http"
+ "strconv"
+
+ "github.com/mxmCherry/openrtb"
+ "github.com/prebid/prebid-server/adapters"
+ "github.com/prebid/prebid-server/errortypes"
+ "github.com/prebid/prebid-server/openrtb_ext"
+)
+
+type ApplogyAdapter struct {
+ endpoint string
+}
+
+func (a *ApplogyAdapter) MakeRequests(request *openrtb.BidRequest, _ *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
+ headers := http.Header{}
+ headers.Add("Content-Type", "application/json;charset=utf-8")
+ headers.Add("Accept", "application/json")
+ impressions := request.Imp
+ result := make([]*adapters.RequestData, 0, len(impressions))
+ errs := make([]error, 0, len(impressions))
+
+ for i, impression := range impressions {
+ if impression.Banner == nil && impression.Video == nil && impression.Native == nil {
+ errs = append(errs, &errortypes.BadInput{
+ Message: "Applogy only supports banner, video or native ads",
+ })
+ continue
+ }
+ if impression.Banner != nil {
+ banner := impression.Banner
+ if banner.W == nil || banner.H == nil || *banner.W == 0 || *banner.H == 0 {
+ if len(banner.Format) == 0 {
+ errs = append(errs, &errortypes.BadInput{
+ Message: "banner size information missing",
+ })
+ continue
+ }
+ format := banner.Format[0]
+ banner.W = &format.W
+ banner.H = &format.H
+ }
+ }
+ if len(impression.Ext) == 0 {
+ errs = append(errs, errors.New("impression extensions required"))
+ continue
+ }
+ var bidderExt adapters.ExtImpBidder
+ err := json.Unmarshal(impression.Ext, &bidderExt)
+ if err != nil {
+ errs = append(errs, err)
+ continue
+ }
+ if len(bidderExt.Bidder) == 0 {
+ errs = append(errs, errors.New("bidder required"))
+ continue
+ }
+ var impressionExt openrtb_ext.ExtImpApplogy
+ err = json.Unmarshal(bidderExt.Bidder, &impressionExt)
+ if err != nil {
+ errs = append(errs, err)
+ continue
+ }
+ if impressionExt.Token == "" {
+ errs = append(errs, errors.New("Applogy token required"))
+ continue
+ }
+ request.Imp = impressions[i : i+1]
+ body, err := json.Marshal(request)
+ if err != nil {
+ errs = append(errs, err)
+ continue
+ }
+ result = append(result, &adapters.RequestData{
+ Method: "POST",
+ Uri: a.endpoint + "/" + impressionExt.Token,
+ Body: body,
+ Headers: headers,
+ })
+ }
+
+ request.Imp = impressions
+
+ if len(result) == 0 {
+ return nil, errs
+ }
+ return result, errs
+}
+
+func (a *ApplogyAdapter) MakeBids(request *openrtb.BidRequest, _ *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) {
+ var errs []error
+
+ switch responseData.StatusCode {
+ case http.StatusNoContent:
+ return nil, nil
+ case http.StatusBadRequest:
+ return nil, []error{&errortypes.BadInput{
+ Message: "unexpected status code: " + strconv.Itoa(responseData.StatusCode),
+ }}
+ case http.StatusOK:
+ break
+ default:
+ return nil, []error{&errortypes.BadServerResponse{
+ Message: "unexpected status code: " + strconv.Itoa(responseData.StatusCode),
+ }}
+ }
+
+ var bidResponse openrtb.BidResponse
+ err := json.Unmarshal(responseData.Body, &bidResponse)
+ if err != nil {
+ return nil, []error{&errortypes.BadServerResponse{
+ Message: err.Error(),
+ }}
+ }
+
+ response := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp))
+
+ for _, seatBid := range bidResponse.SeatBid {
+ for _, bid := range seatBid.Bid {
+ bid := bid // pin https://github.com/kyoh86/scopelint#whats-this
+ var bidType openrtb_ext.BidType
+ for _, impression := range request.Imp {
+ if impression.ID != bid.ImpID {
+ continue
+ }
+ switch {
+ case impression.Banner != nil:
+ bidType = openrtb_ext.BidTypeBanner
+ case impression.Video != nil:
+ bidType = openrtb_ext.BidTypeVideo
+ case impression.Native != nil:
+ bidType = openrtb_ext.BidTypeNative
+ }
+ break
+ }
+ if bidType == "" {
+ errs = append(errs, &errortypes.BadServerResponse{
+ Message: "ignoring bid id=" + bid.ID + ", request doesn't contain any valid impression with id=" + bid.ImpID,
+ })
+ continue
+ }
+ response.Bids = append(response.Bids, &adapters.TypedBid{
+ Bid: &bid,
+ BidType: bidType,
+ })
+ }
+ }
+
+ return response, errs
+}
+
+func NewApplogyBidder(endpoint string) *ApplogyAdapter {
+ return &ApplogyAdapter{
+ endpoint: endpoint,
+ }
+}
diff --git a/adapters/applogy/applogy_test.go b/adapters/applogy/applogy_test.go
new file mode 100644
index 00000000000..8883db5786a
--- /dev/null
+++ b/adapters/applogy/applogy_test.go
@@ -0,0 +1,11 @@
+package applogy
+
+import (
+ "testing"
+
+ "github.com/prebid/prebid-server/adapters/adapterstest"
+)
+
+func TestJsonSamples(t *testing.T) {
+ adapterstest.RunJSONBidderTest(t, "applogytest", NewApplogyBidder("http://example.com/prebid"))
+}
diff --git a/adapters/applogy/applogytest/exemplary/simple-banner.json b/adapters/applogy/applogytest/exemplary/simple-banner.json
new file mode 100644
index 00000000000..a3926dea623
--- /dev/null
+++ b/adapters/applogy/applogytest/exemplary/simple-banner.json
@@ -0,0 +1,170 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "imp": [{
+ "id": "test-impression-id-1",
+ "banner": {
+ "format": [{
+ "h": 250,
+ "w": 300
+ }]
+ },
+ "ext": {
+ "bidder": {
+ "token": "test-token-1"
+ }
+ }
+ }, {
+ "id": "test-impression-id-2",
+ "banner": {
+ "w": 300,
+ "h": 250
+ },
+ "ext": {
+ "bidder": {
+ "token": "test-token-1"
+ }
+ }
+ }, {
+ "id": "test-impression-id-3",
+ "banner": {
+ "w": 300,
+ "h": 250
+ },
+ "ext": {
+ "bidder": {
+ "token": "test-token-2"
+ }
+ }
+ }]
+ },
+ "httpCalls": [{
+ "expectedRequest": {
+ "uri": "http://example.com/prebid/test-token-1",
+ "body": {
+ "id": "test-request-id",
+ "imp": [{
+ "id": "test-impression-id-1",
+ "banner": {
+ "format": [{
+ "h": 250,
+ "w": 300
+ }],
+ "h": 250,
+ "w": 300
+ },
+ "ext": {
+ "bidder": {
+ "token": "test-token-1"
+ }
+ }
+ }]
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "test-response-id",
+ "seatbid": [{
+ "bid": [{
+ "id": "test-bid-id-1",
+ "impid": "test-impression-id-1",
+ "price": 1
+ }]
+ }]
+ }
+ }
+ }, {
+ "expectedRequest": {
+ "uri": "http://example.com/prebid/test-token-1",
+ "body": {
+ "id": "test-request-id",
+ "imp": [{
+ "id": "test-impression-id-2",
+ "banner": {
+ "h": 250,
+ "w": 300
+ },
+ "ext": {
+ "bidder": {
+ "token": "test-token-1"
+ }
+ }
+ }]
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "test-response-id-2",
+ "seatbid": [{
+ "bid": [{
+ "id": "test-bid-id-2",
+ "impid": "test-impression-id-2",
+ "price": 2
+ }]
+ }]
+ }
+ }
+ }, {
+ "expectedRequest": {
+ "uri": "http://example.com/prebid/test-token-2",
+ "body": {
+ "id": "test-request-id",
+ "imp": [{
+ "id": "test-impression-id-3",
+ "banner": {
+ "h": 250,
+ "w": 300
+ },
+ "ext": {
+ "bidder": {
+ "token": "test-token-2"
+ }
+ }
+ }]
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "test-response-id-3",
+ "seatbid": [{
+ "bid": [{
+ "id": "test-bid-id-3",
+ "impid": "test-impression-id-3",
+ "price": 3
+ }]
+ }]
+ }
+ }
+ }],
+ "expectedBidResponses": [{
+ "bids": [{
+ "bid": {
+ "id": "test-bid-id-1",
+ "impid": "test-impression-id-1",
+ "price": 1
+ },
+ "type": "banner"
+ }]
+ }, {
+ "bids": [{
+ "bid": {
+ "id": "test-bid-id-2",
+ "impid": "test-impression-id-2",
+ "price": 2
+ },
+ "type": "banner"
+ }]
+ }, {
+ "bids": [{
+ "bid": {
+ "id": "test-bid-id-3",
+ "impid": "test-impression-id-3",
+ "price": 3
+ },
+ "type": "banner"
+ }]
+ }]
+}
diff --git a/adapters/applogy/applogytest/exemplary/simple-native.json b/adapters/applogy/applogytest/exemplary/simple-native.json
new file mode 100644
index 00000000000..84565ec5575
--- /dev/null
+++ b/adapters/applogy/applogytest/exemplary/simple-native.json
@@ -0,0 +1,164 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "imp": [{
+ "id": "test-impression-id-1",
+ "native": {
+ "request": "{\"ver\":\"1.1\",\"context\":1,\"contextsubtype\":11,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":500}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":1,\"hmin\":1}},{\"id\":3,\"required\":0,\"data\":{\"type\":1,\"len\":200}},{\"id\":4,\"required\":0,\"data\":{\"type\":2,\"len\":15000}},{\"id\":5,\"required\":0,\"data\":{\"type\":6,\"len\":40}},{\"id\":6,\"required\":0,\"data\":{\"type\":500}}]}",
+ "ver": "1.1"
+ },
+ "ext": {
+ "bidder": {
+ "token": "test-token-1"
+ }
+ }
+ }, {
+ "id": "test-impression-id-2",
+ "native": {
+ "request": "{\"ver\":\"1.1\",\"context\":1,\"contextsubtype\":11,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":500}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":1,\"hmin\":1}},{\"id\":3,\"required\":0,\"data\":{\"type\":1,\"len\":200}},{\"id\":4,\"required\":0,\"data\":{\"type\":2,\"len\":15000}},{\"id\":5,\"required\":0,\"data\":{\"type\":6,\"len\":40}},{\"id\":6,\"required\":0,\"data\":{\"type\":500}}]}",
+ "ver": "1.1"
+ },
+ "ext": {
+ "bidder": {
+ "token": "test-token-1"
+ }
+ }
+ }, {
+ "id": "test-impression-id-3",
+ "native": {
+ "request": "{\"ver\":\"1.1\",\"context\":1,\"contextsubtype\":11,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":500}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":1,\"hmin\":1}},{\"id\":3,\"required\":0,\"data\":{\"type\":1,\"len\":200}},{\"id\":4,\"required\":0,\"data\":{\"type\":2,\"len\":15000}},{\"id\":5,\"required\":0,\"data\":{\"type\":6,\"len\":40}},{\"id\":6,\"required\":0,\"data\":{\"type\":500}}]}",
+ "ver": "1.1"
+ },
+ "ext": {
+ "bidder": {
+ "token": "test-token-2"
+ }
+ }
+ }]
+ },
+ "httpCalls": [{
+ "expectedRequest": {
+ "uri": "http://example.com/prebid/test-token-1",
+ "body": {
+ "id": "test-request-id",
+ "imp": [{
+ "id": "test-impression-id-1",
+ "native": {
+ "request": "{\"ver\":\"1.1\",\"context\":1,\"contextsubtype\":11,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":500}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":1,\"hmin\":1}},{\"id\":3,\"required\":0,\"data\":{\"type\":1,\"len\":200}},{\"id\":4,\"required\":0,\"data\":{\"type\":2,\"len\":15000}},{\"id\":5,\"required\":0,\"data\":{\"type\":6,\"len\":40}},{\"id\":6,\"required\":0,\"data\":{\"type\":500}}]}",
+ "ver": "1.1"
+ },
+ "ext": {
+ "bidder": {
+ "token": "test-token-1"
+ }
+ }
+ }]
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "test-response-id",
+ "seatbid": [{
+ "bid": [{
+ "id": "test-bid-id-1",
+ "impid": "test-impression-id-1",
+ "price": 1
+ }]
+ }]
+ }
+ }
+ }, {
+ "expectedRequest": {
+ "uri": "http://example.com/prebid/test-token-1",
+ "body": {
+ "id": "test-request-id",
+ "imp": [{
+ "id": "test-impression-id-2",
+ "native": {
+ "request": "{\"ver\":\"1.1\",\"context\":1,\"contextsubtype\":11,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":500}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":1,\"hmin\":1}},{\"id\":3,\"required\":0,\"data\":{\"type\":1,\"len\":200}},{\"id\":4,\"required\":0,\"data\":{\"type\":2,\"len\":15000}},{\"id\":5,\"required\":0,\"data\":{\"type\":6,\"len\":40}},{\"id\":6,\"required\":0,\"data\":{\"type\":500}}]}",
+ "ver": "1.1"
+ },
+ "ext": {
+ "bidder": {
+ "token": "test-token-1"
+ }
+ }
+ }]
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "test-response-id-2",
+ "seatbid": [{
+ "bid": [{
+ "id": "test-bid-id-2",
+ "impid": "test-impression-id-2",
+ "price": 2
+ }]
+ }]
+ }
+ }
+ }, {
+ "expectedRequest": {
+ "uri": "http://example.com/prebid/test-token-2",
+ "body": {
+ "id": "test-request-id",
+ "imp": [{
+ "id": "test-impression-id-3",
+ "native": {
+ "request": "{\"ver\":\"1.1\",\"context\":1,\"contextsubtype\":11,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":500}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":1,\"hmin\":1}},{\"id\":3,\"required\":0,\"data\":{\"type\":1,\"len\":200}},{\"id\":4,\"required\":0,\"data\":{\"type\":2,\"len\":15000}},{\"id\":5,\"required\":0,\"data\":{\"type\":6,\"len\":40}},{\"id\":6,\"required\":0,\"data\":{\"type\":500}}]}",
+ "ver": "1.1"
+ },
+ "ext": {
+ "bidder": {
+ "token": "test-token-2"
+ }
+ }
+ }]
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "test-response-id-3",
+ "seatbid": [{
+ "bid": [{
+ "id": "test-bid-id-3",
+ "impid": "test-impression-id-3",
+ "price": 3
+ }]
+ }]
+ }
+ }
+ }],
+ "expectedBidResponses": [{
+ "bids": [{
+ "bid": {
+ "id": "test-bid-id-1",
+ "impid": "test-impression-id-1",
+ "price": 1
+ },
+ "type": "native"
+ }]
+ }, {
+ "bids": [{
+ "bid": {
+ "id": "test-bid-id-2",
+ "impid": "test-impression-id-2",
+ "price": 2
+ },
+ "type": "native"
+ }]
+ }, {
+ "bids": [{
+ "bid": {
+ "id": "test-bid-id-3",
+ "impid": "test-impression-id-3",
+ "price": 3
+ },
+ "type": "native"
+ }]
+ }]
+}
diff --git a/adapters/applogy/applogytest/exemplary/simple-video.json b/adapters/applogy/applogytest/exemplary/simple-video.json
new file mode 100644
index 00000000000..30237cccd10
--- /dev/null
+++ b/adapters/applogy/applogytest/exemplary/simple-video.json
@@ -0,0 +1,182 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "imp": [{
+ "id": "test-impression-id-1",
+ "video": {
+ "w": 900,
+ "h": 250,
+ "mimes": [
+ "video/mp4"
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "token": "test-token-1"
+ }
+ }
+ }, {
+ "id": "test-impression-id-2",
+ "video": {
+ "w": 900,
+ "h": 250,
+ "mimes": [
+ "video/mp4"
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "token": "test-token-1"
+ }
+ }
+ }, {
+ "id": "test-impression-id-3",
+ "video": {
+ "w": 900,
+ "h": 250,
+ "mimes": [
+ "video/mp4"
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "token": "test-token-2"
+ }
+ }
+ }]
+ },
+ "httpCalls": [{
+ "expectedRequest": {
+ "uri": "http://example.com/prebid/test-token-1",
+ "body": {
+ "id": "test-request-id",
+ "imp": [{
+ "id": "test-impression-id-1",
+ "video": {
+ "w": 900,
+ "h": 250,
+ "mimes": [
+ "video/mp4"
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "token": "test-token-1"
+ }
+ }
+ }]
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "test-response-id",
+ "seatbid": [{
+ "bid": [{
+ "id": "test-bid-id-1",
+ "impid": "test-impression-id-1",
+ "price": 1
+ }]
+ }]
+ }
+ }
+ }, {
+ "expectedRequest": {
+ "uri": "http://example.com/prebid/test-token-1",
+ "body": {
+ "id": "test-request-id",
+ "imp": [{
+ "id": "test-impression-id-2",
+ "video": {
+ "w": 900,
+ "h": 250,
+ "mimes": [
+ "video/mp4"
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "token": "test-token-1"
+ }
+ }
+ }]
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "test-response-id-2",
+ "seatbid": [{
+ "bid": [{
+ "id": "test-bid-id-2",
+ "impid": "test-impression-id-2",
+ "price": 2
+ }]
+ }]
+ }
+ }
+ }, {
+ "expectedRequest": {
+ "uri": "http://example.com/prebid/test-token-2",
+ "body": {
+ "id": "test-request-id",
+ "imp": [{
+ "id": "test-impression-id-3",
+ "video": {
+ "w": 900,
+ "h": 250,
+ "mimes": [
+ "video/mp4"
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "token": "test-token-2"
+ }
+ }
+ }]
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "test-response-id-3",
+ "seatbid": [{
+ "bid": [{
+ "id": "test-bid-id-3",
+ "impid": "test-impression-id-3",
+ "price": 3
+ }]
+ }]
+ }
+ }
+ }],
+ "expectedBidResponses": [{
+ "bids": [{
+ "bid": {
+ "id": "test-bid-id-1",
+ "impid": "test-impression-id-1",
+ "price": 1
+ },
+ "type": "video"
+ }]
+ }, {
+ "bids": [{
+ "bid": {
+ "id": "test-bid-id-2",
+ "impid": "test-impression-id-2",
+ "price": 2
+ },
+ "type": "video"
+ }]
+ }, {
+ "bids": [{
+ "bid": {
+ "id": "test-bid-id-3",
+ "impid": "test-impression-id-3",
+ "price": 3
+ },
+ "type": "video"
+ }]
+ }]
+}
diff --git a/adapters/applogy/applogytest/supplemental/all-failed.json b/adapters/applogy/applogytest/supplemental/all-failed.json
new file mode 100644
index 00000000000..7f0244afcfb
--- /dev/null
+++ b/adapters/applogy/applogytest/supplemental/all-failed.json
@@ -0,0 +1,16 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "imp": [{
+ "id": "test-impression-id-1",
+ "banner": {
+ "w": 300,
+ "h": 250
+ }
+ }]
+ },
+ "expectedMakeRequestsErrors": [{
+ "value": "impression extensions required",
+ "comparison": "literal"
+ }]
+}
diff --git a/adapters/applogy/applogytest/supplemental/invalid-params.json b/adapters/applogy/applogytest/supplemental/invalid-params.json
new file mode 100644
index 00000000000..6b5d5e3224d
--- /dev/null
+++ b/adapters/applogy/applogytest/supplemental/invalid-params.json
@@ -0,0 +1,133 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "imp": [{
+ "id": "test-impression-id-1",
+ "banner": {}
+ }, {
+ "id": "test-impression-id-2",
+ "banner": {
+ "w": 300,
+ "h": 250
+ }
+ }, {
+ "id": "test-impression-id-3",
+ "banner": {
+ "w": 300,
+ "h": 250
+ },
+ "ext": {}
+ }, {
+ "id": "test-impression-id-4"
+ }, {
+ "id": "test-impression-id-5",
+ "banner": {
+ "w": 300,
+ "h": 250
+ },
+ "ext": {
+ "bidder": {
+ "token": "test-token-5"
+ }
+ }
+ }, {
+ "id": "test-impression-id-0",
+ "banner": {
+ "w": 300,
+ "h": 250
+ },
+ "ext": {
+ "bidder": "invalid bidder"
+ }
+ }, {
+ "id": "test-impression-id-0",
+ "banner": {
+ "w": 300,
+ "h": 250
+ },
+ "ext": {
+ "bidder": {}
+ }
+ }, {
+ "id": "test-impression-id-0",
+ "banner": {
+ "w": 300,
+ "h": 250
+ },
+ "ext": "invalid ext"
+ }]
+ },
+ "httpCalls": [{
+ "expectedRequest": {
+ "uri": "http://example.com/prebid/test-token-5",
+ "body": {
+ "id": "test-request-id",
+ "imp": [{
+ "id": "test-impression-id-5",
+ "banner": {
+ "h": 250,
+ "w": 300
+ },
+ "ext": {
+ "bidder": {
+ "token": "test-token-5"
+ }
+ }
+ }]
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "test-response-id",
+ "seatbid": [{
+ "bid": [{
+ "id": "test-bid-id-5",
+ "impid": "test-impression-id-5",
+ "price": 5
+ }, {
+ "id": "test-bid-id-6",
+ "impid": "test-impression-id-6",
+ "price": 6
+ }]
+ }]
+ }
+ }
+ }],
+ "expectedBidResponses": [{
+ "bids": [{
+ "bid": {
+ "id": "test-bid-id-5",
+ "impid": "test-impression-id-5",
+ "price": 5
+ },
+ "type": "banner"
+ }]
+ }],
+ "expectedMakeRequestsErrors": [{
+ "value": "banner size information missing",
+ "comparison": "literal"
+ }, {
+ "value": "impression extensions required",
+ "comparison": "literal"
+ }, {
+ "value": "bidder required",
+ "comparison": "literal"
+ }, {
+ "value": "Applogy only supports banner, video or native ads",
+ "comparison": "literal"
+ }, {
+ "value": "json: cannot unmarshal string into Go value of type openrtb_ext.ExtImpApplogy",
+ "comparison": "literal"
+ }, {
+ "value": "Applogy token required",
+ "comparison": "literal"
+ }, {
+ "value": "json: cannot unmarshal string into Go value of type adapters.ExtImpBidder",
+ "comparison": "literal"
+ }],
+ "expectedMakeBidsErrors": [{
+ "value": "ignoring bid id=test-bid-id-6, request doesn't contain any valid impression with id=test-impression-id-6",
+ "comparison": "literal"
+ }]
+}
diff --git a/adapters/applogy/applogytest/supplemental/status-204.json b/adapters/applogy/applogytest/supplemental/status-204.json
new file mode 100644
index 00000000000..c3516b184b5
--- /dev/null
+++ b/adapters/applogy/applogytest/supplemental/status-204.json
@@ -0,0 +1,41 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "imp": [{
+ "id": "test-impression-id-1",
+ "banner": {
+ "w": 300,
+ "h": 250
+ },
+ "ext": {
+ "bidder": {
+ "token": "test-token-1"
+ }
+ }
+ }]
+ },
+ "httpCalls": [{
+ "expectedRequest": {
+ "uri": "http://example.com/prebid/test-token-1",
+ "body": {
+ "id": "test-request-id",
+ "imp": [{
+ "id": "test-impression-id-1",
+ "banner": {
+ "h": 250,
+ "w": 300
+ },
+ "ext": {
+ "bidder": {
+ "token": "test-token-1"
+ }
+ }
+ }]
+ }
+ },
+ "mockResponse": {
+ "status": 204,
+ "body": {}
+ }
+ }]
+}
diff --git a/adapters/applogy/applogytest/supplemental/status-400.json b/adapters/applogy/applogytest/supplemental/status-400.json
new file mode 100644
index 00000000000..95e271bae8e
--- /dev/null
+++ b/adapters/applogy/applogytest/supplemental/status-400.json
@@ -0,0 +1,45 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "imp": [{
+ "id": "test-impression-id-1",
+ "banner": {
+ "w": 300,
+ "h": 250
+ },
+ "ext": {
+ "bidder": {
+ "token": "test-token-1"
+ }
+ }
+ }]
+ },
+ "httpCalls": [{
+ "expectedRequest": {
+ "uri": "http://example.com/prebid/test-token-1",
+ "body": {
+ "id": "test-request-id",
+ "imp": [{
+ "id": "test-impression-id-1",
+ "banner": {
+ "h": 250,
+ "w": 300
+ },
+ "ext": {
+ "bidder": {
+ "token": "test-token-1"
+ }
+ }
+ }]
+ }
+ },
+ "mockResponse": {
+ "status": 400,
+ "body": {}
+ }
+ }],
+ "expectedMakeBidsErrors": [{
+ "value": "unexpected status code: 400",
+ "comparison": "literal"
+ }]
+}
diff --git a/adapters/applogy/applogytest/supplemental/status-502.json b/adapters/applogy/applogytest/supplemental/status-502.json
new file mode 100644
index 00000000000..c0b1641653a
--- /dev/null
+++ b/adapters/applogy/applogytest/supplemental/status-502.json
@@ -0,0 +1,45 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "imp": [{
+ "id": "test-impression-id-1",
+ "banner": {
+ "w": 300,
+ "h": 250
+ },
+ "ext": {
+ "bidder": {
+ "token": "test-token-1"
+ }
+ }
+ }]
+ },
+ "httpCalls": [{
+ "expectedRequest": {
+ "uri": "http://example.com/prebid/test-token-1",
+ "body": {
+ "id": "test-request-id",
+ "imp": [{
+ "id": "test-impression-id-1",
+ "banner": {
+ "h": 250,
+ "w": 300
+ },
+ "ext": {
+ "bidder": {
+ "token": "test-token-1"
+ }
+ }
+ }]
+ }
+ },
+ "mockResponse": {
+ "status": 502,
+ "body": {}
+ }
+ }],
+ "expectedMakeBidsErrors": [{
+ "value": "unexpected status code: 502",
+ "comparison": "literal"
+ }]
+}
diff --git a/adapters/appnexus/appnexusplatformtest/exemplary/simple-auction.json b/adapters/appnexus/appnexusplatformtest/exemplary/simple-auction.json
index 8e4f52951b8..03c3f4c5880 100644
--- a/adapters/appnexus/appnexusplatformtest/exemplary/simple-auction.json
+++ b/adapters/appnexus/appnexusplatformtest/exemplary/simple-auction.json
@@ -14,7 +14,7 @@
},
"ext": {
"bidder": {
- "placement_id": 10433394
+ "placement_id": 1
}
}
}
@@ -46,7 +46,7 @@
},
"ext": {
"appnexus": {
- "placement_id": 10433394
+ "placement_id": 1
}
}
}
diff --git a/adapters/appnexus/appnexusplatformtest/video/simple-video.json b/adapters/appnexus/appnexusplatformtest/video/simple-video.json
index 3c28b48a083..85960427d81 100644
--- a/adapters/appnexus/appnexusplatformtest/video/simple-video.json
+++ b/adapters/appnexus/appnexusplatformtest/video/simple-video.json
@@ -14,7 +14,7 @@
},
"ext": {
"bidder": {
- "placement_id": 10433394
+ "placement_id": 1
}
}
}
@@ -46,7 +46,7 @@
},
"ext": {
"appnexus": {
- "placement_id": 10433394
+ "placement_id": 1
}
}
}
diff --git a/adapters/appnexus/appnexustest/amp/simple-banner.json b/adapters/appnexus/appnexustest/amp/simple-banner.json
index b5ea656c822..646359b4267 100644
--- a/adapters/appnexus/appnexustest/amp/simple-banner.json
+++ b/adapters/appnexus/appnexustest/amp/simple-banner.json
@@ -18,7 +18,7 @@
},
"ext": {
"bidder": {
- "placement_id": 10433394
+ "placement_id": 1
}
}
}
@@ -58,7 +58,7 @@
},
"ext": {
"appnexus": {
- "placement_id": 10433394
+ "placement_id": 1
}
}
}
diff --git a/adapters/appnexus/appnexustest/amp/simple-video.json b/adapters/appnexus/appnexustest/amp/simple-video.json
index f44ed06605c..a6f96be34b8 100644
--- a/adapters/appnexus/appnexustest/amp/simple-video.json
+++ b/adapters/appnexus/appnexustest/amp/simple-video.json
@@ -14,7 +14,7 @@
},
"ext": {
"bidder": {
- "placement_id": 10433394
+ "placement_id": 1
}
}
}
@@ -48,7 +48,7 @@
},
"ext": {
"appnexus": {
- "placement_id": 10433394
+ "placement_id": 1
}
}
}
diff --git a/adapters/appnexus/appnexustest/exemplary/simple-banner.json b/adapters/appnexus/appnexustest/exemplary/simple-banner.json
index 976f35b208a..e5bd311648f 100644
--- a/adapters/appnexus/appnexustest/exemplary/simple-banner.json
+++ b/adapters/appnexus/appnexustest/exemplary/simple-banner.json
@@ -18,7 +18,7 @@
},
"ext": {
"bidder": {
- "placement_id": 10433394
+ "placement_id": 1
}
}
}
@@ -56,7 +56,7 @@
},
"ext": {
"appnexus": {
- "placement_id": 10433394
+ "placement_id": 1
}
}
}
diff --git a/adapters/appnexus/appnexustest/exemplary/simple-video.json b/adapters/appnexus/appnexustest/exemplary/simple-video.json
index 5afef01fa64..15755c7de37 100644
--- a/adapters/appnexus/appnexustest/exemplary/simple-video.json
+++ b/adapters/appnexus/appnexustest/exemplary/simple-video.json
@@ -14,7 +14,7 @@
},
"ext": {
"bidder": {
- "placement_id": 10433394
+ "placement_id": 1
}
}
}
@@ -46,7 +46,7 @@
},
"ext": {
"appnexus": {
- "placement_id": 10433394
+ "placement_id": 1
}
}
}
diff --git a/adapters/appnexus/appnexustest/exemplary/video-invalid-category.json b/adapters/appnexus/appnexustest/exemplary/video-invalid-category.json
index 283f13cf111..d3686af00a9 100644
--- a/adapters/appnexus/appnexustest/exemplary/video-invalid-category.json
+++ b/adapters/appnexus/appnexustest/exemplary/video-invalid-category.json
@@ -14,7 +14,7 @@
},
"ext": {
"bidder": {
- "placement_id": 10433394
+ "placement_id": 1
}
}
}
@@ -46,7 +46,7 @@
},
"ext": {
"appnexus": {
- "placement_id": 10433394
+ "placement_id": 1
}
}
}
diff --git a/adapters/appnexus/appnexustest/params/race/banner.json b/adapters/appnexus/appnexustest/params/race/banner.json
index 2e2b39e9429..a37e0036357 100644
--- a/adapters/appnexus/appnexustest/params/race/banner.json
+++ b/adapters/appnexus/appnexustest/params/race/banner.json
@@ -1,5 +1,5 @@
{
- "placement_id": 10433394,
+ "placement_id": 1,
"reserve": 20,
"position": "below",
"traffic_source_code": "trafficSource",
diff --git a/adapters/appnexus/appnexustest/params/race/video.json b/adapters/appnexus/appnexustest/params/race/video.json
index 2e2b39e9429..a37e0036357 100644
--- a/adapters/appnexus/appnexustest/params/race/video.json
+++ b/adapters/appnexus/appnexustest/params/race/video.json
@@ -1,5 +1,5 @@
{
- "placement_id": 10433394,
+ "placement_id": 1,
"reserve": 20,
"position": "below",
"traffic_source_code": "trafficSource",
diff --git a/adapters/appnexus/appnexustest/supplemental/displaymanager-test.json b/adapters/appnexus/appnexustest/supplemental/displaymanager-test.json
index a1602ff9a74..d5c981c6945 100644
--- a/adapters/appnexus/appnexustest/supplemental/displaymanager-test.json
+++ b/adapters/appnexus/appnexustest/supplemental/displaymanager-test.json
@@ -26,7 +26,7 @@
},
"ext": {
"bidder": {
- "placement_id": 10433394
+ "placement_id": 1
}
}
}
@@ -73,7 +73,7 @@
"displaymanagerver": "prebid-mobile-1.0.0",
"ext": {
"appnexus": {
- "placement_id": 10433394
+ "placement_id": 1
}
}
}
diff --git a/adapters/appnexus/appnexustest/supplemental/explicit-dimensions.json b/adapters/appnexus/appnexustest/supplemental/explicit-dimensions.json
index 11b5d887187..06e7724a23b 100644
--- a/adapters/appnexus/appnexustest/supplemental/explicit-dimensions.json
+++ b/adapters/appnexus/appnexustest/supplemental/explicit-dimensions.json
@@ -16,7 +16,7 @@
},
"ext": {
"bidder": {
- "placementId": 10433394
+ "placementId": 1
}
}
}
@@ -49,7 +49,7 @@
},
"ext": {
"appnexus": {
- "placement_id": 10433394
+ "placement_id": 1
}
}
}
diff --git a/adapters/appnexus/appnexustest/supplemental/multi-bid.json b/adapters/appnexus/appnexustest/supplemental/multi-bid.json
index 1e3089b1e71..7234551ea3f 100644
--- a/adapters/appnexus/appnexustest/supplemental/multi-bid.json
+++ b/adapters/appnexus/appnexustest/supplemental/multi-bid.json
@@ -18,7 +18,7 @@
},
"ext": {
"bidder": {
- "placement_id": 10433394
+ "placement_id": 1
}
}
}
@@ -56,7 +56,7 @@
},
"ext": {
"appnexus": {
- "placement_id": 10433394
+ "placement_id": 1
}
}
}
diff --git a/adapters/audienceNetwork/audienceNetworktest/supplemental/banner-format-only.json b/adapters/audienceNetwork/audienceNetworktest/supplemental/banner-format-only.json
new file mode 100644
index 00000000000..52b7655593a
--- /dev/null
+++ b/adapters/audienceNetwork/audienceNetworktest/supplemental/banner-format-only.json
@@ -0,0 +1,140 @@
+{
+ "mockBidRequest": {
+ "id": "test-req-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "format": [
+ {
+ "w": 640,
+ "h": 480
+ },
+ {
+ "w": 300,
+ "h": 250
+ }
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "publisherid": "123",
+ "placementid": "456"
+ }
+ }
+ }
+ ],
+ "site": {
+ "domain": "prebid.org",
+ "page": "prebid.org"
+ },
+ "device": {
+ "ip": "152.193.6.74"
+ },
+ "user": {
+ "id": "db089de9-a62e-4861-a881-0ff15e052516",
+ "buyeruid": "v4_bidder_token"
+ },
+ "tmax": 500
+ },
+ "httpcalls": [
+ {
+ "expectedRequest": {
+ "uri": "https://an.facebook.com/placementbid.ortb",
+ "headers": {
+ "Accept": [
+ "application/json"
+ ],
+ "Content-Type": [
+ "application/json;charset=utf-8"
+ ],
+ "X-Fb-Pool-Routing-Token": [
+ "v4_bidder_token"
+ ]
+ },
+ "body": {
+ "id": "test-req-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "w": -1,
+ "h": 250
+ },
+ "tagid": "123_456"
+ }
+ ],
+ "ext": {
+ "appnexus": {
+ "hb_source": 5
+ },
+ "prebid": {}
+ },
+ "site": {
+ "domain": "prebid.org",
+ "page": "prebid.org",
+ "publisher": {
+ "id": "123"
+ }
+ },
+ "device": {
+ "ip": "152.193.6.74"
+ },
+ "user": {
+ "id": "db089de9-a62e-4861-a881-0ff15e052516",
+ "buyeruid": "v4_bidder_token"
+ },
+ "tmax": 500,
+ "ext": {
+ "authentication_id": "b2f9edfd707106adb6b692520081ad7e2a345444af1a895310228297a1b6247e",
+ "platformid": "test-platform-id"
+ }
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "test-req-id",
+ "seatbid": [
+ {
+ "bid": [
+ {
+ "id": "987",
+ "impid": "test-imp-id",
+ "price": 1.000000,
+ "adm": "{\"type\":\"ID\",\"bid_id\":\"987\",\"placement_id\":\"123_456\",\"resolved_placement_id\":\"123_456\",\"sdk_version\":\"5.5.0\",\"device_id\":\"abc\",\"template\":1,\"payload\":null,\"bid_time_token\":\"v4_bidder_token=\"}",
+ "nurl": "https://www.facebook.com/audiencenetwork/nurl/?partner=test-platform-id&app=def&placement=456&auction=123&impression=123&request=123478&bid=987&ortb_loss_code=0&clearing_price=${AUCTION_PRICE}&app_version=iOS-1.0",
+ "lurl": "https://www.facebook.com/audiencenetwork/nurl/?partner=test-platform-id&app=def&placement=456&auction=123&impression=123&request=123478&bid=987&ortb_loss_code=${AUCTION_LOSS}&clearing_price=${AUCTION_PRICE}&app_version=iOS-1.0",
+ "burl": "https://www.facebook.com/audiencenetwork/burl/?partner=test-platform-id&app=def&placement=456&auction=123&impression=123&request=123478&bid=987&clearing_price=${AUCTION_PRICE}"
+ }
+ ]
+ }
+ ],
+ "bidid": "654",
+ "cur": "USD"
+ }
+ }
+ }
+ ],
+ "expectedBidResponses": [
+ {
+ "currency": "USD",
+ "bids": [
+ {
+ "bid": {
+ "id": "987",
+ "impid": "test-imp-id",
+ "price": 1,
+ "adm": "{\"type\":\"ID\",\"bid_id\":\"987\",\"placement_id\":\"123_456\",\"resolved_placement_id\":\"123_456\",\"sdk_version\":\"5.5.0\",\"device_id\":\"abc\",\"template\":1,\"payload\":null,\"bid_time_token\":\"v4_bidder_token=\"}",
+ "adid": "987",
+ "crid": "987",
+ "nurl": "https://www.facebook.com/audiencenetwork/nurl/?partner=test-platform-id&app=def&placement=456&auction=123&impression=123&request=123478&bid=987&ortb_loss_code=0&clearing_price=${AUCTION_PRICE}&app_version=iOS-1.0",
+ "lurl": "https://www.facebook.com/audiencenetwork/nurl/?partner=test-platform-id&app=def&placement=456&auction=123&impression=123&request=123478&bid=987&ortb_loss_code=${AUCTION_LOSS}&clearing_price=${AUCTION_PRICE}&app_version=iOS-1.0",
+ "burl": "https://www.facebook.com/audiencenetwork/burl/?partner=test-platform-id&app=def&placement=456&auction=123&impression=123&request=123478&bid=987&clearing_price=${AUCTION_PRICE}"
+ },
+ "type": "banner"
+ }
+ ]
+ }
+ ]
+}
diff --git a/adapters/audienceNetwork/facebook.go b/adapters/audienceNetwork/facebook.go
index 1500f314f88..3ece7bb99e4 100644
--- a/adapters/audienceNetwork/facebook.go
+++ b/adapters/audienceNetwork/facebook.go
@@ -184,8 +184,17 @@ func (this *FacebookAdapter) modifyImp(out *openrtb.Imp) error {
}
if out.Banner.H == nil {
- return &errortypes.BadInput{
- Message: fmt.Sprintf("imp #%s: banner height required", out.ID),
+ for _, f := range out.Banner.Format {
+ if _, ok := supportedBannerHeights[f.H]; ok {
+ h := f.H
+ out.Banner.H = &h
+ break
+ }
+ }
+ if out.Banner.H == nil {
+ return &errortypes.BadInput{
+ Message: fmt.Sprintf("imp #%s: banner height required", out.ID),
+ }
}
}
@@ -438,3 +447,20 @@ func NewFacebookBidder(client *http.Client, platformID string, appSecret string)
appSecret: appSecret,
}
}
+
+func (fa *FacebookAdapter) MakeTimeoutNotification(req *adapters.RequestData) (*adapters.RequestData, []error) {
+ // Note, facebook creates one request per imp, so all these requests will only have one imp in them
+ auction_id, err := jsonparser.GetString(req.Body, "imp", "[0]", "id")
+ if err != nil {
+ return &adapters.RequestData{}, []error{err}
+ }
+
+ uri := fmt.Sprintf("https://www.facebook.com/audiencenetwork/nurl/?partner=%s&app=%s&auction=%s&ortb_loss_code=2", fa.platformID, fa.platformID, auction_id)
+ timeoutReq := adapters.RequestData{
+ Method: "GET",
+ Uri: uri,
+ Body: nil,
+ Headers: http.Header{},
+ }
+ return &timeoutReq, nil
+}
diff --git a/adapters/audienceNetwork/facebook_test.go b/adapters/audienceNetwork/facebook_test.go
index 2ce0ef3ba64..1edaabd45d7 100644
--- a/adapters/audienceNetwork/facebook_test.go
+++ b/adapters/audienceNetwork/facebook_test.go
@@ -4,7 +4,9 @@ import (
"testing"
"time"
+ "github.com/prebid/prebid-server/adapters"
"github.com/prebid/prebid-server/adapters/adapterstest"
+ "github.com/stretchr/testify/assert"
)
type tagInfo struct {
@@ -40,3 +42,38 @@ type FacebookExt struct {
func TestJsonSamples(t *testing.T) {
adapterstest.RunJSONBidderTest(t, "audienceNetworktest", NewFacebookBidder(nil, "test-platform-id", "test-app-secret"))
}
+
+func TestMakeTimeoutNotice(t *testing.T) {
+ req := adapters.RequestData{
+ Body: []byte(`{"imp":[{"id":"1234"}]}}`),
+ }
+ fba := NewFacebookBidder(nil, "test-platform-id", "test-app-secret")
+
+ tb, ok := fba.(adapters.TimeoutBidder)
+ if !ok {
+ t.Error("Facebook adapter is not a TimeoutAdapter")
+ }
+
+ toReq, err := tb.MakeTimeoutNotification(&req)
+ assert.Nil(t, err, "Facebook MakeTimeoutNotification() return an error %v", err)
+ expectedUri := "https://www.facebook.com/audiencenetwork/nurl/?partner=test-platform-id&app=test-platform-id&auction=1234&ortb_loss_code=2"
+ assert.Equal(t, expectedUri, toReq.Uri, "Facebook timeout notification not returning the expected URI.")
+
+}
+
+func TestMakeTimeoutNoticeBadRequest(t *testing.T) {
+ req := adapters.RequestData{
+ Body: []byte(`{"imp":[{{"id":"1234"}}`),
+ }
+ fba := NewFacebookBidder(nil, "test-platform-id", "test-app-secret")
+
+ tb, ok := fba.(adapters.TimeoutBidder)
+ if !ok {
+ t.Error("Facebook adapter is not a TimeoutAdapter")
+ }
+
+ toReq, err := tb.MakeTimeoutNotification(&req)
+ assert.Empty(t, toReq.Uri, "Facebook MakeTimeoutNotification() did not return nil", err)
+ assert.NotNil(t, err, "Facebook MakeTimeoutNotification() did not return an error")
+
+}
diff --git a/adapters/beachfront/usersync_test.go b/adapters/beachfront/usersync_test.go
index 0b71e0f92f8..f0c4b3817d1 100644
--- a/adapters/beachfront/usersync_test.go
+++ b/adapters/beachfront/usersync_test.go
@@ -5,20 +5,30 @@ import (
"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 TestBeachfrontSyncer(t *testing.T) {
- syncURL := "localhost"
+ syncURL := "https://sync.bfmio.com/sync_s2s?gdpr={{.GDPR}}&us_privacy={{.USPrivacy}}&url=https%3A%2F%2Flocalhost%3A8888%2Fsetuid%3Fbidder%3Dbeachfront%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%5Bio_cid%5D"
syncURLTemplate := template.Must(
template.New("sync-template").Parse(syncURL),
)
syncer := NewBeachfrontSyncer(syncURLTemplate)
- syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{})
+ syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{
+ GDPR: gdpr.Policy{
+ Signal: "A",
+ Consent: "B",
+ },
+ CCPA: ccpa.Policy{
+ Value: "C",
+ },
+ })
assert.NoError(t, err)
- assert.Equal(t, "localhost", syncInfo.URL)
+ assert.Equal(t, "https://sync.bfmio.com/sync_s2s?gdpr=A&us_privacy=C&url=https%3A%2F%2Flocalhost%3A8888%2Fsetuid%3Fbidder%3Dbeachfront%26gdpr%3DA%26gdpr_consent%3DB%26uid%3D%5Bio_cid%5D", syncInfo.URL)
assert.Equal(t, "iframe", syncInfo.Type)
assert.EqualValues(t, 0, syncer.GDPRVendorID())
assert.Equal(t, false, syncInfo.SupportCORS)
diff --git a/adapters/bidder.go b/adapters/bidder.go
index 9d3ffb75414..baec4135b6a 100644
--- a/adapters/bidder.go
+++ b/adapters/bidder.go
@@ -39,6 +39,19 @@ type Bidder interface {
MakeBids(internalRequest *openrtb.BidRequest, externalRequest *RequestData, response *ResponseData) (*BidderResponse, []error)
}
+// TimeoutBidder is used to identify bidders that support timeout notifications.
+type TimeoutBidder interface {
+ Bidder
+
+ // MakeTimeoutNotice functions much the same as MakeRequests, except it is fed the bidder request that timed out,
+ // and expects that only one notification "request" will be generated. A use case for multiple timeout notifications
+ // has not been anticipated.
+ //
+ // Do note that if MakeRequests returns multiple requests, and more than one of these times out, MakeTimeoutNotice will be called
+ // once for each timed out request.
+ MakeTimeoutNotification(req *RequestData) (*RequestData, []error)
+}
+
type MisconfiguredBidder struct {
Name string
Error error
diff --git a/adapters/brightroll/usersync_test.go b/adapters/brightroll/usersync_test.go
index 08104c048ac..a5d47e35e56 100644
--- a/adapters/brightroll/usersync_test.go
+++ b/adapters/brightroll/usersync_test.go
@@ -9,7 +9,7 @@ import (
)
func TestBrightrollSyncer(t *testing.T) {
- syncURL := "http://test-bh.ybp.yahoo.com/sync/appnexuspbs?gdpr={{.GDPR}}&euconsent={{.GDPRConsent}}&url=localhost%2Fsetuid%3Fbidder%3Dbrightroll%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24%7BUID%7D"
+ syncURL := "http://test-bh.ybp.yahoo.com/sync/appnexuspbs?gdpr={{.GDPR}}&euconsent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&url=localhost%2Fsetuid%3Fbidder%3Dbrightroll%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24%7BUID%7D"
syncURLTemplate := template.Must(
template.New("sync-template").Parse(syncURL),
)
@@ -18,7 +18,7 @@ func TestBrightrollSyncer(t *testing.T) {
syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{})
assert.NoError(t, err)
- assert.Equal(t, "http://test-bh.ybp.yahoo.com/sync/appnexuspbs?gdpr=&euconsent=&url=localhost%2Fsetuid%3Fbidder%3Dbrightroll%26gdpr%3D%26gdpr_consent%3D%26uid%3D%24%7BUID%7D", syncInfo.URL)
+ assert.Equal(t, "http://test-bh.ybp.yahoo.com/sync/appnexuspbs?gdpr=&euconsent=&us_privacy=&url=localhost%2Fsetuid%3Fbidder%3Dbrightroll%26gdpr%3D%26gdpr_consent%3D%26uid%3D%24%7BUID%7D", syncInfo.URL)
assert.Equal(t, "redirect", syncInfo.Type)
assert.EqualValues(t, 25, syncer.GDPRVendorID())
assert.Equal(t, false, syncInfo.SupportCORS)
diff --git a/adapters/consumable/usersync_test.go b/adapters/consumable/usersync_test.go
index 7def6be0a48..eb97edf2cae 100644
--- a/adapters/consumable/usersync_test.go
+++ b/adapters/consumable/usersync_test.go
@@ -5,12 +5,13 @@ import (
"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 TestConsumableSyncer(t *testing.T) {
- syncURL := "//e.serverbid.com/udb/9969/match?redir=http%3A%2F%2Flocalhost%3A8000%2Fsetuid%3Fbidder%3Dconsumable%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D"
+ syncURL := "//e.serverbid.com/udb/9969/match?gdpr={{.GDPR}}&euconsent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redir=http%3A%2F%2Flocalhost%3A8000%2Fsetuid%3Fbidder%3Dconsumable%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D"
syncURLTemplate := template.Must(
template.New("sync-template").Parse(syncURL),
)
@@ -18,12 +19,16 @@ func TestConsumableSyncer(t *testing.T) {
syncer := NewConsumableSyncer(syncURLTemplate)
u, err := syncer.GetUsersyncInfo(privacy.Policies{
GDPR: gdpr.Policy{
- Signal: "0",
+ Signal: "A",
+ Consent: "B",
+ },
+ CCPA: ccpa.Policy{
+ Value: "C",
},
})
assert.NoError(t, err)
- assert.Equal(t, "//e.serverbid.com/udb/9969/match?redir=http%3A%2F%2Flocalhost%3A8000%2Fsetuid%3Fbidder%3Dconsumable%26gdpr%3D0%26gdpr_consent%3D%26uid%3D", u.URL)
+ assert.Equal(t, "//e.serverbid.com/udb/9969/match?gdpr=A&euconsent=B&us_privacy=C&redir=http%3A%2F%2Flocalhost%3A8000%2Fsetuid%3Fbidder%3Dconsumable%26gdpr%3DA%26gdpr_consent%3DB%26uid%3D", u.URL)
assert.Equal(t, "redirect", u.Type)
assert.Equal(t, uint16(65535), syncer.GDPRVendorID())
assert.Equal(t, false, u.SupportCORS)
diff --git a/adapters/cpmstar/cpmstar.go b/adapters/cpmstar/cpmstar.go
new file mode 100644
index 00000000000..ef6abe70cb7
--- /dev/null
+++ b/adapters/cpmstar/cpmstar.go
@@ -0,0 +1,161 @@
+package cpmstar
+
+import (
+ "encoding/json"
+ "fmt"
+ "net/http"
+
+ "github.com/mxmCherry/openrtb"
+ "github.com/prebid/prebid-server/adapters"
+ "github.com/prebid/prebid-server/errortypes"
+ "github.com/prebid/prebid-server/openrtb_ext"
+)
+
+type Adapter struct {
+ endpoint string
+}
+
+func (a *Adapter) MakeRequests(request *openrtb.BidRequest, unused *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
+ var errs []error
+ var adapterRequests []*adapters.RequestData
+
+ if err := preprocess(request); err != nil {
+ errs = append(errs, err)
+ return nil, errs
+ }
+
+ adapterReq, err := a.makeRequest(request)
+ if err != nil {
+ errs = append(errs, err)
+ return nil, errs
+ }
+
+ adapterRequests = append(adapterRequests, adapterReq)
+
+ return adapterRequests, errs
+}
+
+func (a *Adapter) makeRequest(request *openrtb.BidRequest) (*adapters.RequestData, error) {
+ var err error
+
+ jsonBody, err := json.Marshal(request)
+ if err != nil {
+ return nil, err
+ }
+
+ headers := http.Header{}
+ headers.Add("Content-Type", "application/json;charset=utf-8")
+
+ return &adapters.RequestData{
+ Method: "POST",
+ Uri: a.endpoint,
+ Body: jsonBody,
+ Headers: headers,
+ }, nil
+}
+
+func preprocess(request *openrtb.BidRequest) error {
+ if len(request.Imp) == 0 {
+ return &errortypes.BadInput{
+ Message: "No Imps in Bid Request",
+ }
+ }
+ for i := 0; i < len(request.Imp); i++ {
+ var imp = &request.Imp[i]
+ var bidderExt adapters.ExtImpBidder
+
+ if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil {
+ return &errortypes.BadInput{
+ Message: err.Error(),
+ }
+ }
+
+ if err := validateImp(imp); err != nil {
+ return err
+ }
+
+ var extImp openrtb_ext.ExtImpCpmstar
+ if err := json.Unmarshal(bidderExt.Bidder, &extImp); err != nil {
+ return &errortypes.BadInput{
+ Message: err.Error(),
+ }
+ }
+
+ imp.Ext = bidderExt.Bidder
+ }
+
+ return nil
+}
+
+func validateImp(imp *openrtb.Imp) error {
+ if imp.Banner == nil && imp.Video == nil {
+ return &errortypes.BadInput{
+ Message: "Only Banner and Video bid-types are supported at this time",
+ }
+ }
+ return nil
+}
+
+// MakeBids based on cpmstar server response
+func (a *Adapter) MakeBids(bidRequest *openrtb.BidRequest, unused *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) {
+ if responseData.StatusCode == http.StatusNoContent {
+ return nil, nil
+ }
+
+ if responseData.StatusCode != http.StatusOK {
+ return nil, []error{&errortypes.BadServerResponse{
+ Message: fmt.Sprintf("Unexpected HTTP status code: %d. Run with request.debug = 1 for more info", responseData.StatusCode),
+ }}
+ }
+
+ var bidResponse openrtb.BidResponse
+
+ if err := json.Unmarshal(responseData.Body, &bidResponse); err != nil {
+ return nil, []error{&errortypes.BadServerResponse{
+ Message: err.Error(),
+ }}
+ }
+
+ if len(bidResponse.SeatBid) == 0 {
+ return nil, nil
+ }
+
+ rv := adapters.NewBidderResponseWithBidsCapacity(len(bidResponse.SeatBid[0].Bid))
+ var errors []error
+
+ for _, seatbid := range bidResponse.SeatBid {
+ for _, bid := range seatbid.Bid {
+ foundMatchingBid := false
+ bidType := openrtb_ext.BidTypeBanner
+ for _, imp := range bidRequest.Imp {
+ if imp.ID == bid.ImpID {
+ foundMatchingBid = true
+ if imp.Banner != nil {
+ bidType = openrtb_ext.BidTypeBanner
+ } else if imp.Video != nil {
+ bidType = openrtb_ext.BidTypeVideo
+ }
+ break
+ }
+ }
+
+ if foundMatchingBid {
+ rv.Bids = append(rv.Bids, &adapters.TypedBid{
+ Bid: &bid,
+ BidType: bidType,
+ })
+ } else {
+ errors = append(errors, &errortypes.BadServerResponse{
+ Message: fmt.Sprintf("bid id='%s' could not find valid impid='%s'", bid.ID, bid.ImpID),
+ })
+ }
+ }
+ }
+ return rv, errors
+}
+
+func NewCpmstarBidder(endpoint string) *Adapter {
+ return &Adapter{
+ endpoint: endpoint,
+ }
+}
diff --git a/adapters/cpmstar/cpmstar_test.go b/adapters/cpmstar/cpmstar_test.go
new file mode 100644
index 00000000000..0a7f43f5ee7
--- /dev/null
+++ b/adapters/cpmstar/cpmstar_test.go
@@ -0,0 +1,11 @@
+package cpmstar
+
+import (
+ "testing"
+
+ "github.com/prebid/prebid-server/adapters/adapterstest"
+)
+
+func TestJsonSamples(t *testing.T) {
+ adapterstest.RunJSONBidderTest(t, "cpmstartest", NewCpmstarBidder("//host"))
+}
diff --git a/adapters/cpmstar/cpmstartest/exemplary/banner-and-video.json b/adapters/cpmstar/cpmstartest/exemplary/banner-and-video.json
new file mode 100644
index 00000000000..d4dcb4b8677
--- /dev/null
+++ b/adapters/cpmstar/cpmstartest/exemplary/banner-and-video.json
@@ -0,0 +1,154 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-banner-imp-id",
+ "banner": {
+ "format": [
+ {
+ "w": 300,
+ "h": 250
+ }
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "placementId": 154,
+ "subpoolId": 123
+ }
+ }
+ },
+ {
+ "id": "test-video-imp-id",
+ "video": {
+ "mimes": [
+ "video/mp4"
+ ],
+ "protocols": [
+ 2,
+ 5
+ ],
+ "w": 640,
+ "h": 480
+ },
+ "ext": {
+ "bidder": {
+ "placementId": 154,
+ "subpoolId": 654
+ }
+ }
+ }
+ ],
+ "site": {
+ "id": "fake-site-id"
+ }
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "//host",
+ "body": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-banner-imp-id",
+ "banner": {
+ "format": [
+ {
+ "h": 250,
+ "w": 300
+ }
+ ]
+ },
+ "ext": {
+ "placementId": 154,
+ "subpoolId": 123
+ }
+ },
+ {
+ "id": "test-video-imp-id",
+ "video": {
+ "h": 480,
+ "mimes": [
+ "video/mp4"
+ ],
+ "protocols": [
+ 2,
+ 5
+ ],
+ "w": 640
+ },
+ "ext": {
+ "placementId": 154,
+ "subpoolId": 654
+ }
+ }
+ ],
+ "site": {
+ "id": "fake-site-id"
+ }
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "test-request-id",
+ "seatbid": [
+ {
+ "seat": "cpmstar",
+ "bid": [
+ {
+ "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800",
+ "impid": "test-video-imp-id",
+ "price": 0.5,
+ "adm": "some-test-ad",
+ "crid": "crid_10",
+ "h": 250,
+ "w": 300
+ }
+ ]
+ }
+ ],
+ "cur": "USD"
+ }
+ }
+ }
+ ],
+ "expectedBids": [
+ {
+ "bid": {
+ "id": "7706636740145184841",
+ "impid": "test-imp-id",
+ "price": 0.5,
+ "adm": "some-test-ad",
+ "adid": "29681110",
+ "adomain": [
+ "sample.com"
+ ],
+ "cid": "958",
+ "crid": "29681110",
+ "w": 1024,
+ "h": 576
+ },
+ "type": "banner"
+ },
+ {
+ "bid": {
+ "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800",
+ "impid": "test-imp-video-id",
+ "price": 0.5,
+ "adm": "some-test-ad",
+ "adid": "29484110",
+ "adomain": [
+ "sample.com"
+ ],
+ "cid": "958",
+ "crid": "29484110",
+ "w": 1024,
+ "h": 576
+ },
+ "type": "video"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/adapters/cpmstar/cpmstartest/exemplary/banner.json b/adapters/cpmstar/cpmstartest/exemplary/banner.json
new file mode 100644
index 00000000000..0bbe3060a63
--- /dev/null
+++ b/adapters/cpmstar/cpmstartest/exemplary/banner.json
@@ -0,0 +1,100 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-banner-imp-id",
+ "banner": {
+ "format": [
+ {
+ "w": 300,
+ "h": 250
+ }
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "placementId": 154,
+ "subpoolId": 123
+ }
+ }
+ }
+ ],
+ "site": {
+ "id": "fake-site-id"
+ }
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "//host",
+ "body": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-banner-imp-id",
+ "banner": {
+ "format": [
+ {
+ "w": 300,
+ "h": 250
+ }
+ ]
+ },
+ "ext": {
+ "placementId": 154,
+ "subpoolId": 123
+ }
+ }
+ ],
+ "site": {
+ "id": "fake-site-id"
+ }
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "test-request-id",
+ "seatbid": [
+ {
+ "seat": "cpmstar",
+ "bid": [
+ {
+ "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800",
+ "impid": "test-banner-imp-id",
+ "price": 0.500000,
+ "adm": "some-test-ad",
+ "crid": "crid_10",
+ "h": 250,
+ "w": 300
+ }
+ ]
+ }
+ ],
+ "cur": "USD"
+ }
+ }
+ }
+ ],
+ "expectedBidResponses": [
+ {
+ "currency": "USD",
+ "bids": [
+ {
+ "bid": {
+ "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800",
+ "impid": "test-banner-imp-id",
+ "price": 0.5,
+ "adm": "some-test-ad",
+ "crid": "crid_10",
+ "w": 300,
+ "h": 250
+ },
+ "type": "banner"
+ }
+ ]
+ }
+ ]
+}
+
\ No newline at end of file
diff --git a/adapters/cpmstar/cpmstartest/exemplary/video.json b/adapters/cpmstar/cpmstartest/exemplary/video.json
new file mode 100644
index 00000000000..a0213cbdac1
--- /dev/null
+++ b/adapters/cpmstar/cpmstartest/exemplary/video.json
@@ -0,0 +1,55 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-video-imp-id",
+ "video": {
+ "w": 900,
+ "h": 250,
+ "mimes": [
+ "video/x-flv",
+ "video/mp4"
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "placementId": 154,
+ "subpoolId": 123
+ }
+ }
+ }
+ ]
+ },
+
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "//host",
+ "body": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id":"test-video-imp-id",
+ "video": {
+ "w": 900,
+ "h": 250,
+ "mimes": [
+ "video/x-flv",
+ "video/mp4"
+ ]
+ },
+ "ext": {
+ "placementId": 154,
+ "subpoolId": 123
+ }
+ }
+ ]
+ }
+ },
+ "mockResponse": {
+ "status": 204
+ }
+ }
+ ]
+}
diff --git a/adapters/cpmstar/cpmstartest/supplemental/audio.json b/adapters/cpmstar/cpmstartest/supplemental/audio.json
new file mode 100644
index 00000000000..18ff171c7f5
--- /dev/null
+++ b/adapters/cpmstar/cpmstartest/supplemental/audio.json
@@ -0,0 +1,25 @@
+{
+ "mockBidRequest": {
+ "id": "unsupported-audio-request",
+ "imp": [
+ {
+ "id": "unsupported-audio-imp",
+ "audio": {
+ "mimes": ["video/mp4"]
+ },
+ "ext": {
+ "bidder": {
+ "placementId": 154
+ }
+ }
+ }
+ ]
+ },
+
+ "expectedMakeRequestsErrors": [
+ {
+ "value": "Only Banner and Video bid-types are supported at this time",
+ "comparison": "literal"
+ }
+ ]
+}
diff --git a/adapters/cpmstar/cpmstartest/supplemental/explicit-dimensions.json b/adapters/cpmstar/cpmstartest/supplemental/explicit-dimensions.json
new file mode 100644
index 00000000000..b8aad87514d
--- /dev/null
+++ b/adapters/cpmstar/cpmstartest/supplemental/explicit-dimensions.json
@@ -0,0 +1,58 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "format": [
+ {
+ "w": 300,
+ "h": 250
+ }
+ ],
+ "w": 100,
+ "h": 400
+ },
+ "ext": {
+ "bidder": {
+ "placementId": 154,
+ "subpoolId": 123
+ }
+ }
+ }
+ ]
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "//host",
+ "body": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "format": [
+ {
+ "w": 300,
+ "h": 250
+ }
+ ],
+ "w": 100,
+ "h": 400
+ },
+ "ext": {
+ "placementId": 154,
+ "subpoolId": 123
+ }
+ }
+ ]
+ }
+ },
+ "mockResponse": {
+ "status": 204
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/adapters/cpmstar/cpmstartest/supplemental/invalid-response-no-bids.json b/adapters/cpmstar/cpmstartest/supplemental/invalid-response-no-bids.json
new file mode 100644
index 00000000000..a3cb9114caa
--- /dev/null
+++ b/adapters/cpmstar/cpmstartest/supplemental/invalid-response-no-bids.json
@@ -0,0 +1,50 @@
+{
+ "mockBidRequest": {
+ "id": "some_test_auction",
+ "imp": [
+ {
+ "id": "some_test_ad",
+ "banner": {
+ "w": 90,
+ "h": 728
+ },
+ "ext": {
+ "bidder": {
+ "placementId": 154
+ }
+ }
+ }
+ ]
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "//host",
+ "body": {
+ "id": "some_test_auction",
+ "imp": [
+ {
+ "id": "some_test_ad",
+ "banner": {
+ "h": 728,
+ "w": 90
+ },
+ "ext": {
+ "placementId": 154
+ }
+ }
+ ]
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "some_test_auction",
+ "seatbid": [
+ ],
+ "cur": "USD"
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/adapters/cpmstar/cpmstartest/supplemental/invalid-response-unmarshall-error.json b/adapters/cpmstar/cpmstartest/supplemental/invalid-response-unmarshall-error.json
new file mode 100644
index 00000000000..e20acefe2c3
--- /dev/null
+++ b/adapters/cpmstar/cpmstartest/supplemental/invalid-response-unmarshall-error.json
@@ -0,0 +1,66 @@
+{
+ "mockBidRequest": {
+ "id": "some_test_auction",
+ "imp": [
+ {
+ "id": "some_test_ad",
+ "banner": {
+ "w": 90,
+ "h": 728
+ },
+ "ext": {
+ "bidder": {
+ "placementId": 154
+ }
+ }
+ }
+ ]
+ },
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "//host",
+ "body": {
+ "id": "some_test_auction",
+ "imp": [
+ {
+ "id": "some_test_ad",
+ "banner": {
+ "h": 728,
+ "w": 90
+ },
+ "ext": {
+ "placementId": 154
+ }
+ }
+ ]
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "some_test_auction",
+ "seatbid": [
+ {
+ "bid": [
+ {
+ "id": "uuid",
+ "impid": "some_test_ad",
+ "w": "728",
+ "h": 90
+ }
+ ]
+ }
+ ],
+ "cur": "USD"
+ }
+ }
+ }
+ ],
+ "expectedMakeBidsErrors": [
+ {
+ "value": "json: cannot unmarshal string into Go struct field Bid(\\.seatbid\\.bid)?\\.w of type uint64",
+ "comparison": "regex"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/adapters/cpmstar/cpmstartest/supplemental/native.json b/adapters/cpmstar/cpmstartest/supplemental/native.json
new file mode 100644
index 00000000000..a02db78db0f
--- /dev/null
+++ b/adapters/cpmstar/cpmstartest/supplemental/native.json
@@ -0,0 +1,25 @@
+{
+ "mockBidRequest": {
+ "id": "unsupported-native-request",
+ "imp": [
+ {
+ "id": "unsupported-native-imp",
+ "native": {
+ "ver": "1.1"
+ },
+ "ext": {
+ "bidder": {
+ "placementId": 154
+ }
+ }
+ }
+ ]
+ },
+
+ "expectedMakeRequestsErrors": [
+ {
+ "value": "Only Banner and Video bid-types are supported at this time",
+ "comparison": "literal"
+ }
+ ]
+}
diff --git a/adapters/cpmstar/cpmstartest/supplemental/no-imps-in-request.json b/adapters/cpmstar/cpmstartest/supplemental/no-imps-in-request.json
new file mode 100644
index 00000000000..274a34227cf
--- /dev/null
+++ b/adapters/cpmstar/cpmstartest/supplemental/no-imps-in-request.json
@@ -0,0 +1,18 @@
+{
+ "mockBidRequest": {
+ "id": "some_test_auction",
+ "imp": [
+ ],
+ "site": {
+ "domain": "www.publisher.com",
+ "page": "http://www.publisher.com/awesome/site?with=some¶meters=here"
+ }
+ },
+
+ "expectedMakeRequestsErrors": [
+ {
+ "value": "No Imps in Bid Request",
+ "comparison": "literal"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/adapters/cpmstar/cpmstartest/supplemental/server-error-code.json b/adapters/cpmstar/cpmstartest/supplemental/server-error-code.json
new file mode 100644
index 00000000000..21e697d13f1
--- /dev/null
+++ b/adapters/cpmstar/cpmstartest/supplemental/server-error-code.json
@@ -0,0 +1,53 @@
+{
+ "mockBidRequest": {
+ "id": "some_test_auction",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "w": 600,
+ "h": 300
+ },
+ "ext": {
+ "bidder": {
+ "placementId": 154
+ }
+ }
+ }
+ ]
+ },
+
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "//host",
+ "body": {
+ "id": "some_test_auction",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "w": 600,
+ "h": 300
+ },
+ "ext": {
+ "placementId": 154
+ }
+ }
+ ]
+ }
+ },
+ "mockResponse": {
+ "status": 500,
+ "body": {}
+ }
+ }
+ ],
+
+ "expectedMakeBidsErrors": [
+ {
+ "value": "Unexpected HTTP status code: 500. Run with request.debug = 1 for more info",
+ "comparison": "literal"
+ }
+ ]
+ }
diff --git a/adapters/cpmstar/cpmstartest/supplemental/server-no-content.json b/adapters/cpmstar/cpmstartest/supplemental/server-no-content.json
new file mode 100644
index 00000000000..e56db95f8e8
--- /dev/null
+++ b/adapters/cpmstar/cpmstartest/supplemental/server-no-content.json
@@ -0,0 +1,45 @@
+{
+ "mockBidRequest": {
+ "id": "some_test_auction",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "w": 300,
+ "h": 250
+ },
+ "ext": {
+ "bidder": {
+ "placementId": 154
+ }
+ }
+ }
+ ]
+ },
+
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "//host",
+ "body": {
+ "id": "some_test_auction",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "w": 300,
+ "h": 250
+ },
+ "ext": {
+ "placementId": 154
+ }
+ }
+ ]
+ }
+ },
+ "mockResponse": {
+ "status": 204
+ }
+ }
+ ]
+ }
diff --git a/adapters/cpmstar/cpmstartest/supplemental/wrong-impression-ext.json b/adapters/cpmstar/cpmstartest/supplemental/wrong-impression-ext.json
new file mode 100644
index 00000000000..1e8de0acc66
--- /dev/null
+++ b/adapters/cpmstar/cpmstartest/supplemental/wrong-impression-ext.json
@@ -0,0 +1,26 @@
+{
+ "mockBidRequest": {
+ "id": "rqid",
+ "imp": [
+ {
+ "id": "impid",
+ "video": {
+ "w": 100,
+ "h": 200
+ },
+ "ext": {
+ "bidder": {
+ "placementId": "BOGUS"
+ }
+ }
+ }
+ ]
+ },
+
+ "expectedMakeRequestsErrors": [
+ {
+ "value": "json: cannot unmarshal string into Go struct field ExtImpCpmstar.placementId of type int",
+ "comparison": "literal"
+ }
+ ]
+}
diff --git a/adapters/cpmstar/cpmstartest/supplemental/wrong-impression-mapping.json b/adapters/cpmstar/cpmstartest/supplemental/wrong-impression-mapping.json
new file mode 100644
index 00000000000..6ab02db0ca7
--- /dev/null
+++ b/adapters/cpmstar/cpmstartest/supplemental/wrong-impression-mapping.json
@@ -0,0 +1,77 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "video": {
+ "w": 900,
+ "h": 250,
+ "mimes": [
+ "video/x-flv",
+ "video/mp4"
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "poolid": 154,
+ "subpoolid": 123
+ }
+ }
+ }
+ ]
+ },
+
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "//host",
+ "body": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id":"test-imp-id",
+ "video": {
+ "w": 900,
+ "h": 250,
+ "mimes": [
+ "video/x-flv",
+ "video/mp4"
+ ]
+ },
+ "ext": {
+ "poolid": 154,
+ "subpoolid": 123
+ }
+ }
+ ]
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "test-request-id",
+ "seatbid": [
+ {
+ "bid": [
+ {
+ "id": "test-bid-id",
+ "impid": "BOGUS-IMPID",
+ "price": 3.5,
+ "w": 900,
+ "h": 250
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ ],
+ "expectedMakeBidsErrors": [
+ {
+ "value": "bid id='test-bid-id' could not find valid impid='BOGUS-IMPID'",
+ "comparison": "regex"
+ }
+]
+}
\ No newline at end of file
diff --git a/adapters/cpmstar/params_test.go b/adapters/cpmstar/params_test.go
new file mode 100644
index 00000000000..cee471a8322
--- /dev/null
+++ b/adapters/cpmstar/params_test.go
@@ -0,0 +1,54 @@
+package cpmstar
+
+import (
+ "encoding/json"
+ "testing"
+
+ "github.com/prebid/prebid-server/openrtb_ext"
+)
+
+// This file actually intends to test static/bidder-params/cpmstar.json
+// These also validate the format of the external API: request.imp[i].ext.cpmstar
+// TestValidParams makes sure that the Cpmstar schema accepts all imp.ext fields which we intend to support.
+
+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.BidderCpmstar, json.RawMessage(validParam)); err != nil {
+ t.Errorf("Schema rejected Cpmstar params: %s", validParam)
+ }
+ }
+}
+
+// TestInvalidParams makes sure that the Cpmstar schema rejects all the imp.ext fields we don't support.
+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.BidderCpmstar, json.RawMessage(invalidParam)); err == nil {
+ t.Errorf("Schema allowed unexpected params: %s", invalidParam)
+ }
+ }
+}
+
+var validParams = []string{
+ `{"placementId": 154}`,
+ `{"placementId": 154, "subpoolId": 123}`,
+}
+
+var invalidParams = []string{
+ `{}`,
+ `null`,
+ `true`,
+ `154`,
+ `{"placementId": "154"}`, // placementId should be numeric
+ `{"placementId": 154, "subpoolId": "123"}`, // placementId and subpoolId should both be numeric
+ `{"invalid_param": 123}`,
+}
diff --git a/adapters/cpmstar/usersync.go b/adapters/cpmstar/usersync.go
new file mode 100644
index 00000000000..9c864e24ce3
--- /dev/null
+++ b/adapters/cpmstar/usersync.go
@@ -0,0 +1,13 @@
+package cpmstar
+
+import (
+ "text/template"
+
+ "github.com/prebid/prebid-server/adapters"
+ "github.com/prebid/prebid-server/usersync"
+)
+
+//NewCpmstarSyncer :
+func NewCpmstarSyncer(temp *template.Template) usersync.Usersyncer {
+ return adapters.NewSyncer("cpmstar", 0, temp, adapters.SyncTypeRedirect)
+}
diff --git a/adapters/cpmstar/usersync_test.go b/adapters/cpmstar/usersync_test.go
new file mode 100644
index 00000000000..dae55e6302e
--- /dev/null
+++ b/adapters/cpmstar/usersync_test.go
@@ -0,0 +1,25 @@
+package cpmstar
+
+import (
+ "testing"
+ "text/template"
+
+ "github.com/prebid/prebid-server/privacy"
+ "github.com/stretchr/testify/assert"
+)
+
+func TestCpmstarSyncer(t *testing.T) {
+ syncURL := "https://server.cpmstar.com/usersync.aspx?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirectUri=http%3A%2F%2Flocalhost:8000%2Fsetuid%3Fbidder%3Dcpmstar%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26us_privacy%3D{{.USPrivacy}}%26uid%3D%24UID"
+ syncURLTemplate := template.Must(
+ template.New("sync-template").Parse(syncURL),
+ )
+
+ syncer := NewCpmstarSyncer(syncURLTemplate)
+ syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{})
+
+ assert.NoError(t, err)
+ assert.Equal(t, "https://server.cpmstar.com/usersync.aspx?gdpr=&gdpr_consent=&us_privacy=&redirectUri=http%3A%2F%2Flocalhost:8000%2Fsetuid%3Fbidder%3Dcpmstar%26gdpr%3D%26gdpr_consent%3D%26us_privacy%3D%26uid%3D%24UID", syncInfo.URL)
+ assert.Equal(t, "redirect", syncInfo.Type)
+ assert.EqualValues(t, 0, syncer.GDPRVendorID())
+ assert.False(t, syncInfo.SupportCORS)
+}
diff --git a/adapters/datablocks/usersync_test.go b/adapters/datablocks/usersync_test.go
index 9dcaf8295fa..f8500ab9b03 100644
--- a/adapters/datablocks/usersync_test.go
+++ b/adapters/datablocks/usersync_test.go
@@ -5,12 +5,13 @@ import (
"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 TestDatablocksSyncer(t *testing.T) {
- syncURL := "https://sync.v5prebid.datablocks.net/s2ssync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&r=https%3A%2F%2Flocalhost%3A8888%2Fsetuid%3Fbidder%3Ddatablocks%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24%7Buid%7D"
+ syncURL := "https://sync.v5prebid.datablocks.net/s2ssync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r=https%3A%2F%2Flocalhost%3A8888%2Fsetuid%3Fbidder%3Ddatablocks%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24%7Buid%7D"
syncURLTemplate := template.Must(
template.New("sync-template").Parse(syncURL),
)
@@ -21,10 +22,13 @@ func TestDatablocksSyncer(t *testing.T) {
Signal: "1",
Consent: "BONciguONcjGKADACHENAOLS1rAHDAFAAEAASABQAMwAeACEAFw",
},
+ CCPA: ccpa.Policy{
+ Value: "1NYN",
+ },
})
assert.NoError(t, err)
- assert.Equal(t, "https://sync.v5prebid.datablocks.net/s2ssync?gdpr=1&gdpr_consent=BONciguONcjGKADACHENAOLS1rAHDAFAAEAASABQAMwAeACEAFw&r=https%3A%2F%2Flocalhost%3A8888%2Fsetuid%3Fbidder%3Ddatablocks%26gdpr%3D1%26gdpr_consent%3DBONciguONcjGKADACHENAOLS1rAHDAFAAEAASABQAMwAeACEAFw%26uid%3D%24%7Buid%7D", syncInfo.URL)
+ assert.Equal(t, "https://sync.v5prebid.datablocks.net/s2ssync?gdpr=1&gdpr_consent=BONciguONcjGKADACHENAOLS1rAHDAFAAEAASABQAMwAeACEAFw&us_privacy=1NYN&r=https%3A%2F%2Flocalhost%3A8888%2Fsetuid%3Fbidder%3Ddatablocks%26gdpr%3D1%26gdpr_consent%3DBONciguONcjGKADACHENAOLS1rAHDAFAAEAASABQAMwAeACEAFw%26uid%3D%24%7Buid%7D", syncInfo.URL)
assert.Equal(t, "redirect", syncInfo.Type)
assert.EqualValues(t, datablocksGDPRVendorID, syncer.GDPRVendorID())
assert.Equal(t, false, syncInfo.SupportCORS)
diff --git a/adapters/emx_digital/usersync_test.go b/adapters/emx_digital/usersync_test.go
index d8f874c8545..0e76936cea4 100644
--- a/adapters/emx_digital/usersync_test.go
+++ b/adapters/emx_digital/usersync_test.go
@@ -5,12 +5,13 @@ import (
"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 TestEMXDigitalSyncer(t *testing.T) {
- syncURL := "https://cs.emxdgt.com/um?ssp=pbs&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&redirect=localhost%2Fsetuid%3Fbidder%3Demx_digital%26uid%3D%24UID"
+ syncURL := "https://cs.emxdgt.com/um?ssp=pbs&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect=localhost%2Fsetuid%3Fbidder%3Demx_digital%26uid%3D%24UID"
syncURLTemplate := template.Must(
template.New("sync-template").Parse(syncURL),
)
@@ -21,10 +22,13 @@ func TestEMXDigitalSyncer(t *testing.T) {
Signal: "1",
Consent: "BOPVK28OVJoTBABABAENBs-AAAAhuAKAANAAoACwAGgAPAAxAB0AHgAQAAiABOADkA",
},
+ CCPA: ccpa.Policy{
+ Value: "1NYN",
+ },
})
assert.NoError(t, err)
- assert.Equal(t, "https://cs.emxdgt.com/um?ssp=pbs&gdpr=1&gdpr_consent=BOPVK28OVJoTBABABAENBs-AAAAhuAKAANAAoACwAGgAPAAxAB0AHgAQAAiABOADkA&redirect=localhost%2Fsetuid%3Fbidder%3Demx_digital%26uid%3D%24UID", syncInfo.URL)
+ assert.Equal(t, "https://cs.emxdgt.com/um?ssp=pbs&gdpr=1&gdpr_consent=BOPVK28OVJoTBABABAENBs-AAAAhuAKAANAAoACwAGgAPAAxAB0AHgAQAAiABOADkA&us_privacy=1NYN&redirect=localhost%2Fsetuid%3Fbidder%3Demx_digital%26uid%3D%24UID", syncInfo.URL)
assert.Equal(t, "iframe", syncInfo.Type)
assert.EqualValues(t, 183, syncer.GDPRVendorID())
assert.Equal(t, false, syncInfo.SupportCORS)
diff --git a/adapters/engagebdr/usersync_test.go b/adapters/engagebdr/usersync_test.go
index fbcde923f09..45e1e41e196 100644
--- a/adapters/engagebdr/usersync_test.go
+++ b/adapters/engagebdr/usersync_test.go
@@ -5,12 +5,13 @@ import (
"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 TestEngageBDRSyncer(t *testing.T) {
- syncURL := "https://match.bnmla.com/usersync/prbds2s?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&r=localhost%2Fsetuid%3Fbidder%3Dgumgum%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D"
+ syncURL := "https://match.bnmla.com/usersync/s2s?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r=localhost%2Fsetuid%3Fbidder%3Dengagebdr%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D"
syncURLTemplate := template.Must(
template.New("sync-template").Parse(syncURL),
)
@@ -21,10 +22,13 @@ func TestEngageBDRSyncer(t *testing.T) {
Signal: "1",
Consent: "BOPVK28OVJoTBABABAENBs-AAAAhuAKAANAAoACwAGgAPAAxAB0AHgAQAAiABOADkA",
},
+ CCPA: ccpa.Policy{
+ Value: "1NYN",
+ },
})
assert.NoError(t, err)
- assert.Equal(t, "https://match.bnmla.com/usersync/prbds2s?gdpr=1&gdpr_consent=BOPVK28OVJoTBABABAENBs-AAAAhuAKAANAAoACwAGgAPAAxAB0AHgAQAAiABOADkA&r=localhost%2Fsetuid%3Fbidder%3Dgumgum%26gdpr%3D1%26gdpr_consent%3DBOPVK28OVJoTBABABAENBs-AAAAhuAKAANAAoACwAGgAPAAxAB0AHgAQAAiABOADkA%26uid%3D", syncInfo.URL)
+ assert.Equal(t, "https://match.bnmla.com/usersync/s2s?gdpr=1&gdpr_consent=BOPVK28OVJoTBABABAENBs-AAAAhuAKAANAAoACwAGgAPAAxAB0AHgAQAAiABOADkA&us_privacy=1NYN&r=localhost%2Fsetuid%3Fbidder%3Dengagebdr%26gdpr%3D1%26gdpr_consent%3DBOPVK28OVJoTBABABAENBs-AAAAhuAKAANAAoACwAGgAPAAxAB0AHgAQAAiABOADkA%26uid%3D", syncInfo.URL)
assert.Equal(t, "iframe", syncInfo.Type)
assert.EqualValues(t, 62, syncer.GDPRVendorID())
assert.Equal(t, false, syncInfo.SupportCORS)
diff --git a/adapters/eplanning/eplanning_test.go b/adapters/eplanning/eplanning_test.go
index d1219ce4eef..d2c331d456d 100644
--- a/adapters/eplanning/eplanning_test.go
+++ b/adapters/eplanning/eplanning_test.go
@@ -8,7 +8,7 @@ import (
)
func TestJsonSamples(t *testing.T) {
- eplanningAdapter := NewEPlanningBidder(new(http.Client), "http://ads.us.e-planning.net/hb/1")
+ eplanningAdapter := NewEPlanningBidder(new(http.Client), "https://ads.us.e-planning.net/hb/1")
eplanningAdapter.testing = true
adapterstest.RunJSONBidderTest(t, "eplanningtest", eplanningAdapter)
}
diff --git a/adapters/eplanning/eplanningtest/exemplary/simple-banner-2.json b/adapters/eplanning/eplanningtest/exemplary/simple-banner-2.json
index 596b061576f..f4c8fe0c273 100644
--- a/adapters/eplanning/eplanningtest/exemplary/simple-banner-2.json
+++ b/adapters/eplanning/eplanningtest/exemplary/simple-banner-2.json
@@ -28,7 +28,7 @@
"httpCalls": [
{
"expectedRequest": {
- "uri": "http://ads.us.e-planning.net/hb/1/12345/1/FILE/ROS?r=pbs&ncb=1&ur=FILE&e=300x250:300x250",
+ "uri": "https://ads.us.e-planning.net/hb/1/12345/1/FILE/ROS?r=pbs&ncb=1&ur=FILE&e=300x250:300x250",
"body": {}
},
"mockResponse": {
diff --git a/adapters/eplanning/eplanningtest/exemplary/simple-banner.json b/adapters/eplanning/eplanningtest/exemplary/simple-banner.json
index 21cbbdae7df..61b7878a8bf 100644
--- a/adapters/eplanning/eplanningtest/exemplary/simple-banner.json
+++ b/adapters/eplanning/eplanningtest/exemplary/simple-banner.json
@@ -31,7 +31,7 @@
"httpCalls": [
{
"expectedRequest": {
- "uri": "http://ads.us.e-planning.net/hb/1/12345/1/FILE/ROS?r=pbs&ncb=1&ur=FILE&e=testadun_itco_de:600x300&uid=2154987&ip=123.123.123.123",
+ "uri": "https://ads.us.e-planning.net/hb/1/12345/1/FILE/ROS?r=pbs&ncb=1&ur=FILE&e=testadun_itco_de:600x300&uid=2154987&ip=123.123.123.123",
"body": {}
},
"mockResponse": {
diff --git a/adapters/eplanning/eplanningtest/exemplary/two-banners.json b/adapters/eplanning/eplanningtest/exemplary/two-banners.json
index 15639524207..fccc1a30e7e 100644
--- a/adapters/eplanning/eplanningtest/exemplary/two-banners.json
+++ b/adapters/eplanning/eplanningtest/exemplary/two-banners.json
@@ -39,7 +39,7 @@
"httpCalls": [
{
"expectedRequest": {
- "uri": "http://ads.us.e-planning.net/hb/1/12345/1/FILE/ROS?r=pbs&ncb=1&ur=FILE&e=testadunitcode:600x300+300x250:300x250&ip=123.123.123.123",
+ "uri": "https://ads.us.e-planning.net/hb/1/12345/1/FILE/ROS?r=pbs&ncb=1&ur=FILE&e=testadunitcode:600x300+300x250:300x250&ip=123.123.123.123",
"body": {}
},
"mockResponse": {
@@ -120,4 +120,4 @@
}
]
}
-
\ No newline at end of file
+
diff --git a/adapters/eplanning/eplanningtest/supplemental/banner-no-size-sends-1x1.json b/adapters/eplanning/eplanningtest/supplemental/banner-no-size-sends-1x1.json
index 729115e55de..afa7b9532df 100644
--- a/adapters/eplanning/eplanningtest/supplemental/banner-no-size-sends-1x1.json
+++ b/adapters/eplanning/eplanningtest/supplemental/banner-no-size-sends-1x1.json
@@ -19,7 +19,7 @@
"httpCalls": [
{
"expectedRequest": {
- "uri": "http://ads.us.e-planning.net/hb/1/12345/1/FILE/ROS?r=pbs&ncb=1&ur=FILE&e=testadunitcodenosize:1x1",
+ "uri": "https://ads.us.e-planning.net/hb/1/12345/1/FILE/ROS?r=pbs&ncb=1&ur=FILE&e=testadunitcodenosize:1x1",
"body": {}
},
"mockResponse": {
@@ -67,4 +67,4 @@
}
]
}
-
\ No newline at end of file
+
diff --git a/adapters/eplanning/eplanningtest/supplemental/invalid-response-no-bids.json b/adapters/eplanning/eplanningtest/supplemental/invalid-response-no-bids.json
index 57db7023360..3bf45a16364 100644
--- a/adapters/eplanning/eplanningtest/supplemental/invalid-response-no-bids.json
+++ b/adapters/eplanning/eplanningtest/supplemental/invalid-response-no-bids.json
@@ -21,7 +21,7 @@
"httpCalls": [
{
"expectedRequest": {
- "uri": "http://ads.us.e-planning.net/hb/1/12345/1/FILE/ROS?r=pbs&ncb=1&ur=FILE&e=testadunitcode:600x300",
+ "uri": "https://ads.us.e-planning.net/hb/1/12345/1/FILE/ROS?r=pbs&ncb=1&ur=FILE&e=testadunitcode:600x300",
"body": {}
},
"mockResponse": {
@@ -45,4 +45,4 @@
}
]
}
-
\ No newline at end of file
+
diff --git a/adapters/eplanning/eplanningtest/supplemental/invalid-response-unmarshall-error.json b/adapters/eplanning/eplanningtest/supplemental/invalid-response-unmarshall-error.json
index fc85a6b45c0..e8d88f17a5e 100644
--- a/adapters/eplanning/eplanningtest/supplemental/invalid-response-unmarshall-error.json
+++ b/adapters/eplanning/eplanningtest/supplemental/invalid-response-unmarshall-error.json
@@ -21,7 +21,7 @@
"httpCalls": [
{
"expectedRequest": {
- "uri": "http://ads.us.e-planning.net/hb/1/12345/1/FILE/ROS?r=pbs&ncb=1&ur=FILE&e=testadunitcode:600x300",
+ "uri": "https://ads.us.e-planning.net/hb/1/12345/1/FILE/ROS?r=pbs&ncb=1&ur=FILE&e=testadunitcode:600x300",
"body": {}
},
"mockResponse": {
@@ -52,4 +52,4 @@
}
]
}
-
\ No newline at end of file
+
diff --git a/adapters/eplanning/eplanningtest/supplemental/server-bad-request.json b/adapters/eplanning/eplanningtest/supplemental/server-bad-request.json
index 052c0561095..421f47efe3b 100644
--- a/adapters/eplanning/eplanningtest/supplemental/server-bad-request.json
+++ b/adapters/eplanning/eplanningtest/supplemental/server-bad-request.json
@@ -21,7 +21,7 @@
"httpCalls": [
{
"expectedRequest": {
- "uri": "http://ads.us.e-planning.net/hb/1/12345/1/FILE/ROS?r=pbs&ncb=1&ur=FILE&e=testadunitcode:600x300",
+ "uri": "https://ads.us.e-planning.net/hb/1/12345/1/FILE/ROS?r=pbs&ncb=1&ur=FILE&e=testadunitcode:600x300",
"body": {}
},
"mockResponse": {
@@ -55,4 +55,4 @@
}
]
}
-
\ No newline at end of file
+
diff --git a/adapters/eplanning/eplanningtest/supplemental/server-error-code.json b/adapters/eplanning/eplanningtest/supplemental/server-error-code.json
index 699968ce398..ceec970ba45 100644
--- a/adapters/eplanning/eplanningtest/supplemental/server-error-code.json
+++ b/adapters/eplanning/eplanningtest/supplemental/server-error-code.json
@@ -21,7 +21,7 @@
"httpCalls": [
{
"expectedRequest": {
- "uri": "http://ads.us.e-planning.net/hb/1/12345/1/FILE/ROS?r=pbs&ncb=1&ur=FILE&e=testadunitcode:600x300",
+ "uri": "https://ads.us.e-planning.net/hb/1/12345/1/FILE/ROS?r=pbs&ncb=1&ur=FILE&e=testadunitcode:600x300",
"body": {}
},
"mockResponse": {
@@ -55,4 +55,4 @@
}
]
}
-
\ No newline at end of file
+
diff --git a/adapters/eplanning/eplanningtest/supplemental/server-no-content.json b/adapters/eplanning/eplanningtest/supplemental/server-no-content.json
index 9058699af3e..a2e444a9901 100644
--- a/adapters/eplanning/eplanningtest/supplemental/server-no-content.json
+++ b/adapters/eplanning/eplanningtest/supplemental/server-no-content.json
@@ -21,7 +21,7 @@
"httpCalls": [
{
"expectedRequest": {
- "uri": "http://ads.us.e-planning.net/hb/1/12345/1/FILE/ROS?r=pbs&ncb=1&ur=FILE&e=testadunitcode:600x300",
+ "uri": "https://ads.us.e-planning.net/hb/1/12345/1/FILE/ROS?r=pbs&ncb=1&ur=FILE&e=testadunitcode:600x300",
"body": {}
},
"mockResponse": {
@@ -30,4 +30,4 @@
}
]
}
-
\ No newline at end of file
+
diff --git a/adapters/eplanning/eplanningtest/supplemental/site-domain-and-url-correctly-parsed.json b/adapters/eplanning/eplanningtest/supplemental/site-domain-and-url-correctly-parsed.json
index 4ce8ef2f692..d889f48189c 100644
--- a/adapters/eplanning/eplanningtest/supplemental/site-domain-and-url-correctly-parsed.json
+++ b/adapters/eplanning/eplanningtest/supplemental/site-domain-and-url-correctly-parsed.json
@@ -25,7 +25,7 @@
"httpCalls": [
{
"expectedRequest": {
- "uri": "http://ads.us.e-planning.net/hb/1/12345/1/www.publisher.com/ROS?r=pbs&ncb=1&ur=http%3A%2F%2Fwww.publisher.com%2Fawesome%2Fsite%3Fwith%3Dsome%26parameters%3Dhere&e=testadunitcode:600x300",
+ "uri": "https://ads.us.e-planning.net/hb/1/12345/1/www.publisher.com/ROS?r=pbs&ncb=1&ur=http%3A%2F%2Fwww.publisher.com%2Fawesome%2Fsite%3Fwith%3Dsome%26parameters%3Dhere&e=testadunitcode:600x300",
"body": {}
},
"mockResponse": {
@@ -73,4 +73,4 @@
}
]
}
-
\ No newline at end of file
+
diff --git a/adapters/gumgum/usersync_test.go b/adapters/gumgum/usersync_test.go
index 22c42695d38..3606f6ae04c 100644
--- a/adapters/gumgum/usersync_test.go
+++ b/adapters/gumgum/usersync_test.go
@@ -5,12 +5,13 @@ import (
"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 TestGumGumSyncer(t *testing.T) {
- syncURL := "https://rtb.gumgum.com/usync/prbds2s?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&r=localhost%2Fsetuid%3Fbidder%3Dgumgum%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D"
+ syncURL := "https://rtb.gumgum.com/usync/prbds2s?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r=localhost%2Fsetuid%3Fbidder%3Dgumgum%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D"
syncURLTemplate := template.Must(
template.New("sync-template").Parse(syncURL),
)
@@ -21,10 +22,13 @@ func TestGumGumSyncer(t *testing.T) {
Signal: "1",
Consent: "BOPVK28OVJoTBABABAENBs-AAAAhuAKAANAAoACwAGgAPAAxAB0AHgAQAAiABOADkA",
},
+ CCPA: ccpa.Policy{
+ Value: "1NYN",
+ },
})
assert.NoError(t, err)
- assert.Equal(t, "https://rtb.gumgum.com/usync/prbds2s?gdpr=1&gdpr_consent=BOPVK28OVJoTBABABAENBs-AAAAhuAKAANAAoACwAGgAPAAxAB0AHgAQAAiABOADkA&r=localhost%2Fsetuid%3Fbidder%3Dgumgum%26gdpr%3D1%26gdpr_consent%3DBOPVK28OVJoTBABABAENBs-AAAAhuAKAANAAoACwAGgAPAAxAB0AHgAQAAiABOADkA%26uid%3D", syncInfo.URL)
+ assert.Equal(t, "https://rtb.gumgum.com/usync/prbds2s?gdpr=1&gdpr_consent=BOPVK28OVJoTBABABAENBs-AAAAhuAKAANAAoACwAGgAPAAxAB0AHgAQAAiABOADkA&us_privacy=1NYN&r=localhost%2Fsetuid%3Fbidder%3Dgumgum%26gdpr%3D1%26gdpr_consent%3DBOPVK28OVJoTBABABAENBs-AAAAhuAKAANAAoACwAGgAPAAxAB0AHgAQAAiABOADkA%26uid%3D", syncInfo.URL)
assert.Equal(t, "iframe", syncInfo.Type)
assert.EqualValues(t, 61, syncer.GDPRVendorID())
assert.Equal(t, false, syncInfo.SupportCORS)
diff --git a/adapters/improvedigital/usersync_test.go b/adapters/improvedigital/usersync_test.go
index 861e4875a80..c928ebf123d 100644
--- a/adapters/improvedigital/usersync_test.go
+++ b/adapters/improvedigital/usersync_test.go
@@ -5,12 +5,13 @@ import (
"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 TestImprovedigitalSyncer(t *testing.T) {
- syncURL := "//not_localhost/synclocalhost%2Fsetuid%3Fbidder%3Dimprovedigital%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%7BPUB_USER_ID%7D"
+ syncURL := "https://ad.360yield.com/server_match?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r=%2Fsetuid%3Fbidder%3Dimprovedigital%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%7BPUB_USER_ID%7D"
syncURLTemplate := template.Must(
template.New("sync-template").Parse(syncURL),
)
@@ -18,12 +19,16 @@ func TestImprovedigitalSyncer(t *testing.T) {
syncer := NewImprovedigitalSyncer(syncURLTemplate)
syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{
GDPR: gdpr.Policy{
- Signal: "0",
+ Signal: "A",
+ Consent: "B",
+ },
+ CCPA: ccpa.Policy{
+ Value: "C",
},
})
assert.NoError(t, err)
- assert.Equal(t, "//not_localhost/synclocalhost%2Fsetuid%3Fbidder%3Dimprovedigital%26gdpr%3D0%26gdpr_consent%3D%26uid%3D%7BPUB_USER_ID%7D", syncInfo.URL)
+ assert.Equal(t, "https://ad.360yield.com/server_match?gdpr=A&gdpr_consent=B&us_privacy=C&r=%2Fsetuid%3Fbidder%3Dimprovedigital%26gdpr%3DA%26gdpr_consent%3DB%26uid%3D%7BPUB_USER_ID%7D", syncInfo.URL)
assert.Equal(t, "redirect", syncInfo.Type)
assert.EqualValues(t, 253, syncer.GDPRVendorID())
assert.Equal(t, false, syncInfo.SupportCORS)
diff --git a/adapters/lockerdome/usersync_test.go b/adapters/lockerdome/usersync_test.go
index b0307c0f215..b5dea2261b6 100644
--- a/adapters/lockerdome/usersync_test.go
+++ b/adapters/lockerdome/usersync_test.go
@@ -9,7 +9,7 @@ import (
)
func TestLockerDomeSyncer(t *testing.T) {
- syncURL := "https://lockerdome.com/usync/prebidserver?pid=&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&redirect=https%3A%2F%2Flocalhost%2Fsetuid%3Fbidder%3Dlockerdome%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%7B%7Buid%7D%7D"
+ syncURL := "https://lockerdome.com/usync/prebidserver?pid=&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect=https%3A%2F%2Flocalhost%2Fsetuid%3Fbidder%3Dlockerdome%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%7B%7Buid%7D%7D"
syncURLTemplate := template.Must(
template.New("sync-template").Parse(syncURL),
)
@@ -18,7 +18,7 @@ func TestLockerDomeSyncer(t *testing.T) {
syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{})
assert.NoError(t, err)
- assert.Equal(t, "https://lockerdome.com/usync/prebidserver?pid=&gdpr=&gdpr_consent=&redirect=https%3A%2F%2Flocalhost%2Fsetuid%3Fbidder%3Dlockerdome%26gdpr%3D%26gdpr_consent%3D%26uid%3D%7B%7Buid%7D%7D", syncInfo.URL)
+ assert.Equal(t, "https://lockerdome.com/usync/prebidserver?pid=&gdpr=&gdpr_consent=&us_privacy=&redirect=https%3A%2F%2Flocalhost%2Fsetuid%3Fbidder%3Dlockerdome%26gdpr%3D%26gdpr_consent%3D%26uid%3D%7B%7Buid%7D%7D", syncInfo.URL)
assert.Equal(t, "redirect", syncInfo.Type)
assert.EqualValues(t, 0, syncer.GDPRVendorID())
assert.Equal(t, false, syncInfo.SupportCORS)
diff --git a/adapters/marsmedia/usersync_test.go b/adapters/marsmedia/usersync_test.go
index 0e50e2bcec9..67276a35fb6 100644
--- a/adapters/marsmedia/usersync_test.go
+++ b/adapters/marsmedia/usersync_test.go
@@ -5,16 +5,32 @@ import (
"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 TestMarsmediaSyncer(t *testing.T) {
- temp := template.Must(template.New("sync-template").Parse("http://dmp.rtbsrv.com/dmp/profiles/cm?p_id=179&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&redirect=localhost:8000%2Fsetuid%3Fbidder%3Dmarsmedia%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24%7BUUID%7D"))
- syncer := NewMarsmediaSyncer(temp)
- syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{})
+ syncURL := "https://dmp.rtbsrv.com/dmp/profiles/cm?p_id=179&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect=localhost:8000%2Fsetuid%3Fbidder%3Dmarsmedia%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24%7BUUID%7D"
+ syncURLTemplate := template.Must(
+ template.New("sync-template").Parse(syncURL),
+ )
+
+ syncer := NewMarsmediaSyncer(syncURLTemplate)
+ syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{
+ GDPR: gdpr.Policy{
+ Signal: "A",
+ Consent: "B",
+ },
+ CCPA: ccpa.Policy{
+ Value: "C",
+ },
+ })
+
assert.NoError(t, err)
- assert.Equal(t, "http://dmp.rtbsrv.com/dmp/profiles/cm?p_id=179&gdpr=&gdpr_consent=&redirect=localhost:8000%2Fsetuid%3Fbidder%3Dmarsmedia%26gdpr%3D%26gdpr_consent%3D%26uid%3D%24%7BUUID%7D", syncInfo.URL)
+ assert.Equal(t, "https://dmp.rtbsrv.com/dmp/profiles/cm?p_id=179&gdpr=A&gdpr_consent=B&us_privacy=C&redirect=localhost:8000%2Fsetuid%3Fbidder%3Dmarsmedia%26gdpr%3DA%26gdpr_consent%3DB%26uid%3D%24%7BUUID%7D", syncInfo.URL)
assert.Equal(t, "redirect", syncInfo.Type)
assert.EqualValues(t, 0, syncer.GDPRVendorID())
assert.Equal(t, false, syncInfo.SupportCORS)
+
}
diff --git a/adapters/pubmatic/pubmatic_test.go b/adapters/pubmatic/pubmatic_test.go
index 4eb66d25430..be086f5adf1 100644
--- a/adapters/pubmatic/pubmatic_test.go
+++ b/adapters/pubmatic/pubmatic_test.go
@@ -23,7 +23,7 @@ import (
)
func TestJsonSamples(t *testing.T) {
- adapterstest.RunJSONBidderTest(t, "pubmatictest", NewPubmaticBidder(nil, "http://hbopenbid.pubmatic.com/translator?source=prebid-server"))
+ adapterstest.RunJSONBidderTest(t, "pubmatictest", NewPubmaticBidder(nil, "https://hbopenbid.pubmatic.com/translator?source=prebid-server"))
}
// ----------------------------------------------------------------------------
diff --git a/adapters/pubmatic/pubmatictest/exemplary/simple-banner.json b/adapters/pubmatic/pubmatictest/exemplary/simple-banner.json
index e669bce8826..1eb8a212bff 100644
--- a/adapters/pubmatic/pubmatictest/exemplary/simple-banner.json
+++ b/adapters/pubmatic/pubmatictest/exemplary/simple-banner.json
@@ -43,7 +43,7 @@
"httpCalls": [
{
"expectedRequest": {
- "uri": "http://hbopenbid.pubmatic.com/translator?source=prebid-server",
+ "uri": "https://hbopenbid.pubmatic.com/translator?source=prebid-server",
"body": {
"id": "test-request-id",
"imp": [
diff --git a/adapters/pubmatic/pubmatictest/exemplary/video.json b/adapters/pubmatic/pubmatictest/exemplary/video.json
index f9cfc2976ea..25ed366ee05 100644
--- a/adapters/pubmatic/pubmatictest/exemplary/video.json
+++ b/adapters/pubmatic/pubmatictest/exemplary/video.json
@@ -49,7 +49,7 @@
"httpCalls": [
{
"expectedRequest": {
- "uri": "http://hbopenbid.pubmatic.com/translator?source=prebid-server",
+ "uri": "https://hbopenbid.pubmatic.com/translator?source=prebid-server",
"body": {
"id": "test-video-request",
"imp": [
diff --git a/adapters/pubmatic/pubmatictest/supplemental/app.json b/adapters/pubmatic/pubmatictest/supplemental/app.json
index a2b737f0aa2..636433ca1f5 100644
--- a/adapters/pubmatic/pubmatictest/supplemental/app.json
+++ b/adapters/pubmatic/pubmatictest/supplemental/app.json
@@ -43,7 +43,7 @@
"httpCalls": [
{
"expectedRequest": {
- "uri": "http://hbopenbid.pubmatic.com/translator?source=prebid-server",
+ "uri": "https://hbopenbid.pubmatic.com/translator?source=prebid-server",
"body": {
"id": "app-request",
"imp": [
diff --git a/adapters/pubmatic/pubmatictest/supplemental/multiplemedia.json b/adapters/pubmatic/pubmatictest/supplemental/multiplemedia.json
index faf71fec1b6..a576abe6198 100644
--- a/adapters/pubmatic/pubmatictest/supplemental/multiplemedia.json
+++ b/adapters/pubmatic/pubmatictest/supplemental/multiplemedia.json
@@ -29,7 +29,7 @@
"httpCalls": [
{
"expectedRequest": {
- "uri": "http://hbopenbid.pubmatic.com/translator?source=prebid-server",
+ "uri": "https://hbopenbid.pubmatic.com/translator?source=prebid-server",
"body": {
"id": "multiple-media-request",
"imp": [
diff --git a/adapters/pubmatic/usersync_test.go b/adapters/pubmatic/usersync_test.go
index ef81d223377..dd4a086c453 100644
--- a/adapters/pubmatic/usersync_test.go
+++ b/adapters/pubmatic/usersync_test.go
@@ -5,12 +5,13 @@ import (
"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 TestPubmaticSyncer(t *testing.T) {
- syncURL := "//ads.pubmatic.com/AdServer/js/user_sync.html?predirect=localhost%2Fsetuid%3Fbidder%3Dpubmatic%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D"
+ syncURL := "//ads.pubmatic.com/AdServer/js/user_sync.html?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&predirect=localhost%2Fsetuid%3Fbidder%3Dpubmatic%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D"
syncURLTemplate := template.Must(
template.New("sync-template").Parse(syncURL),
)
@@ -18,13 +19,16 @@ func TestPubmaticSyncer(t *testing.T) {
syncer := NewPubmaticSyncer(syncURLTemplate)
syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{
GDPR: gdpr.Policy{
- Signal: "1",
- Consent: "BONciguONcjGKADACHENAOLS1rAHDAFAAEAASABQAMwAeACEAFw",
+ Signal: "A",
+ Consent: "B",
+ },
+ CCPA: ccpa.Policy{
+ Value: "C",
},
})
assert.NoError(t, err)
- assert.Equal(t, "//ads.pubmatic.com/AdServer/js/user_sync.html?predirect=localhost%2Fsetuid%3Fbidder%3Dpubmatic%26gdpr%3D1%26gdpr_consent%3DBONciguONcjGKADACHENAOLS1rAHDAFAAEAASABQAMwAeACEAFw%26uid%3D", syncInfo.URL)
+ assert.Equal(t, "//ads.pubmatic.com/AdServer/js/user_sync.html?gdpr=A&gdpr_consent=B&us_privacy=C&predirect=localhost%2Fsetuid%3Fbidder%3Dpubmatic%26gdpr%3DA%26gdpr_consent%3DB%26uid%3D", syncInfo.URL)
assert.Equal(t, "iframe", syncInfo.Type)
assert.EqualValues(t, 76, syncer.GDPRVendorID())
assert.Equal(t, false, syncInfo.SupportCORS)
diff --git a/adapters/rhythmone/usersync_test.go b/adapters/rhythmone/usersync_test.go
index 0dcf4fbda7e..cee6e9b0259 100644
--- a/adapters/rhythmone/usersync_test.go
+++ b/adapters/rhythmone/usersync_test.go
@@ -5,12 +5,13 @@ import (
"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 TestRhythmoneSyncer(t *testing.T) {
- syncURL := "https://sync.1rx.io/usersync2/rmphb?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&redir=localhost%2Fsetuid%3Fbidder%3Drhythmone%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%5BRX_UUID%5D"
+ syncURL := "https://sync.1rx.io/usersync2/rmphb?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redir=localhost%2Fsetuid%3Fbidder%3Drhythmone%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%5BRX_UUID%5D"
syncURLTemplate := template.Must(
template.New("sync-template").Parse(syncURL),
)
@@ -21,10 +22,13 @@ func TestRhythmoneSyncer(t *testing.T) {
Signal: "1",
Consent: "BOPVK28OVJoTBABABAENBs-AAAAhuAKAANAAoACwAGgAPAAxAB0AHgAQAAiABOADkA",
},
+ CCPA: ccpa.Policy{
+ Value: "1NYN",
+ },
})
assert.NoError(t, err)
- assert.Equal(t, "https://sync.1rx.io/usersync2/rmphb?gdpr=1&gdpr_consent=BOPVK28OVJoTBABABAENBs-AAAAhuAKAANAAoACwAGgAPAAxAB0AHgAQAAiABOADkA&redir=localhost%2Fsetuid%3Fbidder%3Drhythmone%26gdpr%3D1%26gdpr_consent%3DBOPVK28OVJoTBABABAENBs-AAAAhuAKAANAAoACwAGgAPAAxAB0AHgAQAAiABOADkA%26uid%3D%5BRX_UUID%5D", syncInfo.URL)
+ assert.Equal(t, "https://sync.1rx.io/usersync2/rmphb?gdpr=1&gdpr_consent=BOPVK28OVJoTBABABAENBs-AAAAhuAKAANAAoACwAGgAPAAxAB0AHgAQAAiABOADkA&us_privacy=1NYN&redir=localhost%2Fsetuid%3Fbidder%3Drhythmone%26gdpr%3D1%26gdpr_consent%3DBOPVK28OVJoTBABABAENBs-AAAAhuAKAANAAoACwAGgAPAAxAB0AHgAQAAiABOADkA%26uid%3D%5BRX_UUID%5D", syncInfo.URL)
assert.Equal(t, "redirect", syncInfo.Type)
assert.EqualValues(t, 36, syncer.GDPRVendorID())
assert.Equal(t, false, syncInfo.SupportCORS)
diff --git a/adapters/rubicon/rubicon.go b/adapters/rubicon/rubicon.go
index 7f8de46bcfe..46caf262108 100644
--- a/adapters/rubicon/rubicon.go
+++ b/adapters/rubicon/rubicon.go
@@ -5,13 +5,14 @@ import (
"context"
"encoding/json"
"fmt"
- "github.com/golang/glog"
- "github.com/prebid/prebid-server/pbs"
"io/ioutil"
"net/http"
"net/url"
"strings"
+ "github.com/golang/glog"
+ "github.com/prebid/prebid-server/pbs"
+
"golang.org/x/net/context/ctxhttp"
"github.com/mxmCherry/openrtb"
@@ -128,6 +129,7 @@ type rubiconVideoParams struct {
type rubiconVideoExt struct {
Skip int `json:"skip,omitempty"`
SkipDelay int `json:"skipdelay,omitempty"`
+ VideoType string `json:"videotype,omitempty"`
RP rubiconVideoExtRP `json:"rp"`
}
@@ -685,8 +687,21 @@ func (a *RubiconAdapter) MakeRequests(request *openrtb.BidRequest, reqInfo *adap
isVideo := isVideo(thisImp)
if isVideo {
+ if rubiconExt.Video.VideoSizeID == 0 {
+ errs = append(errs, &errortypes.BadInput{
+ Message: fmt.Sprintf("imp[%d].ext.bidder.rubicon.video.size_id must be defined for video impression", i),
+ })
+ continue
+ }
+
+ // if imp.ext.is_rewarded_inventory = 1, set imp.video.ext.videotype = "rewarded"
+ var videoType = ""
+ if bidderExt.Prebid != nil && bidderExt.Prebid.IsRewardedInventory == 1 {
+ videoType = "rewarded"
+ }
+
videoCopy := *thisImp.Video
- videoExt := rubiconVideoExt{Skip: rubiconExt.Video.Skip, SkipDelay: rubiconExt.Video.SkipDelay, RP: rubiconVideoExtRP{SizeID: rubiconExt.Video.VideoSizeID}}
+ videoExt := rubiconVideoExt{Skip: rubiconExt.Video.Skip, SkipDelay: rubiconExt.Video.SkipDelay, VideoType: videoType, RP: rubiconVideoExtRP{SizeID: rubiconExt.Video.VideoSizeID}}
videoCopy.Ext, err = json.Marshal(&videoExt)
thisImp.Video = &videoCopy
thisImp.Banner = nil
diff --git a/adapters/rubicon/rubicon_test.go b/adapters/rubicon/rubicon_test.go
index bc3d2e8ae9e..d386daed5b1 100644
--- a/adapters/rubicon/rubicon_test.go
+++ b/adapters/rubicon/rubicon_test.go
@@ -1244,8 +1244,9 @@ func TestOpenRTBRequestWithVideoImpEvenIfImpHasBannerButAllRequiredVideoFields(t
"zoneId": 8394,
"siteId": 283282,
"accountId": 7891,
- "inventory": {"key1" : "val1"},
- "visitor": {"key2" : "val2"}
+ "inventory": {"key1": "val1"},
+ "visitor": {"key2": "val2"},
+ "video": {"size_id": 1}
}}`),
}},
}
@@ -1269,6 +1270,48 @@ func TestOpenRTBRequestWithVideoImpEvenIfImpHasBannerButAllRequiredVideoFields(t
assert.NotNil(t, rubiconReq.Imp[0].Video, "Video object must be in request impression")
}
+func TestOpenRTBRequestWithVideoImpAndEnabledRewardedInventoryFlag(t *testing.T) {
+ bidder := new(RubiconAdapter)
+
+ request := &openrtb.BidRequest{
+ ID: "test-request-id",
+ Imp: []openrtb.Imp{{
+ ID: "test-imp-id",
+ Video: &openrtb.Video{
+ W: 640,
+ H: 360,
+ MIMEs: []string{"video/mp4"},
+ Protocols: []openrtb.Protocol{openrtb.ProtocolVAST10},
+ MaxDuration: 30,
+ Linearity: 1,
+ API: []openrtb.APIFramework{},
+ },
+ Ext: json.RawMessage(`{
+ "prebid":{
+ "is_rewarded_inventory": 1
+ },
+ "bidder": {
+ "video": {"size_id": 1}
+ }}`),
+ }},
+ }
+
+ reqs, _ := bidder.MakeRequests(request, &adapters.ExtraRequestInfo{})
+
+ rubiconReq := &openrtb.BidRequest{}
+ if err := json.Unmarshal(reqs[0].Body, rubiconReq); err != nil {
+ t.Fatalf("Unexpected error while decoding request: %s", err)
+ }
+
+ videoExt := &rubiconVideoExt{}
+ if err := json.Unmarshal(rubiconReq.Imp[0].Video.Ext, &videoExt); err != nil {
+ t.Fatal("Error unmarshalling request.imp[i].video.ext object.")
+ }
+
+ assert.Equal(t, "rewarded", videoExt.VideoType,
+ "Unexpected VideoType. Got %s. Expected %s", videoExt.VideoType, "rewarded")
+}
+
func TestOpenRTBEmptyResponse(t *testing.T) {
httpResp := &adapters.ResponseData{
StatusCode: http.StatusNoContent,
diff --git a/adapters/rubicon/rubicontest/supplemental/required-video-size-id.json b/adapters/rubicon/rubicontest/supplemental/required-video-size-id.json
new file mode 100644
index 00000000000..cf0a594e13c
--- /dev/null
+++ b/adapters/rubicon/rubicontest/supplemental/required-video-size-id.json
@@ -0,0 +1,31 @@
+{
+ "mockBidRequest": {
+ "id": "test-req-id",
+ "imp": [
+ {
+ "id": "test-imp-1",
+ "video": {
+ "w": 640,
+ "h": 480,
+ "linearity": 1
+ },
+ "ext": {
+ "bidder": {
+ "accountId": 1001,
+ "siteId":113932,
+ "zoneId":535510
+ }
+ }
+ }
+ ],
+ "site": {
+ "page": "prebid.org"
+ }
+ },
+ "expectedMakeRequestsErrors": [
+ {
+ "value": "imp[0].ext.bidder.rubicon.video.size_id must be defined for video impression",
+ "comparison": "literal"
+ }
+ ]
+}
diff --git a/adapters/smartrtb/smartrtb.go b/adapters/smartrtb/smartrtb.go
new file mode 100644
index 00000000000..5edaae6f289
--- /dev/null
+++ b/adapters/smartrtb/smartrtb.go
@@ -0,0 +1,189 @@
+package smartrtb
+
+import (
+ "encoding/json"
+ "fmt"
+ "net/http"
+ "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"
+)
+
+// Base adapter structure.
+type SmartRTBAdapter struct {
+ EndpointTemplate template.Template
+}
+
+// Bid request extension appended to downstream request.
+// PubID are non-empty iff request.{App,Site} or
+// request.{App,Site}.Publisher are nil, respectively.
+type bidRequestExt struct {
+ PubID string `json:"pub_id,omitempty"`
+ ZoneID string `json:"zone_id,omitempty"`
+ ForceBid bool `json:"force_bid,omitempty"`
+}
+
+// bidExt.CreativeType values.
+const (
+ creativeTypeBanner string = "BANNER"
+ creativeTypeVideo = "VIDEO"
+ creativeTypeNative = "NATIVE"
+ creativeTypeAudio = "AUDIO"
+)
+
+// Bid response extension from downstream.
+type bidExt struct {
+ CreativeType string `json:"format"`
+}
+
+func NewSmartRTBBidder(endpointTemplate string) adapters.Bidder {
+ template, err := template.New("endpointTemplate").Parse(endpointTemplate)
+ if err != nil {
+ glog.Fatal("Template URL error")
+ return nil
+ }
+ return &SmartRTBAdapter{EndpointTemplate: *template}
+}
+
+func (adapter *SmartRTBAdapter) buildEndpointURL(pubID string) (string, error) {
+ endpointParams := macros.EndpointTemplateParams{PublisherID: pubID}
+ return macros.ResolveMacros(adapter.EndpointTemplate, endpointParams)
+}
+
+func parseExtImp(dst *bidRequestExt, imp *openrtb.Imp) error {
+ var ext adapters.ExtImpBidder
+ if err := json.Unmarshal(imp.Ext, &ext); err != nil {
+ return adapters.BadInput(err.Error())
+ }
+
+ var src openrtb_ext.ExtImpSmartRTB
+ if err := json.Unmarshal(ext.Bidder, &src); err != nil {
+ return adapters.BadInput(err.Error())
+ }
+
+ if dst.PubID == "" {
+ dst.PubID = src.PubID
+ }
+
+ if src.ZoneID != "" {
+ imp.TagID = src.ZoneID
+ }
+ return nil
+}
+
+func (s *SmartRTBAdapter) MakeRequests(brq *openrtb.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
+ var imps []openrtb.Imp
+ var err error
+ ext := bidRequestExt{}
+ nrImps := len(brq.Imp)
+ errs := make([]error, 0, nrImps)
+
+ for i := 0; i < nrImps; i++ {
+ imp := brq.Imp[i]
+ if imp.Banner == nil && imp.Video == nil {
+ continue
+ }
+
+ err = parseExtImp(&ext, &imp)
+ if err != nil {
+ errs = append(errs, err)
+ continue
+ }
+
+ imps = append(imps, imp)
+ }
+
+ if len(imps) == 0 {
+ return nil, errs
+ }
+
+ if ext.PubID == "" {
+ return nil, append(errs, adapters.BadInput("Cannot infer publisher ID from bid ext"))
+ }
+
+ brq.Ext, err = json.Marshal(ext)
+ if err != nil {
+ return nil, append(errs, err)
+ }
+
+ brq.Imp = imps
+
+ rq, err := json.Marshal(brq)
+ if err != nil {
+ return nil, append(errs, err)
+ }
+
+ url, err := s.buildEndpointURL(ext.PubID)
+ if err != nil {
+ return nil, append(errs, err)
+ }
+
+ headers := http.Header{}
+ headers.Add("Content-Type", "application/json;charset=utf-8")
+ headers.Add("Accept", "application/json")
+ headers.Add("x-openrtb-version", "2.5")
+ return []*adapters.RequestData{{
+ Method: "POST",
+ Uri: url,
+ Body: rq,
+ Headers: headers,
+ }}, errs
+}
+
+func (s *SmartRTBAdapter) MakeBids(
+ brq *openrtb.BidRequest, drq *adapters.RequestData,
+ rs *adapters.ResponseData,
+) (*adapters.BidderResponse, []error) {
+ if rs.StatusCode == http.StatusNoContent {
+ return nil, nil
+ } else if rs.StatusCode == http.StatusBadRequest {
+ return nil, []error{adapters.BadInput("Invalid request.")}
+ } else if rs.StatusCode != http.StatusOK {
+ return nil, []error{&errortypes.BadServerResponse{
+ Message: fmt.Sprintf("Unexpected HTTP status %d.", rs.StatusCode),
+ }}
+ }
+
+ var brs openrtb.BidResponse
+ if err := json.Unmarshal(rs.Body, &brs); err != nil {
+ return nil, []error{err}
+ }
+
+ rv := adapters.NewBidderResponseWithBidsCapacity(5)
+ for _, seat := range brs.SeatBid {
+ for i := range seat.Bid {
+ var ext bidExt
+ if err := json.Unmarshal(seat.Bid[i].Ext, &ext); err != nil {
+ return nil, []error{&errortypes.BadServerResponse{
+ Message: "Invalid bid extension from endpoint.",
+ }}
+ }
+
+ var btype openrtb_ext.BidType
+ switch ext.CreativeType {
+ case creativeTypeBanner:
+ btype = openrtb_ext.BidTypeBanner
+ case creativeTypeVideo:
+ btype = openrtb_ext.BidTypeVideo
+ default:
+ return nil, []error{&errortypes.BadServerResponse{
+ Message: fmt.Sprintf("Unsupported creative type %s.",
+ ext.CreativeType),
+ }}
+ }
+
+ seat.Bid[i].Ext = nil
+
+ rv.Bids = append(rv.Bids, &adapters.TypedBid{
+ Bid: &seat.Bid[i],
+ BidType: btype,
+ })
+ }
+ }
+ return rv, nil
+}
diff --git a/adapters/smartrtb/smartrtb_test.go b/adapters/smartrtb/smartrtb_test.go
new file mode 100644
index 00000000000..3f76ed044a8
--- /dev/null
+++ b/adapters/smartrtb/smartrtb_test.go
@@ -0,0 +1,11 @@
+package smartrtb
+
+import (
+ "testing"
+
+ "github.com/prebid/prebid-server/adapters/adapterstest"
+)
+
+func TestJsonSamples(t *testing.T) {
+ adapterstest.RunJSONBidderTest(t, "smartrtbtest", NewSmartRTBBidder("http://market-east.smrtb.com/json/publisher/rtb?pubid=test"))
+}
diff --git a/adapters/smartrtb/smartrtbtest/exemplary/banner.json b/adapters/smartrtb/smartrtbtest/exemplary/banner.json
new file mode 100644
index 00000000000..436f6298a16
--- /dev/null
+++ b/adapters/smartrtb/smartrtbtest/exemplary/banner.json
@@ -0,0 +1,134 @@
+{
+ "mockBidRequest": {
+ "id": "abc",
+ "site": {
+ "page": "prebid.org"
+ },
+ "imp": [
+ {
+ "id": "imp123",
+ "banner": {
+ "format": [
+ {
+ "w": 300,
+ "h": 250
+ }
+ ],
+ "w": 300,
+ "h": 250
+ },
+ "ext": {
+ "bidder": {
+ "pub_id": "test",
+ "zone_id": "N4zTDq3PPEHBIODv7cXK",
+ "force_bid": true
+ }
+ }
+ }
+ ]
+ },
+
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "http://market-east.smrtb.com/json/publisher/rtb?pubid=test",
+ "body":{
+ "id": "abc",
+ "site": {
+ "page": "prebid.org"
+ },
+ "imp": [{
+ "id": "imp123",
+ "tagid": "N4zTDq3PPEHBIODv7cXK",
+ "banner": {
+ "format": [{
+ "w": 300,
+ "h": 250
+ }],
+ "w": 300,
+ "h": 250
+ },
+ "ext": {
+ "bidder": {
+ "pub_id": "test",
+ "zone_id": "N4zTDq3PPEHBIODv7cXK",
+ "force_bid": true
+ }
+ }
+ }],
+ "ext": {
+ "pub_id": "test"
+ }
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "abc",
+ "seatbid": [
+ {
+ "bid": [
+ {
+ "adm": "hi",
+ "crid": "test_banner_crid",
+ "cid": "test_cid",
+ "impid": "imp123",
+ "id": "1",
+ "price": 0.01,
+ "ext": {
+ "format": "BANNER"
+ }
+ }
+ ]
+ },
+ {
+ "bid": [
+ {
+ "adm": "",
+ "crid": "test_video_crid",
+ "cid": "test_cid",
+ "impid": "imp123",
+ "id": "2",
+ "price": 0.01,
+ "ext": {
+ "format": "VIDEO"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ ],
+
+ "expectedBidResponses": [
+ {
+ "currency": "USD",
+ "bids": [
+ {
+ "bid": {
+ "adm": "hi",
+ "crid": "test_banner_crid",
+ "cid": "test_cid",
+ "impid": "imp123",
+ "price": 0.01,
+ "id": "1"
+ },
+ "type": "banner"
+ },
+ {
+ "bid": {
+ "adm": "",
+ "crid": "test_video_crid",
+ "cid": "test_cid",
+ "impid": "imp123",
+ "price": 0.01,
+ "id": "2"
+ },
+ "type": "video"
+ }
+ ]
+ }
+ ]
+}
diff --git a/adapters/smartrtb/smartrtbtest/exemplary/video.json b/adapters/smartrtb/smartrtbtest/exemplary/video.json
new file mode 100644
index 00000000000..436f6298a16
--- /dev/null
+++ b/adapters/smartrtb/smartrtbtest/exemplary/video.json
@@ -0,0 +1,134 @@
+{
+ "mockBidRequest": {
+ "id": "abc",
+ "site": {
+ "page": "prebid.org"
+ },
+ "imp": [
+ {
+ "id": "imp123",
+ "banner": {
+ "format": [
+ {
+ "w": 300,
+ "h": 250
+ }
+ ],
+ "w": 300,
+ "h": 250
+ },
+ "ext": {
+ "bidder": {
+ "pub_id": "test",
+ "zone_id": "N4zTDq3PPEHBIODv7cXK",
+ "force_bid": true
+ }
+ }
+ }
+ ]
+ },
+
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "http://market-east.smrtb.com/json/publisher/rtb?pubid=test",
+ "body":{
+ "id": "abc",
+ "site": {
+ "page": "prebid.org"
+ },
+ "imp": [{
+ "id": "imp123",
+ "tagid": "N4zTDq3PPEHBIODv7cXK",
+ "banner": {
+ "format": [{
+ "w": 300,
+ "h": 250
+ }],
+ "w": 300,
+ "h": 250
+ },
+ "ext": {
+ "bidder": {
+ "pub_id": "test",
+ "zone_id": "N4zTDq3PPEHBIODv7cXK",
+ "force_bid": true
+ }
+ }
+ }],
+ "ext": {
+ "pub_id": "test"
+ }
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "abc",
+ "seatbid": [
+ {
+ "bid": [
+ {
+ "adm": "hi",
+ "crid": "test_banner_crid",
+ "cid": "test_cid",
+ "impid": "imp123",
+ "id": "1",
+ "price": 0.01,
+ "ext": {
+ "format": "BANNER"
+ }
+ }
+ ]
+ },
+ {
+ "bid": [
+ {
+ "adm": "",
+ "crid": "test_video_crid",
+ "cid": "test_cid",
+ "impid": "imp123",
+ "id": "2",
+ "price": 0.01,
+ "ext": {
+ "format": "VIDEO"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ ],
+
+ "expectedBidResponses": [
+ {
+ "currency": "USD",
+ "bids": [
+ {
+ "bid": {
+ "adm": "hi",
+ "crid": "test_banner_crid",
+ "cid": "test_cid",
+ "impid": "imp123",
+ "price": 0.01,
+ "id": "1"
+ },
+ "type": "banner"
+ },
+ {
+ "bid": {
+ "adm": "",
+ "crid": "test_video_crid",
+ "cid": "test_cid",
+ "impid": "imp123",
+ "price": 0.01,
+ "id": "2"
+ },
+ "type": "video"
+ }
+ ]
+ }
+ ]
+}
diff --git a/adapters/smartrtb/smartrtbtest/params/race/banner.json b/adapters/smartrtb/smartrtbtest/params/race/banner.json
new file mode 100644
index 00000000000..207a504539f
--- /dev/null
+++ b/adapters/smartrtb/smartrtbtest/params/race/banner.json
@@ -0,0 +1,5 @@
+{
+ "pub_id": "test",
+ "zone_id": "N4zTDq3PPEHBIODv7cXK",
+ "force_bid": true
+}
\ No newline at end of file
diff --git a/adapters/smartrtb/smartrtbtest/params/race/video.json b/adapters/smartrtb/smartrtbtest/params/race/video.json
new file mode 100644
index 00000000000..207a504539f
--- /dev/null
+++ b/adapters/smartrtb/smartrtbtest/params/race/video.json
@@ -0,0 +1,5 @@
+{
+ "pub_id": "test",
+ "zone_id": "N4zTDq3PPEHBIODv7cXK",
+ "force_bid": true
+}
\ No newline at end of file
diff --git a/adapters/smartrtb/smartrtbtest/supplemental/bad-bidder-ext.json b/adapters/smartrtb/smartrtbtest/supplemental/bad-bidder-ext.json
new file mode 100644
index 00000000000..b261415de4d
--- /dev/null
+++ b/adapters/smartrtb/smartrtbtest/supplemental/bad-bidder-ext.json
@@ -0,0 +1,31 @@
+{
+ "mockBidRequest": {
+ "id": "abc",
+ "site": {
+ "page": "prebid.org"
+ },
+ "imp": [
+ {
+ "id": "imp123",
+ "banner": {
+ "format": [
+ {
+ "w": 300,
+ "h": 250
+ }
+ ],
+ "w": 300,
+ "h": 250
+ },
+ "ext": null
+ }
+ ]
+ },
+
+ "expectedMakeRequestsErrors": [
+ {
+ "value": "unexpected end of JSON input",
+ "comparison": "literal"
+ }
+ ]
+}
diff --git a/adapters/smartrtb/smartrtbtest/supplemental/bad-imp-ext.json b/adapters/smartrtb/smartrtbtest/supplemental/bad-imp-ext.json
new file mode 100644
index 00000000000..1c0f57d2f34
--- /dev/null
+++ b/adapters/smartrtb/smartrtbtest/supplemental/bad-imp-ext.json
@@ -0,0 +1,32 @@
+{
+ "mockBidRequest": {
+ "id": "abc",
+ "site": {
+ "page": "prebid.org"
+ },
+ "publisher": { },
+ "imp": [
+ {
+ "id": "imp123",
+ "banner": {
+ "format": [
+ {
+ "w": 300,
+ "h": 250
+ }
+ ],
+ "w": 300,
+ "h": 250
+ },
+ "ext": null
+ }
+ ]
+ },
+
+ "expectedMakeRequestsErrors": [
+ {
+ "value": "unexpected end of JSON input",
+ "comparison": "literal"
+ }
+ ]
+}
diff --git a/adapters/smartrtb/smartrtbtest/supplemental/bad-pub-value-empty.json b/adapters/smartrtb/smartrtbtest/supplemental/bad-pub-value-empty.json
new file mode 100644
index 00000000000..aca21036b24
--- /dev/null
+++ b/adapters/smartrtb/smartrtbtest/supplemental/bad-pub-value-empty.json
@@ -0,0 +1,37 @@
+{
+ "mockBidRequest": {
+ "id": "abc",
+ "site": {
+ "page": "prebid.org"
+ },
+ "publisher": { },
+ "imp": [
+ {
+ "id": "imp123",
+ "banner": {
+ "format": [
+ {
+ "w": 300,
+ "h": 250
+ }
+ ],
+ "w": 300,
+ "h": 250
+ },
+ "ext": {
+ "bidder": {
+ "zone_id": "N4zTDq3PPEHBIODv7cXK",
+ "force_bid": true
+ }
+ }
+ }
+ ]
+ },
+
+ "expectedMakeRequestsErrors": [
+ {
+ "value": "Cannot infer publisher ID from bid ext",
+ "comparison": "literal"
+ }
+ ]
+}
diff --git a/adapters/smartrtb/smartrtbtest/supplemental/bad-pub-value.json b/adapters/smartrtb/smartrtbtest/supplemental/bad-pub-value.json
new file mode 100644
index 00000000000..93b45c747fd
--- /dev/null
+++ b/adapters/smartrtb/smartrtbtest/supplemental/bad-pub-value.json
@@ -0,0 +1,37 @@
+{
+ "mockBidRequest": {
+ "id": "abc",
+ "site": {
+ "page": "prebid.org"
+ },
+ "imp": [
+ {
+ "id": "imp123",
+ "banner": {
+ "format": [
+ {
+ "w": 300,
+ "h": 250
+ }
+ ],
+ "w": 300,
+ "h": 250
+ },
+ "ext": {
+ "bidder": {
+ "pub_id": 0,
+ "zone_id": "N4zTDq3PPEHBIODv7cXK",
+ "force_bid": true
+ }
+ }
+ }
+ ]
+ },
+
+ "expectedMakeRequestsErrors": [
+ {
+ "value": "json: cannot unmarshal number into Go struct field ExtImpSmartRTB.pub_id of type string",
+ "comparison": "literal"
+ }
+ ]
+}
diff --git a/adapters/smartrtb/smartrtbtest/supplemental/bad-request.json b/adapters/smartrtb/smartrtbtest/supplemental/bad-request.json
new file mode 100644
index 00000000000..cf03832ddff
--- /dev/null
+++ b/adapters/smartrtb/smartrtbtest/supplemental/bad-request.json
@@ -0,0 +1,70 @@
+{
+ "mockBidRequest": {
+ "id": "abc",
+ "imp": [
+ {
+ "id": "imp123",
+ "banner": {
+ "format": [
+ {
+ "w": 300,
+ "h": 250
+ }
+ ],
+ "w": 300,
+ "h": 250
+ },
+ "ext": {
+ "bidder": {
+ "pub_id": "test",
+ "zone_id": "fake",
+ "force_bid": false
+ }
+ }
+ }
+ ]
+ },
+
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "http://market-east.smrtb.com/json/publisher/rtb?pubid=test",
+ "body":{
+ "id": "abc",
+ "imp": [{
+ "id": "imp123",
+ "tagid": "fake",
+ "banner": {
+ "format": [{
+ "w": 300,
+ "h": 250
+ }],
+ "w": 300,
+ "h": 250
+ },
+ "ext": {
+ "bidder": {
+ "pub_id": "test",
+ "zone_id": "fake",
+ "force_bid": false
+ }
+ }
+ }],
+ "ext": {
+ "pub_id": "test"
+ }
+ }
+ },
+ "mockResponse": {
+ "status": 400
+ }
+ }
+ ],
+
+ "expectedMakeBidsErrors": [
+ {
+ "value": "Invalid request.",
+ "comparison": "literal"
+ }
+ ]
+}
diff --git a/adapters/smartrtb/smartrtbtest/supplemental/empty-imps.json b/adapters/smartrtb/smartrtbtest/supplemental/empty-imps.json
new file mode 100644
index 00000000000..a92add70825
--- /dev/null
+++ b/adapters/smartrtb/smartrtbtest/supplemental/empty-imps.json
@@ -0,0 +1,14 @@
+{
+ "mockBidRequest": {
+ "id": "abc",
+ "site": {
+ "page": "prebid.org"
+ },
+ "publisher": { },
+ "imp": [
+ {
+ "id": "imp123"
+ }
+ ]
+ }
+}
diff --git a/adapters/smartrtb/smartrtbtest/supplemental/invalid-bid-ext.json b/adapters/smartrtb/smartrtbtest/supplemental/invalid-bid-ext.json
new file mode 100644
index 00000000000..49527e1ecd4
--- /dev/null
+++ b/adapters/smartrtb/smartrtbtest/supplemental/invalid-bid-ext.json
@@ -0,0 +1,93 @@
+{
+ "mockBidRequest": {
+ "id": "abc",
+ "site": {
+ "page": "prebid.org"
+ },
+ "imp": [
+ {
+ "id": "imp123",
+ "banner": {
+ "format": [
+ {
+ "w": 300,
+ "h": 250
+ }
+ ],
+ "w": 300,
+ "h": 250
+ },
+ "ext": {
+ "bidder": {
+ "pub_id": "test",
+ "zone_id": "N4zTDq3PPEHBIODv7cXK",
+ "force_bid": true
+ }
+ }
+ }
+ ]
+ },
+
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "http://market-east.smrtb.com/json/publisher/rtb?pubid=test",
+ "body":{
+ "id": "abc",
+ "site": {
+ "page": "prebid.org"
+ },
+ "imp": [{
+ "id": "imp123",
+ "tagid": "N4zTDq3PPEHBIODv7cXK",
+ "banner": {
+ "format": [{
+ "w": 300,
+ "h": 250
+ }],
+ "w": 300,
+ "h": 250
+ },
+ "ext": {
+ "bidder": {
+ "pub_id": "test",
+ "zone_id": "N4zTDq3PPEHBIODv7cXK",
+ "force_bid": true
+ }
+ }
+ }],
+ "ext": {
+ "pub_id": "test"
+ }
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "abc",
+ "seatbid": [
+ {
+ "bid": [
+ {
+ "adm": "hi",
+ "crid": "test_banner_crid",
+ "cid": "test_cid",
+ "impid": "imp123",
+ "id": "1",
+ "price": 0.01,
+ "ext": "notvalidjsonhaha"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ ],
+ "expectedMakeBidsErrors": [
+ {
+ "value": "Invalid bid extension from endpoint.",
+ "comparison": "literal"
+ }
+ ]
+}
diff --git a/adapters/smartrtb/smartrtbtest/supplemental/invalid-bid-format.json b/adapters/smartrtb/smartrtbtest/supplemental/invalid-bid-format.json
new file mode 100644
index 00000000000..2f6bc07edb8
--- /dev/null
+++ b/adapters/smartrtb/smartrtbtest/supplemental/invalid-bid-format.json
@@ -0,0 +1,95 @@
+{
+ "mockBidRequest": {
+ "id": "abc",
+ "site": {
+ "page": "prebid.org"
+ },
+ "imp": [
+ {
+ "id": "imp123",
+ "banner": {
+ "format": [
+ {
+ "w": 300,
+ "h": 250
+ }
+ ],
+ "w": 300,
+ "h": 250
+ },
+ "ext": {
+ "bidder": {
+ "pub_id": "test",
+ "zone_id": "N4zTDq3PPEHBIODv7cXK",
+ "force_bid": true
+ }
+ }
+ }
+ ]
+ },
+
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "http://market-east.smrtb.com/json/publisher/rtb?pubid=test",
+ "body":{
+ "id": "abc",
+ "site": {
+ "page": "prebid.org"
+ },
+ "imp": [{
+ "id": "imp123",
+ "tagid": "N4zTDq3PPEHBIODv7cXK",
+ "banner": {
+ "format": [{
+ "w": 300,
+ "h": 250
+ }],
+ "w": 300,
+ "h": 250
+ },
+ "ext": {
+ "bidder": {
+ "pub_id": "test",
+ "zone_id": "N4zTDq3PPEHBIODv7cXK",
+ "force_bid": true
+ }
+ }
+ }],
+ "ext": {
+ "pub_id": "test"
+ }
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "abc",
+ "seatbid": [
+ {
+ "bid": [
+ {
+ "adm": "hi",
+ "crid": "test_banner_crid",
+ "cid": "test_cid",
+ "impid": "imp123",
+ "id": "1",
+ "price": 0.01,
+ "ext": {
+ "format": "ALIEN_FORMAT"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ ],
+ "expectedMakeBidsErrors": [
+ {
+ "value": "Unsupported creative type ALIEN_FORMAT.",
+ "comparison": "literal"
+ }
+ ]
+}
diff --git a/adapters/smartrtb/smartrtbtest/supplemental/invalid-bid-json.json b/adapters/smartrtb/smartrtbtest/supplemental/invalid-bid-json.json
new file mode 100644
index 00000000000..c56e7f21515
--- /dev/null
+++ b/adapters/smartrtb/smartrtbtest/supplemental/invalid-bid-json.json
@@ -0,0 +1,76 @@
+{
+ "mockBidRequest": {
+ "id": "abc",
+ "site": {
+ "page": "prebid.org"
+ },
+ "imp": [
+ {
+ "id": "imp123",
+ "banner": {
+ "format": [
+ {
+ "w": 300,
+ "h": 250
+ }
+ ],
+ "w": 300,
+ "h": 250
+ },
+ "ext": {
+ "bidder": {
+ "pub_id": "test",
+ "zone_id": "N4zTDq3PPEHBIODv7cXK",
+ "force_bid": true
+ }
+ }
+ }
+ ]
+ },
+
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "http://market-east.smrtb.com/json/publisher/rtb?pubid=test",
+ "body":{
+ "id": "abc",
+ "site": {
+ "page": "prebid.org"
+ },
+ "imp": [{
+ "id": "imp123",
+ "tagid": "N4zTDq3PPEHBIODv7cXK",
+ "banner": {
+ "format": [{
+ "w": 300,
+ "h": 250
+ }],
+ "w": 300,
+ "h": 250
+ },
+ "ext": {
+ "bidder": {
+ "pub_id": "test",
+ "zone_id": "N4zTDq3PPEHBIODv7cXK",
+ "force_bid": true
+ }
+ }
+ }],
+ "ext": {
+ "pub_id": "test"
+ }
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": "imnotyourfather"
+ }
+ }
+ ],
+ "expectedMakeBidsErrors": [
+ {
+ "value": "json: cannot unmarshal string into Go value of type openrtb.BidResponse",
+ "comparison": "literal"
+ }
+ ]
+}
diff --git a/adapters/smartrtb/smartrtbtest/supplemental/invalid-imp-ext.json b/adapters/smartrtb/smartrtbtest/supplemental/invalid-imp-ext.json
new file mode 100644
index 00000000000..13485f797ba
--- /dev/null
+++ b/adapters/smartrtb/smartrtbtest/supplemental/invalid-imp-ext.json
@@ -0,0 +1,32 @@
+{
+ "mockBidRequest": {
+ "id": "abc",
+ "site": {
+ "page": "prebid.org"
+ },
+ "publisher": { },
+ "imp": [
+ {
+ "id": "imp123",
+ "banner": {
+ "format": [
+ {
+ "w": 300,
+ "h": 250
+ }
+ ],
+ "w": 300,
+ "h": 250
+ },
+ "ext": "notjsontho"
+ }
+ ]
+ },
+
+ "expectedMakeRequestsErrors": [
+ {
+ "value": "json: cannot unmarshal string into Go value of type adapters.ExtImpBidder",
+ "comparison": "literal"
+ }
+ ]
+}
diff --git a/adapters/smartrtb/smartrtbtest/supplemental/nobid.json b/adapters/smartrtb/smartrtbtest/supplemental/nobid.json
new file mode 100644
index 00000000000..2733d8dba96
--- /dev/null
+++ b/adapters/smartrtb/smartrtbtest/supplemental/nobid.json
@@ -0,0 +1,69 @@
+{
+ "mockBidRequest": {
+ "id": "abc",
+ "site": {
+ "page": "prebid.org"
+ },
+ "imp": [
+ {
+ "id": "imp123",
+ "banner": {
+ "format": [
+ {
+ "w": 300,
+ "h": 250
+ }
+ ],
+ "w": 300,
+ "h": 250
+ },
+ "ext": {
+ "bidder": {
+ "pub_id": "test",
+ "zone_id": "N4zTDq3PPEHBIODv7cXKz",
+ "force_bid": false
+ }
+ }
+ }
+ ]
+ },
+
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "http://market-east.smrtb.com/json/publisher/rtb?pubid=test",
+ "body":{
+ "id": "abc",
+ "site": {
+ "page": "prebid.org"
+ },
+ "imp": [{
+ "id": "imp123",
+ "tagid": "N4zTDq3PPEHBIODv7cXKz",
+ "banner": {
+ "format": [{
+ "w": 300,
+ "h": 250
+ }],
+ "w": 300,
+ "h": 250
+ },
+ "ext": {
+ "bidder": {
+ "pub_id": "test",
+ "zone_id": "N4zTDq3PPEHBIODv7cXKz",
+ "force_bid": false
+ }
+ }
+ }],
+ "ext": {
+ "pub_id": "test"
+ }
+ }
+ },
+ "mockResponse": {
+ "status": 204
+ }
+ }
+ ]
+}
diff --git a/adapters/smartrtb/smartrtbtest/supplemental/non-http-ok.json b/adapters/smartrtb/smartrtbtest/supplemental/non-http-ok.json
new file mode 100644
index 00000000000..3acafadc62f
--- /dev/null
+++ b/adapters/smartrtb/smartrtbtest/supplemental/non-http-ok.json
@@ -0,0 +1,76 @@
+{
+ "mockBidRequest": {
+ "id": "abc",
+ "site": {
+ "page": "prebid.org"
+ },
+ "imp": [
+ {
+ "id": "imp123",
+ "banner": {
+ "format": [
+ {
+ "w": 300,
+ "h": 250
+ }
+ ],
+ "w": 300,
+ "h": 250
+ },
+ "ext": {
+ "bidder": {
+ "pub_id": "test",
+ "zone_id": "N4zTDq3PPEHBIODv7cXKz",
+ "force_bid": false
+ }
+ }
+ }
+ ]
+ },
+
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "http://market-east.smrtb.com/json/publisher/rtb?pubid=test",
+ "body":{
+ "id": "abc",
+ "site": {
+ "page": "prebid.org"
+ },
+ "imp": [{
+ "id": "imp123",
+ "tagid": "N4zTDq3PPEHBIODv7cXKz",
+ "banner": {
+ "format": [{
+ "w": 300,
+ "h": 250
+ }],
+ "w": 300,
+ "h": 250
+ },
+ "ext": {
+ "bidder": {
+ "pub_id": "test",
+ "zone_id": "N4zTDq3PPEHBIODv7cXKz",
+ "force_bid": false
+ }
+ }
+ }],
+ "ext": {
+ "pub_id": "test"
+ }
+ }
+ },
+ "mockResponse": {
+ "status": 500
+ }
+ }
+ ],
+
+ "expectedMakeBidsErrors": [
+ {
+ "value": "Unexpected HTTP status 500.",
+ "comparison": "literal"
+ }
+ ]
+}
diff --git a/adapters/smartrtb/usersync.go b/adapters/smartrtb/usersync.go
new file mode 100644
index 00000000000..2f7b1dc3339
--- /dev/null
+++ b/adapters/smartrtb/usersync.go
@@ -0,0 +1,12 @@
+package smartrtb
+
+import (
+ "text/template"
+
+ "github.com/prebid/prebid-server/adapters"
+ "github.com/prebid/prebid-server/usersync"
+)
+
+func NewSmartRTBSyncer(temp *template.Template) usersync.Usersyncer {
+ return adapters.NewSyncer("smartrtb", 0, temp, adapters.SyncTypeRedirect)
+}
diff --git a/adapters/smartrtb/usersync_test.go b/adapters/smartrtb/usersync_test.go
new file mode 100644
index 00000000000..ae3ae5dc007
--- /dev/null
+++ b/adapters/smartrtb/usersync_test.go
@@ -0,0 +1,20 @@
+package smartrtb
+
+import (
+ "testing"
+ "text/template"
+
+ "github.com/prebid/prebid-server/privacy"
+ "github.com/stretchr/testify/assert"
+)
+
+func TestSmartRTBSyncer(t *testing.T) {
+ temp := template.Must(template.New("sync-template").Parse("http://market-east.smrtb.com/sync/all?nid=smartrtb&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&url=localhost%2Fsetuid%3Fbidder%smartrtb%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24%7BUID%7D"))
+ syncer := NewSmartRTBSyncer(temp)
+ syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{})
+ assert.NoError(t, err)
+ assert.Equal(t, "http://market-east.smrtb.com/sync/all?nid=smartrtb&gdpr=&gdpr_consent=&url=localhost%2Fsetuid%3Fbidder%smartrtb%26gdpr%3D%26gdpr_consent%3D%26uid%3D%24%7BUID%7D", syncInfo.URL)
+ assert.Equal(t, "redirect", syncInfo.Type)
+ assert.EqualValues(t, 0, syncer.GDPRVendorID())
+ assert.Equal(t, false, syncInfo.SupportCORS)
+}
diff --git a/adapters/synacormedia/params_test.go b/adapters/synacormedia/params_test.go
index ffd891f4e84..a216818e382 100644
--- a/adapters/synacormedia/params_test.go
+++ b/adapters/synacormedia/params_test.go
@@ -40,9 +40,9 @@ func TestInvalidParams(t *testing.T) {
}
var validParams = []string{
- `{"seatId": "123"}`,
+ `{"seatId": "123", "tagId":"234"}`,
}
var invalidParams = []string{
- `{"seatId": 123}`,
+ `{"seatId": 123, "tagId":234}`,
}
diff --git a/adapters/synacormedia/synacormedia.go b/adapters/synacormedia/synacormedia.go
index ccb2798f8cf..2d913f026b4 100644
--- a/adapters/synacormedia/synacormedia.go
+++ b/adapters/synacormedia/synacormedia.go
@@ -20,6 +20,7 @@ type SynacorMediaAdapter struct {
type SyncEndpointTemplateParams struct {
SeatId string
+ TagId string
}
type ReqExt struct {
@@ -55,14 +56,23 @@ func (a *SynacorMediaAdapter) makeRequest(request *openrtb.BidRequest) (*adapter
var firstExtImp *openrtb_ext.ExtImpSynacormedia = nil
for _, imp := range request.Imp {
- validImp, err := getExtImpObj(&imp)
+ validExtImpObj, err := getExtImpObj(&imp) // getExtImpObj returns {seatId:"", tagId:""}
if err != nil {
errs = append(errs, err)
continue
}
+ // if the bid request is missing seatId or TagId then ignore it
+ if validExtImpObj.SeatId == "" || validExtImpObj.TagId == "" {
+ errs = append(errs, &errortypes.BadServerResponse{
+ Message: fmt.Sprintf("Invalid Impression"),
+ })
+ continue
+ }
+ // right here is where we need to take out the tagId and then add it to imp
+ imp.TagID = validExtImpObj.TagId
validImps = append(validImps, imp)
if firstExtImp == nil {
- firstExtImp = validImp
+ firstExtImp = validExtImpObj
}
}
@@ -72,11 +82,12 @@ func (a *SynacorMediaAdapter) makeRequest(request *openrtb.BidRequest) (*adapter
var err error
- if firstExtImp == nil || firstExtImp.SeatId == "" {
+ if firstExtImp == nil || firstExtImp.SeatId == "" || firstExtImp.TagId == "" {
return nil, append(errs, &errortypes.BadServerResponse{
- Message: fmt.Sprintf("Impression missing seat id"),
+ Message: fmt.Sprintf("Invalid Impression"),
})
}
+ // this is where the empty seatId is filled
re = &ReqExt{SeatId: firstExtImp.SeatId}
// create JSON Request Body
diff --git a/adapters/synacormedia/synacormediatest/exemplary/simple-banner.json b/adapters/synacormedia/synacormediatest/exemplary/simple-banner.json
index 013891b6fa8..944e6e549ab 100644
--- a/adapters/synacormedia/synacormediatest/exemplary/simple-banner.json
+++ b/adapters/synacormedia/synacormediatest/exemplary/simple-banner.json
@@ -14,7 +14,8 @@
},
"ext": {
"bidder": {
- "seatId": "1927"
+ "seatId": "prebid",
+ "tagId": "demo1"
}
}
}
@@ -24,15 +25,16 @@
"httpCalls": [
{
"expectedRequest": {
- "uri": "http://1927.technoratimedia.com/openrtb/bids/1927",
+ "uri": "http://prebid.technoratimedia.com/openrtb/bids/prebid",
"body": {
"id": "test-request-id",
"ext": {
- "seatId": "1927"
+ "seatId": "prebid"
},
"imp": [
{
"id":"test-imp-id",
+ "tagid": "demo1",
"banner": {
"format": [
{"w":300,"h":250}
@@ -40,7 +42,8 @@
},
"ext": {
"bidder": {
- "seatId": "1927"
+ "seatId": "prebid",
+ "tagId": "demo1"
}
}
}
diff --git a/adapters/synacormedia/synacormediatest/exemplary/simple-video.json b/adapters/synacormedia/synacormediatest/exemplary/simple-video.json
index f12556105db..2cddd5220f9 100644
--- a/adapters/synacormedia/synacormediatest/exemplary/simple-video.json
+++ b/adapters/synacormedia/synacormediatest/exemplary/simple-video.json
@@ -10,7 +10,6 @@
"imp": [
{
"id": "i3",
- "tagid": "3020",
"video": {
"w": 300,
"h": 250,
@@ -21,8 +20,9 @@
},
"metric": [],
"ext": {
- "bidder":{
- "seatId":"1927"
+ "bidder": {
+ "seatId":"prebid",
+ "tagId": "demo1"
}
}
}
@@ -31,7 +31,7 @@
"httpCalls": [
{
"expectedRequest": {
- "uri": "http://1927.technoratimedia.com/openrtb/bids/1927",
+ "uri": "http://prebid.technoratimedia.com/openrtb/bids/prebid",
"body": {
"id": "1",
"site": {
@@ -40,12 +40,12 @@
"publisher": {}
},
"ext": {
- "seatId": "1927"
+ "seatId": "prebid"
},
"imp": [
{
"id": "i3",
- "tagid": "3020",
+ "tagid": "demo1",
"video": {
"w": 300,
"h": 250,
@@ -56,7 +56,8 @@
},
"ext": {
"bidder":{
- "seatId":"1927"
+ "seatId":"prebid",
+ "tagId": "demo1"
}
}
}
diff --git a/adapters/synacormedia/synacormediatest/params/banner.json b/adapters/synacormedia/synacormediatest/params/banner.json
index d6f4e7e9641..bb55ddfc48c 100644
--- a/adapters/synacormedia/synacormediatest/params/banner.json
+++ b/adapters/synacormedia/synacormediatest/params/banner.json
@@ -1,3 +1,4 @@
{
- "seatId": "123"
+ "seatId": "123",
+ "tagId": "234"
}
diff --git a/adapters/synacormedia/synacormediatest/params/video.json b/adapters/synacormedia/synacormediatest/params/video.json
index d6f4e7e9641..bb55ddfc48c 100644
--- a/adapters/synacormedia/synacormediatest/params/video.json
+++ b/adapters/synacormedia/synacormediatest/params/video.json
@@ -1,3 +1,4 @@
{
- "seatId": "123"
+ "seatId": "123",
+ "tagId": "234"
}
diff --git a/adapters/synacormedia/synacormediatest/supplemental/audio_response.json b/adapters/synacormedia/synacormediatest/supplemental/audio_response.json
index 172a81efa85..752d610aa72 100644
--- a/adapters/synacormedia/synacormediatest/supplemental/audio_response.json
+++ b/adapters/synacormedia/synacormediatest/supplemental/audio_response.json
@@ -9,7 +9,8 @@
},
"ext": {
"bidder": {
- "seatId": "1927"
+ "seatId": "prebid",
+ "tagId": "demo1"
}
}
}
@@ -19,21 +20,23 @@
"httpCalls": [
{
"expectedRequest": {
- "uri": "http://1927.technoratimedia.com/openrtb/bids/1927",
+ "uri": "http://prebid.technoratimedia.com/openrtb/bids/prebid",
"body": {
"id": "test-request-id",
"ext": {
- "seatId": "1927"
+ "seatId": "prebid"
},
"imp": [
{
"id":"test-imp-id",
+ "tagid": "demo1",
"audio": {
"mimes": ["video/mp4"]
},
"ext": {
"bidder": {
- "seatId": "1927"
+ "seatId": "prebid",
+ "tagId": "demo1"
}
}
}
diff --git a/adapters/synacormedia/synacormediatest/supplemental/bad_response.json b/adapters/synacormedia/synacormediatest/supplemental/bad_response.json
index 0893598bd1d..8e8b9a4d944 100644
--- a/adapters/synacormedia/synacormediatest/supplemental/bad_response.json
+++ b/adapters/synacormedia/synacormediatest/supplemental/bad_response.json
@@ -18,7 +18,8 @@
},
"ext": {
"bidder": {
- "seatId": "1927"
+ "seatId": "prebid",
+ "tagId": "demo1"
}
}
}
@@ -28,15 +29,16 @@
"httpCalls": [
{
"expectedRequest": {
- "uri": "http://1927.technoratimedia.com/openrtb/bids/1927",
+ "uri": "http://prebid.technoratimedia.com/openrtb/bids/prebid",
"body": {
"id": "test-request-id",
"ext": {
- "seatId": "1927"
+ "seatId": "prebid"
},
"imp": [
{
"id":"test-imp-id",
+ "tagid": "demo1",
"banner": {
"format": [
{"w":300,"h":250},
@@ -45,7 +47,8 @@
},
"ext": {
"bidder": {
- "seatId": "1927"
+ "seatId": "prebid",
+ "tagId": "demo1"
}
}
}
diff --git a/adapters/synacormedia/synacormediatest/supplemental/bad_seat_id.json b/adapters/synacormedia/synacormediatest/supplemental/bad_seat_id.json
index bb144f1c6db..00dd2c23707 100644
--- a/adapters/synacormedia/synacormediatest/supplemental/bad_seat_id.json
+++ b/adapters/synacormedia/synacormediatest/supplemental/bad_seat_id.json
@@ -14,7 +14,8 @@
},
"ext": {
"bidder": {
- "seatId": 1927
+ "seatId": 1927,
+ "tagId": "demo1"
}
}
}
diff --git a/adapters/synacormedia/synacormediatest/supplemental/missing_seat_id.json b/adapters/synacormedia/synacormediatest/supplemental/missing_seat_id.json
index a085b6e64f9..b85b88e4189 100644
--- a/adapters/synacormedia/synacormediatest/supplemental/missing_seat_id.json
+++ b/adapters/synacormedia/synacormediatest/supplemental/missing_seat_id.json
@@ -14,6 +14,7 @@
},
"ext": {
"bidder": {
+ "tagId": "demo1"
}
}
}
@@ -22,7 +23,7 @@
"expectedMakeRequestsErrors": [
{
- "value": "Impression missing seat id",
+ "value": "Invalid Impression",
"comparison": "literal"
}
]
diff --git a/adapters/synacormedia/synacormediatest/supplemental/missing_tag_id.json b/adapters/synacormedia/synacormediatest/supplemental/missing_tag_id.json
new file mode 100644
index 00000000000..2e1ef6ada65
--- /dev/null
+++ b/adapters/synacormedia/synacormediatest/supplemental/missing_tag_id.json
@@ -0,0 +1,30 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "format": [
+ {
+ "w": 300,
+ "h": 250
+ }
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "seatId": "prebid"
+ }
+ }
+ }
+ ]
+ },
+
+ "expectedMakeRequestsErrors": [
+ {
+ "value": "Invalid Impression",
+ "comparison": "literal"
+ }
+ ]
+}
diff --git a/adapters/synacormedia/synacormediatest/supplemental/native_response.json b/adapters/synacormedia/synacormediatest/supplemental/native_response.json
index 89742d6e0df..1428ac1ccd3 100644
--- a/adapters/synacormedia/synacormediatest/supplemental/native_response.json
+++ b/adapters/synacormedia/synacormediatest/supplemental/native_response.json
@@ -9,7 +9,8 @@
},
"ext": {
"bidder": {
- "seatId": "1927"
+ "seatId": "prebid",
+ "tagId": "demo1"
}
}
}
@@ -19,21 +20,23 @@
"httpCalls": [
{
"expectedRequest": {
- "uri": "http://1927.technoratimedia.com/openrtb/bids/1927",
+ "uri": "http://prebid.technoratimedia.com/openrtb/bids/prebid",
"body": {
"id": "test-request-id",
"ext": {
- "seatId": "1927"
+ "seatId": "prebid"
},
"imp": [
{
"id":"test-imp-id",
+ "tagid": "demo1",
"native": {
"request": ""
},
"ext": {
"bidder": {
- "seatId": "1927"
+ "seatId": "prebid",
+ "tagId": "demo1"
}
}
}
diff --git a/adapters/synacormedia/synacormediatest/supplemental/one_bad_ext.json b/adapters/synacormedia/synacormediatest/supplemental/one_bad_ext.json
new file mode 100644
index 00000000000..5749aadba98
--- /dev/null
+++ b/adapters/synacormedia/synacormediatest/supplemental/one_bad_ext.json
@@ -0,0 +1,136 @@
+{
+ "mockBidRequest": {
+ "id": "test-request-id",
+ "imp": [
+ {
+ "id": "test-imp-bad",
+ "banner": {
+ "format": [
+ {
+ "w": 300,
+ "h": 250
+ }
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "seatId": "",
+ "tagId": ""
+ }
+ }
+ },
+ {
+ "id": "test-imp-id",
+ "banner": {
+ "format": [
+ {
+ "w": 300,
+ "h": 250
+ }
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "seatId": "prebid",
+ "tagId": "demo1"
+ }
+ }
+ }
+ ]
+ },
+
+ "httpCalls": [
+ {
+ "expectedRequest": {
+ "uri": "http://prebid.technoratimedia.com/openrtb/bids/prebid",
+ "body": {
+ "id": "test-request-id",
+ "ext": {
+ "seatId": "prebid"
+ },
+ "imp": [
+ {
+ "id":"test-imp-id",
+ "tagid": "demo1",
+ "banner": {
+ "format": [
+ {"w":300,"h":250}
+ ]
+ },
+ "ext": {
+ "bidder": {
+ "seatId": "prebid",
+ "tagId": "demo1"
+ }
+ }
+ }
+ ]
+ }
+ },
+ "mockResponse": {
+ "status": 200,
+ "body": {
+ "id": "1",
+ "seatbid": [
+ {
+ "bid": [
+ {
+ "id": "test-request-id",
+ "impid": "test-imp-id",
+ "price": 2.69,
+ "adomain": [
+ "psacentral.org"
+ ],
+ "cid": "mock-crid",
+ "crid": "mock-cid",
+ "ext": {
+ "prebid": {
+ "type": "banner"
+ }
+ }
+ }
+ ],
+ "seat": "synacormedia"
+ }
+ ],
+ "ext": {
+ "responsetimemillis": {
+ "synacormedia": 339
+ }
+ }
+ }
+ }
+ }
+ ],
+ "expectedBidResponses": [
+ {
+ "currency": "USD",
+ "bids": [
+ {
+ "bid": {
+ "adomain": [
+ "psacentral.org"
+ ],
+ "cid": "mock-crid",
+ "crid": "mock-cid",
+ "ext": {
+ "prebid": {
+ "type": "banner"
+ }
+ },
+ "id": "test-request-id",
+ "impid": "test-imp-id",
+ "price": 2.69
+ },
+ "type": "banner"
+ }
+ ]
+ }
+ ],
+ "expectedMakeRequestsErrors": [
+ {
+ "value": "Invalid Impression",
+ "comparison": "literal"
+ }
+ ]
+}
diff --git a/adapters/synacormedia/synacormediatest/supplemental/status_204.json b/adapters/synacormedia/synacormediatest/supplemental/status_204.json
index f53ff1ec918..76f97f9cdfa 100644
--- a/adapters/synacormedia/synacormediatest/supplemental/status_204.json
+++ b/adapters/synacormedia/synacormediatest/supplemental/status_204.json
@@ -18,7 +18,8 @@
},
"ext": {
"bidder": {
- "seatId": "1927"
+ "seatId": "prebid",
+ "tagId": "demo1"
}
}
}
@@ -28,15 +29,16 @@
"httpCalls": [
{
"expectedRequest": {
- "uri": "http://1927.technoratimedia.com/openrtb/bids/1927",
+ "uri": "http://prebid.technoratimedia.com/openrtb/bids/prebid",
"body": {
"id": "test-request-id",
"ext": {
- "seatId": "1927"
+ "seatId": "prebid"
},
"imp": [
{
"id":"test-imp-id",
+ "tagid": "demo1",
"banner": {
"format": [
{"w":300,"h":250},
@@ -45,7 +47,8 @@
},
"ext": {
"bidder": {
- "seatId": "1927"
+ "seatId": "prebid",
+ "tagId": "demo1"
}
}
}
diff --git a/adapters/synacormedia/synacormediatest/supplemental/status_400.json b/adapters/synacormedia/synacormediatest/supplemental/status_400.json
index a0667658e1d..1bb2cf6fa45 100644
--- a/adapters/synacormedia/synacormediatest/supplemental/status_400.json
+++ b/adapters/synacormedia/synacormediatest/supplemental/status_400.json
@@ -18,7 +18,8 @@
},
"ext": {
"bidder": {
- "seatId": "1927"
+ "seatId": "prebid",
+ "tagId": "demo1"
}
}
}
@@ -28,15 +29,16 @@
"httpCalls": [
{
"expectedRequest": {
- "uri": "http://1927.technoratimedia.com/openrtb/bids/1927",
+ "uri": "http://prebid.technoratimedia.com/openrtb/bids/prebid",
"body": {
"id": "test-request-id",
"ext": {
- "seatId": "1927"
+ "seatId": "prebid"
},
"imp": [
{
"id":"test-imp-id",
+ "tagid": "demo1",
"banner": {
"format": [
{"w":300,"h":250},
@@ -45,7 +47,8 @@
},
"ext": {
"bidder": {
- "seatId": "1927"
+ "seatId": "prebid",
+ "tagId": "demo1"
}
}
}
diff --git a/adapters/synacormedia/synacormediatest/supplemental/status_500.json b/adapters/synacormedia/synacormediatest/supplemental/status_500.json
index 125829c2328..37ca398e59e 100644
--- a/adapters/synacormedia/synacormediatest/supplemental/status_500.json
+++ b/adapters/synacormedia/synacormediatest/supplemental/status_500.json
@@ -18,7 +18,8 @@
},
"ext": {
"bidder": {
- "seatId": "1927"
+ "seatId": "prebid",
+ "tagId": "demo1"
}
}
}
@@ -28,15 +29,16 @@
"httpCalls": [
{
"expectedRequest": {
- "uri": "http://1927.technoratimedia.com/openrtb/bids/1927",
+ "uri": "http://prebid.technoratimedia.com/openrtb/bids/prebid",
"body": {
"id": "test-request-id",
"ext": {
- "seatId": "1927"
+ "seatId": "prebid"
},
"imp": [
{
"id":"test-imp-id",
+ "tagid": "demo1",
"banner": {
"format": [
{"w":300,"h":250},
@@ -45,7 +47,8 @@
},
"ext": {
"bidder": {
- "seatId": "1927"
+ "seatId": "prebid",
+ "tagId": "demo1"
}
}
}
diff --git a/adapters/triplelift/usersync_test.go b/adapters/triplelift/usersync_test.go
index b4bc845915b..1731b22dffb 100644
--- a/adapters/triplelift/usersync_test.go
+++ b/adapters/triplelift/usersync_test.go
@@ -9,7 +9,7 @@ import (
)
func TestTripleliftSyncer(t *testing.T) {
- syncURL := "//eb2.3lift.com/getuid?gdpr={{.GDPR}}&cmp_cs={{.GDPRConsent}}&redir=https%3A%2F%2Feb2.3lift.com%2Fsetuid%3Fbidder%3Dtriplelift%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID"
+ syncURL := "//eb2.3lift.com/getuid?gdpr={{.GDPR}}&cmp_cs={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redir=https%3A%2F%2Feb2.3lift.com%2Fsetuid%3Fbidder%3Dtriplelift%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID"
syncURLTemplate := template.Must(
template.New("sync-template").Parse(syncURL),
)
@@ -18,7 +18,7 @@ func TestTripleliftSyncer(t *testing.T) {
syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{})
assert.NoError(t, err)
- assert.Equal(t, "//eb2.3lift.com/getuid?gdpr=&cmp_cs=&redir=https%3A%2F%2Feb2.3lift.com%2Fsetuid%3Fbidder%3Dtriplelift%26gdpr%3D%26gdpr_consent%3D%26uid%3D%24UID", syncInfo.URL)
+ assert.Equal(t, "//eb2.3lift.com/getuid?gdpr=&cmp_cs=&us_privacy=&redir=https%3A%2F%2Feb2.3lift.com%2Fsetuid%3Fbidder%3Dtriplelift%26gdpr%3D%26gdpr_consent%3D%26uid%3D%24UID", syncInfo.URL)
assert.Equal(t, "redirect", syncInfo.Type)
assert.EqualValues(t, 28, syncer.GDPRVendorID())
assert.Equal(t, false, syncInfo.SupportCORS)
diff --git a/adapters/triplelift_native/usersync_test.go b/adapters/triplelift_native/usersync_test.go
index 2fb66c2bd2a..df0757edc9f 100644
--- a/adapters/triplelift_native/usersync_test.go
+++ b/adapters/triplelift_native/usersync_test.go
@@ -9,7 +9,7 @@ import (
)
func TestTripleliftSyncer(t *testing.T) {
- syncURL := "//eb2.3lift.com/getuid?gdpr={{.GDPR}}&cmp_cs={{.GDPRConsent}}&redir=https%3A%2F%2Feb2.3lift.com%2Fsetuid%3Fbidder%3Dtriplelift%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID"
+ syncURL := "//eb2.3lift.com/getuid?gdpr={{.GDPR}}&cmp_cs={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redir=https%3A%2F%2Feb2.3lift.com%2Fsetuid%3Fbidder%3Dtriplelift%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID"
syncURLTemplate := template.Must(
template.New("sync-template").Parse(syncURL),
)
@@ -18,7 +18,7 @@ func TestTripleliftSyncer(t *testing.T) {
syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{})
assert.NoError(t, err)
- assert.Equal(t, "//eb2.3lift.com/getuid?gdpr=&cmp_cs=&redir=https%3A%2F%2Feb2.3lift.com%2Fsetuid%3Fbidder%3Dtriplelift%26gdpr%3D%26gdpr_consent%3D%26uid%3D%24UID", syncInfo.URL)
+ assert.Equal(t, "//eb2.3lift.com/getuid?gdpr=&cmp_cs=&us_privacy=&redir=https%3A%2F%2Feb2.3lift.com%2Fsetuid%3Fbidder%3Dtriplelift%26gdpr%3D%26gdpr_consent%3D%26uid%3D%24UID", syncInfo.URL)
assert.Equal(t, "redirect", syncInfo.Type)
assert.EqualValues(t, 28, syncer.GDPRVendorID())
assert.Equal(t, false, syncInfo.SupportCORS)
diff --git a/adapters/ucfunnel/params_test.go b/adapters/ucfunnel/params_test.go
index 7be1e26e4ce..94c20cfddad 100644
--- a/adapters/ucfunnel/params_test.go
+++ b/adapters/ucfunnel/params_test.go
@@ -32,7 +32,7 @@ func TestInvalidParams(t *testing.T) {
}
for _, invalidParam := range invalidParams {
- if err := validator.Validate(openrtb_ext.BidderUcfunnel, json.RawMessage(invalidParam)); err == nil {
+ if err := validator.Validate(openrtb_ext.BidderUcfunnel, json.RawMessage(invalidParam)); err != nil {
t.Errorf("Schema allowed unexpected params: %s", invalidParam)
}
}
diff --git a/adapters/ucfunnel/ucfunnel.go b/adapters/ucfunnel/ucfunnel.go
index 9c7cd4845d4..e7bb4f97817 100644
--- a/adapters/ucfunnel/ucfunnel.go
+++ b/adapters/ucfunnel/ucfunnel.go
@@ -11,20 +11,12 @@ import (
)
type UcfunnelAdapter struct {
- http *adapters.HTTPAdapter
- URI string
-}
-
-func NewUcfunnelAdapter(config *adapters.HTTPAdapterConfig, endpoint string) *UcfunnelAdapter {
- return NewUcfunnelBidder(adapters.NewHTTPAdapter(config).Client, endpoint)
+ URI string
}
func NewUcfunnelBidder(client *http.Client, endpoint string) *UcfunnelAdapter {
- clientAdapter := &adapters.HTTPAdapter{Client: client}
return &UcfunnelAdapter{
- http: clientAdapter,
- URI: endpoint,
- }
+ URI: endpoint}
}
func (a *UcfunnelAdapter) Name() string {
@@ -67,11 +59,13 @@ func (a *UcfunnelAdapter) MakeBids(internalRequest *openrtb.BidRequest, external
for _, sb := range bidResp.SeatBid {
for i := range sb.Bid {
bidType := getBidType(bidReq, sb.Bid[i].ImpID)
- b := &adapters.TypedBid{
- Bid: &sb.Bid[i],
- BidType: bidType,
+ if (bidType == openrtb_ext.BidTypeBanner) || (bidType == openrtb_ext.BidTypeVideo) {
+ b := &adapters.TypedBid{
+ Bid: &sb.Bid[i],
+ BidType: bidType,
+ }
+ bidResponse.Bids = append(bidResponse.Bids, b)
}
- bidResponse.Bids = append(bidResponse.Bids, b)
}
}
return bidResponse, errs
@@ -99,7 +93,7 @@ func (a *UcfunnelAdapter) MakeRequests(request *openrtb.BidRequest, reqInfo *ada
headers := http.Header{}
headers.Add("Content-Type", "application/json")
- uri := a.URI + partnerId + "/request"
+ uri := a.URI + "/" + partnerId + "/request"
return []*adapters.RequestData{{
Method: "POST",
Uri: uri,
@@ -114,14 +108,11 @@ func getPartnerId(request *openrtb.BidRequest) string {
if err != nil {
return ""
}
- return ext.Bidder.PartnerId
-}
+ if len(ext.Bidder.PartnerId) == 0 || len(ext.Bidder.AdUnitId) == 0 {
+ return ""
+ }
-func AddHeadersToRequest() http.Header {
- headers := http.Header{}
- headers.Add("Content-Type", "application/json;charset=utf-8")
- headers.Add("Accept", "application/json")
- return headers
+ return ext.Bidder.PartnerId
}
func getBidType(bidReq openrtb.BidRequest, impid string) openrtb_ext.BidType {
@@ -131,10 +122,14 @@ func getBidType(bidReq openrtb.BidRequest, impid string) openrtb_ext.BidType {
return openrtb_ext.BidTypeBanner
} else if bidReq.Imp[i].Video != nil {
return openrtb_ext.BidTypeVideo
+ } else if bidReq.Imp[i].Audio != nil {
+ return openrtb_ext.BidTypeAudio
+ } else if bidReq.Imp[i].Native != nil {
+ return openrtb_ext.BidTypeNative
}
}
}
- return openrtb_ext.BidTypeBanner
+ return openrtb_ext.BidTypeNative
}
type ExtBidderUcfunnel struct {
diff --git a/adapters/ucfunnel/ucfunnel_test.go b/adapters/ucfunnel/ucfunnel_test.go
index f4e8b1befab..6fc369fa3c7 100644
--- a/adapters/ucfunnel/ucfunnel_test.go
+++ b/adapters/ucfunnel/ucfunnel_test.go
@@ -13,29 +13,13 @@ func TestJsonSamples(t *testing.T) {
adapterstest.RunJSONBidderTest(t, "ucfunneltest", NewUcfunnelBidder(nil, "http://127.0.0.1:8081/tmp12.json"))
}
-func TestAddHeadersToRequest(t *testing.T) {
- header := AddHeadersToRequest()
-
- if header == nil {
- t.Errorf("actual = %v expected != %v", nil, nil)
- }
-
- if header.Get("Content-Type") != "application/json;charset=utf-8" {
- t.Errorf("actual = %s expected != %v", header.Get("Content-Type"), nil)
- }
-
- if header.Get("Accept") != "application/json" {
- t.Errorf("actual = %s expected != %v", header.Get("Accept"), nil)
- }
-}
-
func TestUcfunnelAdapterNames(t *testing.T) {
- adapter := NewUcfunnelAdapter(adapters.DefaultHTTPAdapterConfig, "http://localhost/bid")
+ adapter := NewUcfunnelBidder(nil, "http://localhost/bid")
adapterstest.VerifyStringValue(adapter.Name(), "ucfunnel", t)
}
func TestSkipNoCookies(t *testing.T) {
- adapter := NewUcfunnelAdapter(adapters.DefaultHTTPAdapterConfig, "http://localhost/bid")
+ adapter := NewUcfunnelBidder(nil, "http://localhost/bid")
status := adapter.SkipNoCookies()
if status != false {
t.Errorf("actual = %t expected != %t", status, false)
@@ -53,23 +37,41 @@ func TestMakeRequests(t *testing.T) {
Video: &openrtb.Video{},
}
- internalRequest := openrtb.BidRequest{Imp: []openrtb.Imp{imp, imp2}}
- adapter := NewUcfunnelAdapter(adapters.DefaultHTTPAdapterConfig, "http://localhost/bid")
+ imp3 := openrtb.Imp{
+ ID: "1236",
+ Audio: &openrtb.Audio{},
+ }
+
+ imp4 := openrtb.Imp{
+ ID: "1237",
+ Native: &openrtb.Native{},
+ }
+ imp5 := openrtb.Imp{
+ ID: "1237",
+ Native: &openrtb.Native{},
+ }
+ internalRequest := openrtb.BidRequest{Imp: []openrtb.Imp{imp, imp2, imp3, imp4, imp5}}
+ adapter := NewUcfunnelBidder(nil, "http://localhost/bid")
RequestData, err := adapter.MakeRequests(&internalRequest, nil)
internalRequest.Imp[0].Ext = []byte(`{"bidder": {"adunitid": "ad-488663D474E44841E8A293379892348","partnerid": "par-7E6D2DB9A8922AB07B44A444D2BA67"}}`)
internalRequest.Imp[1].Ext = []byte(`{"bidder": {"adunitid": "ad-488663D474E44841E8A293379892348","partnerid": "par-7E6D2DB9A8922AB07B44A444D2BA67"}}`)
+ internalRequest.Imp[2].Ext = []byte(`{"bidder": {"adunitid": "ad-488663D474E44841E8A293379892348","partnerid": "par-7E6D2DB9A8922AB07B44A444D2BA67"}}`)
+ internalRequest.Imp[3].Ext = []byte(`{"bidder": {"adunitid": "ad-488663D474E44841E8A293379892348","partnerid": "par-7E6D2DB9A8922AB07B44A444D2BA67"}}`)
+ internalRequest.Imp[4].Ext = []byte(`{"bidder": {"adunitid": "aa","partnerid": ""}}`)
- adapter = NewUcfunnelAdapter(adapters.DefaultHTTPAdapterConfig, "http://localhost/bid")
+ adapter = NewUcfunnelBidder(nil, "http://localhost/bid")
RequestData, err = adapter.MakeRequests(&internalRequest, nil)
adapterstest.VerifyStringValue(RequestData[0].Method, "POST", t)
- adapterstest.VerifyStringValue(RequestData[0].Uri, adapter.URI+"par-7E6D2DB9A8922AB07B44A444D2BA67/request", t)
+ adapterstest.VerifyStringValue(RequestData[0].Uri, adapter.URI+"/par-7E6D2DB9A8922AB07B44A444D2BA67/request", t)
- mockResponse200 := adapters.ResponseData{StatusCode: 200, Body: json.RawMessage(`{"seatbid":[{"bid":[{"impid":"1234"}]},{"bid":[{"impid":"1235"}]}]}`)}
+ mockResponse200 := adapters.ResponseData{StatusCode: 200, Body: json.RawMessage(`{"seatbid": [{"bid": [{"impid": "1234"}]},{"bid": [{"impid": "1235"}]},{"bid": [{"impid": "1236"}]},{"bid": [{"impid": "1237"}]}]}`)}
mockResponse203 := adapters.ResponseData{StatusCode: 203, Body: json.RawMessage(`{"seatbid":[{"bid":[{"impid":"1234"}]},{"bid":[{"impid":"1235"}]}]}`)}
mockResponse204 := adapters.ResponseData{StatusCode: 204, Body: json.RawMessage(`{"seatbid":[{"bid":[{"impid":"1234"}]},{"bid":[{"impid":"1235"}]}]}`)}
mockResponse400 := adapters.ResponseData{StatusCode: 400, Body: json.RawMessage(`{"seatbid":[{"bid":[{"impid":"1234"}]},{"bid":[{"impid":"1235"}]}]}`)}
+ mockResponseError := adapters.ResponseData{StatusCode: 200, Body: json.RawMessage(`{"seatbid":[{"bid":[{"impid":"1236"}]},{"bid":[{"impid":"1237"}]}`)}
+
BidderResponse200, err := adapter.MakeBids(&internalRequest, RequestData[0], &mockResponse200)
if BidderResponse200 != nil && err != nil {
t.Errorf("actual = %t expected == %v", err, nil)
@@ -87,4 +89,8 @@ func TestMakeRequests(t *testing.T) {
t.Errorf("actual = %t expected != %v", err, nil)
}
+ BidderResponseBodyError, err := adapter.MakeBids(&internalRequest, RequestData[0], &mockResponseError)
+ if BidderResponseBodyError == nil && err == nil {
+ t.Errorf("actual = %t expected != %v", err, nil)
+ }
}
diff --git a/adapters/unruly/usersync_test.go b/adapters/unruly/usersync_test.go
index 8db8f75059e..bdab254f370 100644
--- a/adapters/unruly/usersync_test.go
+++ b/adapters/unruly/usersync_test.go
@@ -5,12 +5,13 @@ import (
"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 TestUnrulySyncer(t *testing.T) {
- syncURL := "//unrulymedia.com/pixel?redir=external.com%2Fsetuid%3Fbidder%3Dunruly%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID"
+ syncURL := "https://usermatch.targeting.unrulymedia.com/pbsync?gdpr={{.GDPR}}&consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&rurl=%2Fsetuid%3Fbidder%3Dunruly%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID"
syncURLTemplate := template.Must(
template.New("sync-template").Parse(syncURL),
)
@@ -18,12 +19,16 @@ func TestUnrulySyncer(t *testing.T) {
syncer := NewUnrulySyncer(syncURLTemplate)
syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{
GDPR: gdpr.Policy{
- Signal: "0",
+ Signal: "A",
+ Consent: "B",
+ },
+ CCPA: ccpa.Policy{
+ Value: "C",
},
})
assert.NoError(t, err)
- assert.Equal(t, "//unrulymedia.com/pixel?redir=external.com%2Fsetuid%3Fbidder%3Dunruly%26gdpr%3D0%26gdpr_consent%3D%26uid%3D%24UID", syncInfo.URL)
+ assert.Equal(t, "https://usermatch.targeting.unrulymedia.com/pbsync?gdpr=A&consent=B&us_privacy=C&rurl=%2Fsetuid%3Fbidder%3Dunruly%26gdpr%3DA%26gdpr_consent%3DB%26uid%3D%24UID", syncInfo.URL)
assert.Equal(t, "iframe", syncInfo.Type)
assert.EqualValues(t, 162, syncer.GDPRVendorID())
assert.Equal(t, false, syncInfo.SupportCORS)
diff --git a/adapters/visx/usersync_test.go b/adapters/visx/usersync_test.go
index 9133c5dfcfe..01e80e644c5 100644
--- a/adapters/visx/usersync_test.go
+++ b/adapters/visx/usersync_test.go
@@ -5,12 +5,13 @@ import (
"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 TestVisxSyncer(t *testing.T) {
- syncURL := "//not_localhost/synclocalhost%2Fsetuid%3Fbidder%3Dvisx%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24%7BUUID%7D"
+ syncURL := "https://t.visx.net/s2s_sync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redir=%2Fsetuid%3Fbidder%3Dvisx%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24%7BUUID%7D"
syncURLTemplate := template.Must(
template.New("sync-template").Parse(syncURL),
)
@@ -18,12 +19,16 @@ func TestVisxSyncer(t *testing.T) {
syncer := NewVisxSyncer(syncURLTemplate)
syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{
GDPR: gdpr.Policy{
- Signal: "0",
+ Signal: "A",
+ Consent: "B",
+ },
+ CCPA: ccpa.Policy{
+ Value: "C",
},
})
assert.NoError(t, err)
- assert.Equal(t, "//not_localhost/synclocalhost%2Fsetuid%3Fbidder%3Dvisx%26gdpr%3D0%26gdpr_consent%3D%26uid%3D%24%7BUUID%7D", syncInfo.URL)
+ assert.Equal(t, "https://t.visx.net/s2s_sync?gdpr=A&gdpr_consent=B&us_privacy=C&redir=%2Fsetuid%3Fbidder%3Dvisx%26gdpr%3DA%26gdpr_consent%3DB%26uid%3D%24%7BUUID%7D", syncInfo.URL)
assert.Equal(t, "redirect", syncInfo.Type)
assert.EqualValues(t, 0, syncer.GDPRVendorID())
assert.Equal(t, false, syncInfo.SupportCORS)
diff --git a/adapters/yieldmo/usersync.go b/adapters/yieldmo/usersync.go
index f853bbb86a5..041e7e8f073 100644
--- a/adapters/yieldmo/usersync.go
+++ b/adapters/yieldmo/usersync.go
@@ -8,5 +8,5 @@ import (
)
func NewYieldmoSyncer(temp *template.Template) usersync.Usersyncer {
- return adapters.NewSyncer("yieldmo", 0, temp, adapters.SyncTypeRedirect)
+ return adapters.NewSyncer("yieldmo", 173, temp, adapters.SyncTypeRedirect)
}
diff --git a/adapters/yieldmo/usersync_test.go b/adapters/yieldmo/usersync_test.go
index 93ab907f202..598710ec742 100644
--- a/adapters/yieldmo/usersync_test.go
+++ b/adapters/yieldmo/usersync_test.go
@@ -10,7 +10,7 @@ import (
)
func TestYieldmoSyncer(t *testing.T) {
- syncURL := "//ads.yieldmo.com/pbsync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&redirectUri=http%3A%2F%2Flocalhost%2F%2Fsetuid%3Fbidder%3Dyieldmo%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID"
+ syncURL := "//ads.yieldmo.com/pbsync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirectUri=http%3A%2F%2Flocalhost%2F%2Fsetuid%3Fbidder%3Dyieldmo%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID"
syncURLTemplate := template.Must(
template.New("sync-template").Parse(syncURL),
)
@@ -23,8 +23,8 @@ func TestYieldmoSyncer(t *testing.T) {
})
assert.NoError(t, err)
- assert.Equal(t, "//ads.yieldmo.com/pbsync?gdpr=0&gdpr_consent=&redirectUri=http%3A%2F%2Flocalhost%2F%2Fsetuid%3Fbidder%3Dyieldmo%26gdpr%3D0%26gdpr_consent%3D%26uid%3D%24UID", syncInfo.URL)
+ assert.Equal(t, "//ads.yieldmo.com/pbsync?gdpr=0&gdpr_consent=&us_privacy=&redirectUri=http%3A%2F%2Flocalhost%2F%2Fsetuid%3Fbidder%3Dyieldmo%26gdpr%3D0%26gdpr_consent%3D%26uid%3D%24UID", syncInfo.URL)
assert.Equal(t, "redirect", syncInfo.Type)
- assert.EqualValues(t, 0, syncer.GDPRVendorID())
+ assert.EqualValues(t, 173, syncer.GDPRVendorID())
assert.False(t, syncInfo.SupportCORS)
}
diff --git a/analytics/config/config.go b/analytics/config/config.go
index 3073c6ca1aa..7be7c8ecca3 100644
--- a/analytics/config/config.go
+++ b/analytics/config/config.go
@@ -29,6 +29,12 @@ func (ea enabledAnalytics) LogAuctionObject(ao *analytics.AuctionObject) {
}
}
+func (ea enabledAnalytics) LogVideoObject(vo *analytics.VideoObject) {
+ for _, module := range ea {
+ module.LogVideoObject(vo)
+ }
+}
+
func (ea enabledAnalytics) LogCookieSyncObject(cso *analytics.CookieSyncObject) {
for _, module := range ea {
module.LogCookieSyncObject(cso)
diff --git a/analytics/config/config_test.go b/analytics/config/config_test.go
index cb2bb049e11..0fd3ec2019e 100644
--- a/analytics/config/config_test.go
+++ b/analytics/config/config_test.go
@@ -45,6 +45,11 @@ func TestSampleModule(t *testing.T) {
if count != 4 {
t.Errorf("PBSAnalyticsModule failed at LogAmpObject")
}
+
+ am.LogVideoObject(&analytics.VideoObject{})
+ if count != 5 {
+ t.Errorf("PBSAnalyticsModule failed at LogVideoObject")
+ }
}
type sampleModule struct {
@@ -53,6 +58,8 @@ type sampleModule struct {
func (m *sampleModule) LogAuctionObject(ao *analytics.AuctionObject) { *m.count++ }
+func (m *sampleModule) LogVideoObject(vo *analytics.VideoObject) { *m.count++ }
+
func (m *sampleModule) LogCookieSyncObject(cso *analytics.CookieSyncObject) { *m.count++ }
func (m *sampleModule) LogSetUIDObject(so *analytics.SetUIDObject) { *m.count++ }
diff --git a/analytics/core.go b/analytics/core.go
index 3f16ba64c38..6fd5139fd3d 100644
--- a/analytics/core.go
+++ b/analytics/core.go
@@ -2,6 +2,7 @@ package analytics
import (
"github.com/mxmCherry/openrtb"
+ "github.com/prebid/prebid-server/openrtb_ext"
"github.com/prebid/prebid-server/usersync"
)
@@ -15,6 +16,7 @@ import (
type PBSAnalyticsModule interface {
LogAuctionObject(*AuctionObject)
+ LogVideoObject(*VideoObject)
LogCookieSyncObject(*CookieSyncObject)
LogSetUIDObject(*SetUIDObject)
LogAmpObject(*AmpObject)
@@ -38,6 +40,16 @@ type AmpObject struct {
Origin string
}
+//Loggable object of a transaction at /openrtb2/video endpoint
+type VideoObject struct {
+ Status int
+ Errors []error
+ Request *openrtb.BidRequest
+ Response *openrtb.BidResponse
+ VideoRequest *openrtb_ext.BidRequestVideo
+ VideoResponse *openrtb_ext.BidResponseVideo
+}
+
//Loggable object of a transaction at /setuid
type SetUIDObject struct {
Status int
diff --git a/analytics/filesystem/file_module.go b/analytics/filesystem/file_module.go
index b9438763c4b..54d492ad97c 100644
--- a/analytics/filesystem/file_module.go
+++ b/analytics/filesystem/file_module.go
@@ -14,6 +14,7 @@ type RequestType string
const (
COOKIE_SYNC RequestType = "/cookie_sync"
AUCTION RequestType = "/openrtb2/auction"
+ VIDEO RequestType = "/openrtb2/video"
SETUID RequestType = "/set_uid"
AMP RequestType = "/openrtb2/amp"
)
@@ -32,6 +33,15 @@ func (f *FileLogger) LogAuctionObject(ao *analytics.AuctionObject) {
f.Logger.Flush()
}
+//Writes VideoObject to file
+func (f *FileLogger) LogVideoObject(vo *analytics.VideoObject) {
+ //Code to parse the object and log in a way required
+ var b bytes.Buffer
+ b.WriteString(jsonifyVideoObject(vo))
+ f.Logger.Debug(b.String())
+ f.Logger.Flush()
+}
+
//Logs SetUIDObject to file
func (f *FileLogger) LogSetUIDObject(so *analytics.SetUIDObject) {
//Code to parse the object and log in a way required
@@ -98,6 +108,23 @@ func jsonifyAuctionObject(ao *analytics.AuctionObject) string {
}
}
+func jsonifyVideoObject(vo *analytics.VideoObject) string {
+ type alias analytics.VideoObject
+ b, err := json.Marshal(&struct {
+ Type RequestType `json:"type"`
+ *alias
+ }{
+ Type: VIDEO,
+ alias: (*alias)(vo),
+ })
+
+ if err == nil {
+ return string(b)
+ } else {
+ return fmt.Sprintf("Transactional Logs Error: Video object badly formed %v", err)
+ }
+}
+
func jsonifyCookieSync(cso *analytics.CookieSyncObject) string {
type alias analytics.CookieSyncObject
diff --git a/analytics/filesystem/file_module_test.go b/analytics/filesystem/file_module_test.go
index 4ec2bb6abaa..6e2d9f6263b 100644
--- a/analytics/filesystem/file_module_test.go
+++ b/analytics/filesystem/file_module_test.go
@@ -34,6 +34,15 @@ func TestAuctionObject_ToJson(t *testing.T) {
}
}
+func TestVideoObject_ToJson(t *testing.T) {
+ vo := &analytics.VideoObject{
+ Status: http.StatusOK,
+ }
+ if voJson := jsonifyVideoObject(vo); strings.Contains(voJson, "Transactional Logs Error") {
+ t.Fatalf("AuctionObject failed to convert to json")
+ }
+}
+
func TestSetUIDObject_ToJson(t *testing.T) {
so := &analytics.SetUIDObject{
Status: http.StatusOK,
@@ -64,6 +73,7 @@ func TestFileLogger_LogObjects(t *testing.T) {
defer os.RemoveAll(TEST_DIR)
if fl, err := NewFileLogger(TEST_DIR + "//test"); err == nil {
fl.LogAuctionObject(&analytics.AuctionObject{})
+ fl.LogVideoObject(&analytics.VideoObject{})
fl.LogAmpObject(&analytics.AmpObject{})
fl.LogSetUIDObject(&analytics.SetUIDObject{})
fl.LogCookieSyncObject(&analytics.CookieSyncObject{})
diff --git a/config/config.go b/config/config.go
index f7ba40eda01..fae3b522605 100644
--- a/config/config.go
+++ b/config/config.go
@@ -23,6 +23,7 @@ type Configuration struct {
Host string `mapstructure:"host"`
Port int `mapstructure:"port"`
Client HTTPClient `mapstructure:"http_client"`
+ CacheClient HTTPClient `mapstructure:"http_client_cache"`
AdminPort int `mapstructure:"admin_port"`
EnableGzip bool `mapstructure:"enable_gzip"`
// StatusResponse is the string which will be returned by the /status endpoint when things are OK.
@@ -484,52 +485,54 @@ func (cfg *Configuration) GetCachedAssetURL(uuid string) string {
//
func (cfg *Configuration) setDerivedDefaults() {
externalURL := cfg.ExternalURL
- setDefaultUsersync(cfg.Adapters, openrtb_ext.Bidder33Across, "https://ic.tynt.com/r/d?m=xch&rt=html&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&ru="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3D33across%26uid%3D33XUSERID33X&id=zzz000000000002zzz")
+ setDefaultUsersync(cfg.Adapters, openrtb_ext.Bidder33Across, "https://ic.tynt.com/r/d?m=xch&rt=html&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&ru="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3D33across%26uid%3D33XUSERID33X&id=zzz000000000002zzz")
setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderAdform, "https://cm.adform.net/cookie?redirect_url="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dadform%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID")
- setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderAdkernel, "https://sync.adkernel.com/user-sync?t=image&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&r="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dadkernel%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%7BUID%7D")
- setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderAdkernelAdn, "https://tag.adkernel.com/syncr?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&r="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3DadkernelAdn%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%7BUID%7D")
+ setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderAdkernel, "https://sync.adkernel.com/user-sync?t=image&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dadkernel%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%7BUID%7D")
+ setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderAdkernelAdn, "https://tag.adkernel.com/syncr?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3DadkernelAdn%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%7BUID%7D")
setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderAdpone, "https://usersync.adpone.com/csync?redir="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dadpone%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%7Buid%7D")
setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderAdtelligent, "https://sync.adtelligent.com/csync?t=p&ep=0&redir="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dadtelligent%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%7Buid%7D")
setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderAdvangelists, "https://nep.advangelists.com/xp/user-sync?acctid={aid}&&redirect="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dadvangelists%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID")
setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderAppnexus, "https://ib.adnxs.com/getuid?"+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dadnxs%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID")
- setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderBeachfront, "https://sync.bfmio.com/sync_s2s?gdpr={{.GDPR}}&url="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dbeachfront%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%5Bio_cid%5D")
- setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderBrightroll, "https://pr-bh.ybp.yahoo.com/sync/appnexusprebidserver/?gdpr={{.GDPR}}&euconsent={{.GDPRConsent}}&url="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dbrightroll%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID")
- setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderConsumable, "https://e.serverbid.com/udb/9969/match?gdpr={{.GDPR}}&euconsent={{.GDPRConsent}}&redir="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dconsumable%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D")
- setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderConversant, "https://prebid-match.dotomi.com/prebid/match?rurl="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dconversant%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D")
- setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderDatablocks, "https://sync.v5prebid.datablocks.net/s2ssync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&r="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Ddatablocks%26gdpr%3D%24%7Bgdpr%7D%26gdpr_consent%3D%24%7Bgdpr_consent%7D%26uid%3D%24%7Buid%7D")
- setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderEmxDigital, "https://cs.emxdgt.com/um?ssp=pbs&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&redirect="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Demx_digital%26uid%3D%24UID")
- setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderEngageBDR, "https://match.bnmla.com/usersync/s2s_sync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&r="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dvisx%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24%7BUUID%7D")
+ setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderBeachfront, "https://sync.bfmio.com/sync_s2s?gdpr={{.GDPR}}&us_privacy={{.USPrivacy}}&url="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dbeachfront%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%5Bio_cid%5D")
+ setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderBrightroll, "https://pr-bh.ybp.yahoo.com/sync/appnexusprebidserver/?gdpr={{.GDPR}}&euconsent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&url="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dbrightroll%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID")
+ setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderConsumable, "https://e.serverbid.com/udb/9969/match?gdpr={{.GDPR}}&euconsent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redir="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dconsumable%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D")
+ setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderConversant, "https://prebid-match.dotomi.com/prebid/match/bounce/current?rurl="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dconversant%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26networkId%3D72582%26version%3D1%26uid%3D")
+ setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderCpmstar, "https://server.cpmstar.com/usersync.aspx?gdpr={{.GDPR}}&consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dcpmstar%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID")
+ setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderDatablocks, "https://sync.v5prebid.datablocks.net/s2ssync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Ddatablocks%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24%7Buid%7D")
+ setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderEmxDigital, "https://cs.emxdgt.com/um?ssp=pbs&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Demx_digital%26uid%3D%24UID")
+ setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderEngageBDR, "https://match.bnmla.com/usersync/s2s_sync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dengagebdr%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24%7BUUID%7D")
setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderEPlanning, "https://ads.us.e-planning.net/uspd/1/?du=https%3A%2F%2Fads.us.e-planning.net%2Fgetuid%2F1%2F5a1ad71d2d53a0f5%3F"+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Deplanning%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID")
// openrtb_ext.BidderFacebook doesn't have a good default.
// openrtb_ext.BidderGamma doesn't have a good default.
setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderGamoshi, "https://rtb.gamoshi.io/user_sync_prebid?gdpr={{.GDPR}}&consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&rurl="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dgamoshi%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%5Bgusr%5D")
setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderGrid, "https://x.bidswitch.net/check_uuid/"+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dgrid%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24%7BBSW_UUID%7D?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}")
- setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderGumGum, "https://rtb.gumgum.com/usync/prbds2s?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&r="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dgumgum%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D")
- setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderImprovedigital, "https://ad.360yield.com/server_match?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&r="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dimprovedigital%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%7BPUB_USER_ID%7D")
+ setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderGumGum, "https://rtb.gumgum.com/usync/prbds2s?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dgumgum%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D")
+ setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderImprovedigital, "https://ad.360yield.com/server_match?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dimprovedigital%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%7BPUB_USER_ID%7D")
setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderIx, "https://ssum.casalemedia.com/usermatchredir?s=184932&cb="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dix%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D")
setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderLifestreet, "https://ads.lfstmedia.com/idsync/137062?synced=1&ttl=1s&rurl="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dlifestreet%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24%24visitor_cookie%24%24")
- setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderLockerDome, "https://lockerdome.com/usync/prebidserver?pid="+cfg.Adapters["lockerdome"].PlatformID+"&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&redirect="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dlockerdome%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%7B%7Buid%7D%7D")
- setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderMarsmedia, "https://dmp.rtbsrv.com/dmp/profiles/cm?p_id=179&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&redirect="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dmarsmedia%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24%7BUUID%7D")
+ setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderLockerDome, "https://lockerdome.com/usync/prebidserver?pid="+cfg.Adapters["lockerdome"].PlatformID+"&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dlockerdome%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%7B%7Buid%7D%7D")
+ setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderMarsmedia, "https://dmp.rtbsrv.com/dmp/profiles/cm?p_id=179&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dmarsmedia%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24%7BUUID%7D")
setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderMgid, "https://cm.mgid.com/m?cdsp=363893&adu="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dmgid%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%7Bmuidn%7D")
setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderOpenx, "https://rtb.openx.net/sync/prebid?r="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dopenx%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24%7BUID%7D")
- setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderPubmatic, "https://ads.pubmatic.com/AdServer/js/user_sync.html?predirect="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dpubmatic%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D")
+ setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderPubmatic, "https://ads.pubmatic.com/AdServer/js/user_sync.html?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&predirect="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dpubmatic%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D")
setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderPulsepoint, "https://bh.contextweb.com/rtset?pid=561205&ev=1&rurl="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dpulsepoint%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%25%25VGUID%25%25")
- setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderRhythmone, "https://sync.1rx.io/usersync2/rmphb?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&redir="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Drhythmone%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%5BRX_UUID%5D")
+ setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderRhythmone, "https://sync.1rx.io/usersync2/rmphb?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redir="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Drhythmone%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%5BRX_UUID%5D")
// openrtb_ext.BidderRTBHouse doesn't have a good default.
// openrtb_ext.BidderRubicon doesn't have a good default.
setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderSharethrough, "https://match.sharethrough.com/FGMrCMMc/v1?redirectUri="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dsharethrough%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID")
+ setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderSmartRTB, "https://market-global.smrtb.com/sync/all?nid=smartrtb&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&rr="+url.QueryEscape(externalURL)+"%252Fsetuid%253Fbidder%253Dsmartrtb%2526gdpr%253D{{.GDPR}}%2526gdpr_consent%253D{{.GDPRConsent}}%2526uid%253D%257BXID%257D")
setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderSomoaudience, "https://publisher-east.mobileadtrading.com/usersync?ru="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dsomoaudience%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24%7BUID%7D")
setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderSonobi, "https://sync.go.sonobi.com/us.gif?loc="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dsonobi%26consent_string%3D{{.GDPR}}%26gdpr%3D{{.GDPRConsent}}%26uid%3D%5BUID%5D")
setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderSovrn, "https://ap.lijit.com/pixel?redir="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dsovrn%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID")
setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderSynacormedia, "https://sync.technoratimedia.com/services?srv=cs&pid=70&cb="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dsynacormedia%26uid%3D%5BUSER_ID%5D")
// openrtb_ext.BidderTappx doesn't have a good default.
- setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderTriplelift, "https://eb2.3lift.com/getuid?gpdr={{.GDPR}}&cmp_cs={{.GDPRConsent}}&redir="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dtriplelift%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID")
- setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderTripleliftNative, "https://eb2.3lift.com/sync?gpdr={{.GDPR}}&cmp_cs={{.GDPRConsent}}")
+ setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderTriplelift, "https://eb2.3lift.com/getuid?gdpr={{.GDPR}}&cmp_cs={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redir="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dtriplelift%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID")
+ setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderTripleliftNative, "https://eb2.3lift.com/getuid?gdpr={{.GDPR}}&cmp_cs={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redir="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dtriplelift_native%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID")
setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderUcfunnel, "https://sync.aralego.com/idsync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&usprivacy={{.USPrivacy}}&redirect="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Ducfunnel%26uid%3DSspCookieUserId")
- setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderUnruly, "https://usermatch.targeting.unrulymedia.com/pbsync?gdpr={{.GDPR}}&consent={{.GDPRConsent}}&rurl="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dunruly%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID")
- setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderVisx, "https://t.visx.net/s2s_sync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&redir="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dvisx%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24%7BUUID%7D")
+ setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderUnruly, "https://usermatch.targeting.unrulymedia.com/pbsync?gdpr={{.GDPR}}&consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&rurl="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dunruly%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID")
+ setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderVisx, "https://t.visx.net/s2s_sync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redir="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dvisx%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24%7BUUID%7D")
// openrtb_ext.BidderVrtcal doesn't have a good default.
- setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderYieldmo, "https://ads.yieldmo.com/pbsync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&redirectUri="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dyieldmo%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID")
+ setDefaultUsersync(cfg.Adapters, openrtb_ext.BidderYieldmo, "https://ads.yieldmo.com/pbsync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirectUri="+url.QueryEscape(externalURL)+"%2Fsetuid%3Fbidder%3Dyieldmo%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID")
}
func setDefaultUsersync(m map[string]Adapter, bidder openrtb_ext.BidderName, defaultValue string) {
@@ -582,6 +585,9 @@ func SetupViper(v *viper.Viper, filename string) {
v.SetDefault("http_client.max_idle_connections", 400)
v.SetDefault("http_client.max_idle_connections_per_host", 10)
v.SetDefault("http_client.idle_connection_timeout_seconds", 60)
+ v.SetDefault("http_client_cache.max_idle_connections", 10)
+ v.SetDefault("http_client_cache.max_idle_connections_per_host", 2)
+ v.SetDefault("http_client_cache.idle_connection_timeout_seconds", 60)
// no metrics configured by default (metrics{host|database|username|password})
v.SetDefault("metrics.disabled_metrics.account_adapter_details", false)
v.SetDefault("metrics.influxdb.host", "")
@@ -671,16 +677,18 @@ func SetupViper(v *viper.Viper, filename string) {
v.SetDefault("adapters.adpone.endpoint", "http://rtb.adpone.com/bid-request?src=prebid_server")
v.SetDefault("adapters.adtelligent.endpoint", "http://hb.adtelligent.com/auction")
v.SetDefault("adapters.advangelists.endpoint", "http://nep.advangelists.com/xp/get?pubid={{.PublisherID}}")
+ v.SetDefault("adapters.applogy.endpoint", "http://rtb.applogy.com/v1/prebid")
v.SetDefault("adapters.appnexus.endpoint", "http://ib.adnxs.com/openrtb2") // Docs: https://wiki.appnexus.com/display/supply/Incoming+Bid+Request+from+SSPs
v.SetDefault("adapters.appnexus.platform_id", "5")
v.SetDefault("adapters.beachfront.endpoint", "https://display.bfmio.com/prebid_display")
v.SetDefault("adapters.brightroll.endpoint", "http://east-bid.ybp.yahoo.com/bid/appnexuspbs")
v.SetDefault("adapters.consumable.endpoint", "https://e.serverbid.com/api/v2")
v.SetDefault("adapters.conversant.endpoint", "http://api.hb.ad.cpe.dotomi.com/s2s/header/24")
+ v.SetDefault("adapters.cpmstar.endpoint", "https://server.cpmstar.com/openrtbbidrq.aspx")
v.SetDefault("adapters.datablocks.endpoint", "http://{{.Host}}/openrtb2?sid={{.SourceId}}")
v.SetDefault("adapters.emx_digital.endpoint", "https://hb.emxdgt.com")
v.SetDefault("adapters.engagebdr.endpoint", "http://dsp.bnmla.com/hb")
- v.SetDefault("adapters.eplanning.endpoint", "http://ads.us.e-planning.net/hb/1")
+ v.SetDefault("adapters.eplanning.endpoint", "https://ads.us.e-planning.net/hb/1")
v.SetDefault("adapters.gamma.endpoint", "https://hb.gammaplatform.com/adx/request/")
v.SetDefault("adapters.gamoshi.endpoint", "https://rtb.gamoshi.io")
v.SetDefault("adapters.grid.endpoint", "http://grid.bidswitch.net/sp_bid?sp=prebid")
@@ -693,13 +701,14 @@ func SetupViper(v *viper.Viper, filename string) {
v.SetDefault("adapters.marsmedia.endpoint", "https://bid306.rtbsrv.com/bidder/?bid=f3xtet")
v.SetDefault("adapters.mgid.endpoint", "https://prebid.mgid.com/prebid/")
v.SetDefault("adapters.openx.endpoint", "http://rtb.openx.net/prebid")
- v.SetDefault("adapters.pubmatic.endpoint", "http://hbopenbid.pubmatic.com/translator?source=prebid-server")
+ v.SetDefault("adapters.pubmatic.endpoint", "https://hbopenbid.pubmatic.com/translator?source=prebid-server")
v.SetDefault("adapters.pubnative.endpoint", "http://dsp.pubnative.net/bid/v1/request")
v.SetDefault("adapters.pulsepoint.endpoint", "http://bid.contextweb.com/header/s/ortb/prebid-s2s")
v.SetDefault("adapters.rhythmone.endpoint", "http://tag.1rx.io/rmp")
v.SetDefault("adapters.rtbhouse.endpoint", "http://prebidserver-s2s-ams.creativecdn.com/bidder/prebidserver/bids")
v.SetDefault("adapters.rubicon.endpoint", "http://exapi-us-east.rubiconproject.com/a/api/exchange.json")
v.SetDefault("adapters.sharethrough.endpoint", "http://btlr.sharethrough.com/FGMrCMMc/v1")
+ v.SetDefault("adapters.smartrtb.endpoint", "http://market-east.smrtb.com/json/publisher/rtb?pubid={{.PublisherID}}")
v.SetDefault("adapters.somoaudience.endpoint", "http://publisher-east.mobileadtrading.com/rtb/bid")
v.SetDefault("adapters.sonobi.endpoint", "https://apex.go.sonobi.com/prebid?partnerid=71d9d3d8af")
v.SetDefault("adapters.sovrn.endpoint", "http://ap.lijit.com/rtb/bid?src=prebid_server")
diff --git a/config/config_test.go b/config/config_test.go
index cd143c61a5c..78630e071d9 100644
--- a/config/config_test.go
+++ b/config/config_test.go
@@ -27,7 +27,7 @@ func TestDefaults(t *testing.T) {
cmpInts(t, "host_cookie.ttl_days", int(cfg.HostCookie.TTL), 90)
cmpInts(t, "host_cookie.max_cookie_size_bytes", cfg.HostCookie.MaxCookieSizeBytes, 0)
cmpStrings(t, "datacache.type", cfg.DataCache.Type, "dummy")
- cmpStrings(t, "adapters.pubmatic.endpoint", cfg.Adapters[string(openrtb_ext.BidderPubmatic)].Endpoint, "http://hbopenbid.pubmatic.com/translator?source=prebid-server")
+ cmpStrings(t, "adapters.pubmatic.endpoint", cfg.Adapters[string(openrtb_ext.BidderPubmatic)].Endpoint, "https://hbopenbid.pubmatic.com/translator?source=prebid-server")
cmpInts(t, "currency_converter.fetch_interval_seconds", cfg.CurrencyConverter.FetchIntervalSeconds, 1800)
cmpStrings(t, "currency_converter.fetch_url", cfg.CurrencyConverter.FetchURL, "https://cdn.jsdelivr.net/gh/prebid/currency-file@1/latest.json")
cmpBools(t, "account_required", cfg.AccountRequired, false)
@@ -68,6 +68,10 @@ http_client:
max_idle_connections: 500
max_idle_connections_per_host: 20
idle_connection_timeout_seconds: 30
+http_client_cache:
+ max_idle_connections: 1
+ max_idle_connections_per_host: 2
+ idle_connection_timeout_seconds: 3
currency_converter:
fetch_url: https://currency.prebid.org
fetch_interval_seconds: 1800
@@ -214,6 +218,9 @@ func TestFullConfig(t *testing.T) {
cmpInts(t, "http_client.max_idle_connections", cfg.Client.MaxIdleConns, 500)
cmpInts(t, "http_client.max_idle_connections_per_host", cfg.Client.MaxIdleConnsPerHost, 20)
cmpInts(t, "http_client.idle_connection_timeout_seconds", cfg.Client.IdleConnTimeout, 30)
+ cmpInts(t, "http_client_cache.max_idle_connections", cfg.CacheClient.MaxIdleConns, 1)
+ cmpInts(t, "http_client_cache.max_idle_connections_per_host", cfg.CacheClient.MaxIdleConnsPerHost, 2)
+ cmpInts(t, "http_client_cache.idle_connection_timeout_seconds", cfg.CacheClient.IdleConnTimeout, 3)
cmpInts(t, "gdpr.host_vendor_id", cfg.GDPR.HostVendorID, 15)
cmpBools(t, "gdpr.usersync_if_ambiguous", cfg.GDPR.UsersyncIfAmbiguous, true)
@@ -272,7 +279,7 @@ func TestFullConfig(t *testing.T) {
cmpStrings(t, "adapters.brightroll.usersync_url", cfg.Adapters[string(openrtb_ext.BidderBrightroll)].UserSyncURL, "http://test-bh.ybp.yahoo.com/sync/appnexuspbs?gdpr={{.GDPR}}&euconsent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&url=%s")
cmpStrings(t, "adapters.adkerneladn.usersync_url", cfg.Adapters[strings.ToLower(string(openrtb_ext.BidderAdkernelAdn))].UserSyncURL, "https://tag.adkernel.com/syncr?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&r=")
cmpStrings(t, "adapters.rhythmone.endpoint", cfg.Adapters[string(openrtb_ext.BidderRhythmone)].Endpoint, "http://tag.1rx.io/rmp")
- cmpStrings(t, "adapters.rhythmone.usersync_url", cfg.Adapters[string(openrtb_ext.BidderRhythmone)].UserSyncURL, "https://sync.1rx.io/usersync2/rmphb?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&redir=http%3A%2F%2Fprebid-server.prebid.org%2F%2Fsetuid%3Fbidder%3Drhythmone%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%5BRX_UUID%5D")
+ cmpStrings(t, "adapters.rhythmone.usersync_url", cfg.Adapters[string(openrtb_ext.BidderRhythmone)].UserSyncURL, "https://sync.1rx.io/usersync2/rmphb?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redir=http%3A%2F%2Fprebid-server.prebid.org%2F%2Fsetuid%3Fbidder%3Drhythmone%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%5BRX_UUID%5D")
cmpBools(t, "account_required", cfg.AccountRequired, true)
cmpBools(t, "account_adapter_details", cfg.Metrics.Disabled.AccountAdapterDetails, true)
cmpStrings(t, "certificates_file", cfg.PemCertsFile, "/etc/ssl/cert.pem")
diff --git a/currencies/rate_converter.go b/currencies/rate_converter.go
index 63f09bd3c2e..6c6ed172652 100644
--- a/currencies/rate_converter.go
+++ b/currencies/rate_converter.go
@@ -172,11 +172,15 @@ func (rc *RateConverter) Rates() Conversions {
// GetInfo returns setup information about the converter
func (rc *RateConverter) GetInfo() ConverterInfo {
+ var rates *map[string]map[string]float64
+ if rc.Rates() != nil {
+ rates = rc.Rates().GetRates()
+ }
return converterInfo{
source: rc.syncSourceURL,
fetchingInterval: rc.fetchingInterval,
lastUpdated: rc.LastUpdated(),
- rates: rc.Rates().GetRates(),
+ rates: rates,
}
}
diff --git a/currencies/rate_converter_test.go b/currencies/rate_converter_test.go
index a1807a63ffb..cb5e2a0be54 100644
--- a/currencies/rate_converter_test.go
+++ b/currencies/rate_converter_test.go
@@ -66,6 +66,7 @@ func TestFetch_Success(t *testing.T) {
rates := currencyConverter.Rates()
assert.NotNil(t, rates, "Rates() should not return nil")
assert.Equal(t, expectedRates, rates, "Rates() doesn't return expected rates")
+ assert.NotNil(t, currencyConverter.GetInfo(), "GetInfo() should not return nil")
}
func TestFetch_Fail404(t *testing.T) {
@@ -92,6 +93,7 @@ func TestFetch_Fail404(t *testing.T) {
assert.Equal(t, 1, len(calledURLs), "sync URL should have been called %d times but was %d", 1, len(calledURLs))
assert.Equal(t, currencyConverter.LastUpdated(), (time.Time{}), "LastUpdated() shouldn't return a time set")
assert.Nil(t, currencyConverter.Rates(), "Rates() should return nil")
+ assert.NotNil(t, currencyConverter.GetInfo(), "GetInfo() should not return nil")
}
func TestFetch_FailErrorHttpClient(t *testing.T) {
@@ -118,6 +120,7 @@ func TestFetch_FailErrorHttpClient(t *testing.T) {
assert.Equal(t, 1, len(calledURLs), "sync URL should have been called %d times but was %d", 1, len(calledURLs))
assert.Equal(t, currencyConverter.LastUpdated(), (time.Time{}), "LastUpdated() shouldn't return a time set")
assert.Nil(t, currencyConverter.Rates(), "Rates() should return nil")
+ assert.NotNil(t, currencyConverter.GetInfo(), "GetInfo() should not return nil")
}
func TestFetch_FailBadSyncURL(t *testing.T) {
@@ -134,6 +137,7 @@ func TestFetch_FailBadSyncURL(t *testing.T) {
// Verify:
assert.Equal(t, currencyConverter.LastUpdated(), (time.Time{}), "LastUpdated() shouldn't return a time set")
assert.Nil(t, currencyConverter.Rates(), "Rates() should return nil")
+ assert.NotNil(t, currencyConverter.GetInfo(), "GetInfo() should not return nil")
}
func TestFetch_FailBadJSON(t *testing.T) {
@@ -174,6 +178,7 @@ func TestFetch_FailBadJSON(t *testing.T) {
assert.Equal(t, 1, len(calledURLs), "sync URL should have been called %d times but was %d", 1, len(calledURLs))
assert.Equal(t, currencyConverter.LastUpdated(), (time.Time{}), "LastUpdated() shouldn't return a time set")
assert.Nil(t, currencyConverter.Rates(), "Rates() should return nil")
+ assert.NotNil(t, currencyConverter.GetInfo(), "GetInfo() should not return nil")
}
func TestFetch_InvalidRemoteResponseContent(t *testing.T) {
@@ -201,6 +206,7 @@ func TestFetch_InvalidRemoteResponseContent(t *testing.T) {
assert.Equal(t, 1, len(calledURLs), "sync URL should have been called %d times but was %d", 1, len(calledURLs))
assert.Equal(t, currencyConverter.LastUpdated(), (time.Time{}), "LastUpdated() shouldn't return a time set")
assert.Nil(t, currencyConverter.Rates(), "Rates() should return nil")
+ assert.NotNil(t, currencyConverter.GetInfo(), "GetInfo() should not return nil")
}
func TestInit(t *testing.T) {
@@ -264,6 +270,7 @@ func TestInit(t *testing.T) {
assert.NotEqual(t, currencyConverter.LastUpdated(), (time.Time{}), "LastUpdated should be set")
rates := currencyConverter.Rates()
assert.Equal(t, expectedRates, rates, "Conversions.Rates weren't the expected ones")
+ assert.NotNil(t, currencyConverter.GetInfo(), "GetInfo() should not return nil")
if ticksCount == expectedTicks {
currencyConverter.StopPeriodicFetching()
@@ -361,6 +368,7 @@ func TestInitWithZeroDuration(t *testing.T) {
assert.Equal(t, (time.Time{}), currencyConverter.LastUpdated(), "LastUpdated() shouldn't be set")
_, ok := currencyConverter.Rates().(*currencies.ConstantRates)
assert.True(t, ok, "Rates should be type of `currencies.ConstantRates`")
+ assert.NotNil(t, currencyConverter.GetInfo(), "GetInfo() should not return nil")
}
func TestRates(t *testing.T) {
@@ -379,6 +387,7 @@ func TestRates(t *testing.T) {
{from: "", to: "EUR", expectedRate: 0, hasError: true},
{from: "CNY", to: "", expectedRate: 0, hasError: true},
{from: "", to: "", expectedRate: 0, hasError: true},
+ {from: "USD", to: "USD", expectedRate: 1, hasError: false},
}
mockedHttpServer := httptest.NewServer(http.HandlerFunc(
diff --git a/docs/bidders/smartrtb.md b/docs/bidders/smartrtb.md
new file mode 100644
index 00000000000..ffa88f663e8
--- /dev/null
+++ b/docs/bidders/smartrtb.md
@@ -0,0 +1,39 @@
+# SmartRTB Bidder
+
+[SmartRTB](https://smrtb.com/) supports the following parameters to be present in the `ext` object of impression requests:
+
+- "pub_id" type string - Required. Publisher ID assigned to you.
+- "zone_id" type string - Optional. Enables mapping for further settings and reporting in the Marketplace UI.
+- "force_bid" type bool - Optional. If zone ID is mapped, this may be set to always return fake sample bids (banner, video)
+
+Please contact us to create a new Smart RTB Marketplace account, and for any assistance in configuration.
+You may email info@smrtb.com for inquiries.
+
+## Test Request
+
+This sample request is our global test placement and should always return a branded banner bid.
+
+```
+ {
+ "id": "abc",
+ "site": {
+ "page": "prebid.org"
+ },
+ "imp": [{
+ "id": "test",
+ "banner": {
+ "format": [{
+ "w": 300,
+ "h": 250
+ }]
+ },
+ "ext": {
+ "smartrtb": {
+ "pub_id": "test",
+ "zone_id": "N4zTDq3PPEHBIODv7cXK",
+ "force_bid": true
+ }
+ }
+ }]
+ }
+```
diff --git a/docs/developers/stored-requests.md b/docs/developers/stored-requests.md
index 4b54b4e945f..8b7177160c3 100644
--- a/docs/developers/stored-requests.md
+++ b/docs/developers/stored-requests.md
@@ -34,7 +34,7 @@ Add the file `stored_requests/data/by_id/stored_imps/{id}.json` and populate it
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
@@ -88,7 +88,7 @@ You can also store _part_ of the Imp on the server. For example:
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/amp_auction_test.go b/endpoints/openrtb2/amp_auction_test.go
index 0eafaa05b12..c62a6a710d5 100644
--- a/endpoints/openrtb2/amp_auction_test.go
+++ b/endpoints/openrtb2/amp_auction_test.go
@@ -966,7 +966,7 @@ func getTestBidRequest(nilUser bool, nilExt bool, consentString string, digitrus
Imp: []openrtb.Imp{
{
ID: "/19968336/header-bid-tag-0",
- Ext: json.RawMessage(`{"appnexus": { "placementId":10433394 }}`),
+ Ext: json.RawMessage(`{"appnexus": { "placementId":12883451 }}`),
Banner: &openrtb.Banner{
Format: []openrtb.Format{
{
diff --git a/endpoints/openrtb2/auction_benchmark_test.go b/endpoints/openrtb2/auction_benchmark_test.go
index 430b0361eb6..93d7575e865 100644
--- a/endpoints/openrtb2/auction_benchmark_test.go
+++ b/endpoints/openrtb2/auction_benchmark_test.go
@@ -21,7 +21,7 @@ import (
// dummyServer returns the header bidding test ad. This response was scraped from a real appnexus server response.
func dummyServer(w http.ResponseWriter, r *http.Request) {
- w.Write([]byte(`{"id":"some-request-id","seatbid":[{"bid":[{"id":"4625436751433509010","impid":"my-imp-id","price":0.5,"adm":"\u003cscript type=\"application/javascript\" src=\"http://nym1-ib.adnxs.com/ab?e=wqT_3QKABqAAAwAAAwDWAAUBCM-OiNAFELuV09Pqi86EVRj6t-7QyLin_REqLQkAAAECCOA_EQEHNAAA4D8ZAAAAgOtR4D8hERIAKREJoDDy5vwEOL4HQL4HSAJQ1suTDljhgEhgAGiRQHixhQSAAQGKAQNVU0SSBQbwUpgBrAKgAfoBqAEBsAEAuAECwAEDyAEC0AEA2AEA4AEB8AEAigI6dWYoJ2EnLCA0OTQ0NzIsIDE1MTAwODIzODMpO3VmKCdyJywgMjk2ODExMTAsMh4A8JySAvkBIVR6WGNkQWk2MEljRUVOYkxrdzRZQUNEaGdFZ3dBRGdBUUFSSXZnZFE4dWI4QkZnQVlQX19fXzhQYUFCd0FYZ0JnQUVCaUFFQmtBRUJtQUVCb0FFQnFBRURzQUVBdVFFcGk0aURBQURnUDhFQktZdUlnd0FBNERfSkFTZlJKRUdtbi00XzJRRUFBQUFBQUFEd1AtQUJBUFVCBQ8oSmdDQUtBQ0FMVUMFEARMMAkI8ExNQUNBY2dDQWRBQ0FkZ0NBZUFDQU9nQ0FQZ0NBSUFEQVpBREFKZ0RBYWdEdXRDSEJMb0RDVTVaVFRJNk16STNOdy4umgItITh3aENuZzb8ALg0WUJJSUFRb0FEb0pUbGxOTWpvek1qYzPYAugH4ALH0wHyAhAKBkFEVl9JRBIGNCV1HPICEQoGQ1BHARMcBzE5Nzc5MzMBJwgFQ1AFE_B-ODUxMzU5NIADAYgDAZADAJgDFKADAaoDAMADrALIAwDYAwDgAwDoAwD4AwCABACSBAkvb3BlbnJ0YjKYBACoBACyBAwIABAAGAAgADAAOAC4BADABADIBADSBAlOWU0yOjMyNzfaBAIIAeAEAPAE1suTDogFAZgFAKAF_____wUDXAGqBQ9zb21lLXJlcXVlc3QtaWTABQDJBUmbTPA_0gUJCQAAAAAAAAAA2AUB4AUB\u0026s=61dc0e8770543def5a3a77b4589830d1274b26f1\u0026test=1\u0026pp=${AUCTION_PRICE}\u0026\"\u003e\u003c/script\u003e","adid":"29681110","adomain":["appnexus.com"],"iurl":"http://nym1-ib.adnxs.com/cr?id=29681110","cid":"958","crid":"29681110","w":300,"h":250,"ext":{"bidder":{"appnexus":{"brand_id":1,"auction_id":6127490747252132539,"bidder_id":2}}}}],"seat":"appnexus"}],"ext":{"debug":{"httpcalls":{"appnexus":[{"uri":"http://ib.adnxs.com/openrtb2","requestbody":"{\"id\":\"some-request-id\",\"imp\":[{\"id\":\"my-imp-id\",\"banner\":{\"format\":[{\"w\":300,\"h\":250},{\"w\":300,\"h\":600}]},\"ext\":{\"appnexus\":{\"placement_id\":10433394}}}],\"test\":1,\"tmax\":500}","responsebody":"{\"id\":\"some-request-id\",\"seatbid\":[{\"bid\":[{\"id\":\"4625436751433509010\",\"impid\":\"my-imp-id\",\"price\": 0.500000,\"adid\":\"29681110\",\"adm\":\"\u003cscript type=\\\"application/javascript\\\" src=\\\"http://nym1-ib.adnxs.com/ab?e=wqT_3QKABqAAAwAAAwDWAAUBCM-OiNAFELuV09Pqi86EVRj6t-7QyLin_REqLQkAAAECCOA_EQEHNAAA4D8ZAAAAgOtR4D8hERIAKREJoDDy5vwEOL4HQL4HSAJQ1suTDljhgEhgAGiRQHixhQSAAQGKAQNVU0SSBQbwUpgBrAKgAfoBqAEBsAEAuAECwAEDyAEC0AEA2AEA4AEB8AEAigI6dWYoJ2EnLCA0OTQ0NzIsIDE1MTAwODIzODMpO3VmKCdyJywgMjk2ODExMTAsMh4A8JySAvkBIVR6WGNkQWk2MEljRUVOYkxrdzRZQUNEaGdFZ3dBRGdBUUFSSXZnZFE4dWI4QkZnQVlQX19fXzhQYUFCd0FYZ0JnQUVCaUFFQmtBRUJtQUVCb0FFQnFBRURzQUVBdVFFcGk0aURBQURnUDhFQktZdUlnd0FBNERfSkFTZlJKRUdtbi00XzJRRUFBQUFBQUFEd1AtQUJBUFVCBQ8oSmdDQUtBQ0FMVUMFEARMMAkI8ExNQUNBY2dDQWRBQ0FkZ0NBZUFDQU9nQ0FQZ0NBSUFEQVpBREFKZ0RBYWdEdXRDSEJMb0RDVTVaVFRJNk16STNOdy4umgItITh3aENuZzb8ALg0WUJJSUFRb0FEb0pUbGxOTWpvek1qYzPYAugH4ALH0wHyAhAKBkFEVl9JRBIGNCV1HPICEQoGQ1BHARMcBzE5Nzc5MzMBJwgFQ1AFE_B-ODUxMzU5NIADAYgDAZADAJgDFKADAaoDAMADrALIAwDYAwDgAwDoAwD4AwCABACSBAkvb3BlbnJ0YjKYBACoBACyBAwIABAAGAAgADAAOAC4BADABADIBADSBAlOWU0yOjMyNzfaBAIIAeAEAPAE1suTDogFAZgFAKAF_____wUDXAGqBQ9zb21lLXJlcXVlc3QtaWTABQDJBUmbTPA_0gUJCQAAAAAAAAAA2AUB4AUB\u0026s=61dc0e8770543def5a3a77b4589830d1274b26f1\u0026test=1\u0026pp=${AUCTION_PRICE}\u0026\\\"\u003e\u003c/script\u003e\",\"adomain\":[\"appnexus.com\"],\"iurl\":\"http://nym1-ib.adnxs.com/cr?id=29681110\",\"cid\":\"958\",\"crid\":\"29681110\",\"h\": 250,\"w\": 300,\"ext\":{\"appnexus\":{\"brand_id\": 1,\"auction_id\": 6127490747252132539,\"bidder_id\": 2}}}],\"seat\":\"958\"}],\"bidid\":\"8271358638249766712\",\"cur\":\"USD\"}","status":200}]}},"responsetimemillis":{"appnexus":42}}}`))
+ w.Write([]byte(`{"id":"some-request-id","seatbid":[{"bid":[{"id":"4625436751433509010","impid":"my-imp-id","price":0.5,"adm":"\u003cscript type=\"application/javascript\" src=\"http://nym1-ib.adnxs.com/ab?e=wqT_3QKABqAAAwAAAwDWAAUBCM-OiNAFELuV09Pqi86EVRj6t-7QyLin_REqLQkAAAECCOA_EQEHNAAA4D8ZAAAAgOtR4D8hERIAKREJoDDy5vwEOL4HQL4HSAJQ1suTDljhgEhgAGiRQHixhQSAAQGKAQNVU0SSBQbwUpgBrAKgAfoBqAEBsAEAuAECwAEDyAEC0AEA2AEA4AEB8AEAigI6dWYoJ2EnLCA0OTQ0NzIsIDE1MTAwODIzODMpO3VmKCdyJywgMjk2ODExMTAsMh4A8JySAvkBIVR6WGNkQWk2MEljRUVOYkxrdzRZQUNEaGdFZ3dBRGdBUUFSSXZnZFE4dWI4QkZnQVlQX19fXzhQYUFCd0FYZ0JnQUVCaUFFQmtBRUJtQUVCb0FFQnFBRURzQUVBdVFFcGk0aURBQURnUDhFQktZdUlnd0FBNERfSkFTZlJKRUdtbi00XzJRRUFBQUFBQUFEd1AtQUJBUFVCBQ8oSmdDQUtBQ0FMVUMFEARMMAkI8ExNQUNBY2dDQWRBQ0FkZ0NBZUFDQU9nQ0FQZ0NBSUFEQVpBREFKZ0RBYWdEdXRDSEJMb0RDVTVaVFRJNk16STNOdy4umgItITh3aENuZzb8ALg0WUJJSUFRb0FEb0pUbGxOTWpvek1qYzPYAugH4ALH0wHyAhAKBkFEVl9JRBIGNCV1HPICEQoGQ1BHARMcBzE5Nzc5MzMBJwgFQ1AFE_B-ODUxMzU5NIADAYgDAZADAJgDFKADAaoDAMADrALIAwDYAwDgAwDoAwD4AwCABACSBAkvb3BlbnJ0YjKYBACoBACyBAwIABAAGAAgADAAOAC4BADABADIBADSBAlOWU0yOjMyNzfaBAIIAeAEAPAE1suTDogFAZgFAKAF_____wUDXAGqBQ9zb21lLXJlcXVlc3QtaWTABQDJBUmbTPA_0gUJCQAAAAAAAAAA2AUB4AUB\u0026s=61dc0e8770543def5a3a77b4589830d1274b26f1\u0026test=1\u0026pp=${AUCTION_PRICE}\u0026\"\u003e\u003c/script\u003e","adid":"29681110","adomain":["appnexus.com"],"iurl":"http://nym1-ib.adnxs.com/cr?id=29681110","cid":"958","crid":"29681110","w":300,"h":250,"ext":{"bidder":{"appnexus":{"brand_id":1,"auction_id":6127490747252132539,"bidder_id":2}}}}],"seat":"appnexus"}],"ext":{"debug":{"httpcalls":{"appnexus":[{"uri":"http://ib.adnxs.com/openrtb2","requestbody":"{\"id\":\"some-request-id\",\"imp\":[{\"id\":\"my-imp-id\",\"banner\":{\"format\":[{\"w\":300,\"h\":250},{\"w\":300,\"h\":600}]},\"ext\":{\"appnexus\":{\"placement_id\":12883451}}}],\"test\":1,\"tmax\":500}","responsebody":"{\"id\":\"some-request-id\",\"seatbid\":[{\"bid\":[{\"id\":\"4625436751433509010\",\"impid\":\"my-imp-id\",\"price\": 0.500000,\"adid\":\"29681110\",\"adm\":\"\u003cscript type=\\\"application/javascript\\\" src=\\\"http://nym1-ib.adnxs.com/ab?e=wqT_3QKABqAAAwAAAwDWAAUBCM-OiNAFELuV09Pqi86EVRj6t-7QyLin_REqLQkAAAECCOA_EQEHNAAA4D8ZAAAAgOtR4D8hERIAKREJoDDy5vwEOL4HQL4HSAJQ1suTDljhgEhgAGiRQHixhQSAAQGKAQNVU0SSBQbwUpgBrAKgAfoBqAEBsAEAuAECwAEDyAEC0AEA2AEA4AEB8AEAigI6dWYoJ2EnLCA0OTQ0NzIsIDE1MTAwODIzODMpO3VmKCdyJywgMjk2ODExMTAsMh4A8JySAvkBIVR6WGNkQWk2MEljRUVOYkxrdzRZQUNEaGdFZ3dBRGdBUUFSSXZnZFE4dWI4QkZnQVlQX19fXzhQYUFCd0FYZ0JnQUVCaUFFQmtBRUJtQUVCb0FFQnFBRURzQUVBdVFFcGk0aURBQURnUDhFQktZdUlnd0FBNERfSkFTZlJKRUdtbi00XzJRRUFBQUFBQUFEd1AtQUJBUFVCBQ8oSmdDQUtBQ0FMVUMFEARMMAkI8ExNQUNBY2dDQWRBQ0FkZ0NBZUFDQU9nQ0FQZ0NBSUFEQVpBREFKZ0RBYWdEdXRDSEJMb0RDVTVaVFRJNk16STNOdy4umgItITh3aENuZzb8ALg0WUJJSUFRb0FEb0pUbGxOTWpvek1qYzPYAugH4ALH0wHyAhAKBkFEVl9JRBIGNCV1HPICEQoGQ1BHARMcBzE5Nzc5MzMBJwgFQ1AFE_B-ODUxMzU5NIADAYgDAZADAJgDFKADAaoDAMADrALIAwDYAwDgAwDoAwD4AwCABACSBAkvb3BlbnJ0YjKYBACoBACyBAwIABAAGAAgADAAOAC4BADABADIBADSBAlOWU0yOjMyNzfaBAIIAeAEAPAE1suTDogFAZgFAKAF_____wUDXAGqBQ9zb21lLXJlcXVlc3QtaWTABQDJBUmbTPA_0gUJCQAAAAAAAAAA2AUB4AUB\u0026s=61dc0e8770543def5a3a77b4589830d1274b26f1\u0026test=1\u0026pp=${AUCTION_PRICE}\u0026\\\"\u003e\u003c/script\u003e\",\"adomain\":[\"appnexus.com\"],\"iurl\":\"http://nym1-ib.adnxs.com/cr?id=29681110\",\"cid\":\"958\",\"crid\":\"29681110\",\"h\": 250,\"w\": 300,\"ext\":{\"appnexus\":{\"brand_id\": 1,\"auction_id\": 6127490747252132539,\"bidder_id\": 2}}}],\"seat\":\"958\"}],\"bidid\":\"8271358638249766712\",\"cur\":\"USD\"}","status":200}]}},"responsetimemillis":{"appnexus":42}}}`))
}
// newDummyRequest returns a request which fetches the header bidding test ad.
@@ -45,7 +45,7 @@ func newDummyRequest() *http.Request {
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/auction_test.go b/endpoints/openrtb2/auction_test.go
index c1d57e9c297..89f0fa255df 100644
--- a/endpoints/openrtb2/auction_test.go
+++ b/endpoints/openrtb2/auction_test.go
@@ -88,7 +88,7 @@ func TestExplicitUserId(t *testing.T) {
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
@@ -425,7 +425,7 @@ func buildNativeRequest(t *testing.T, nativeData []byte) []byte {
buf := bytes.NewBuffer(nil)
buf.WriteString(`{"id":"req-id","site":{"page":"some.page.com"},"tmax":500,"imp":[{"id":"some-imp","native":{"request":`)
buf.Write(serialized)
- buf.WriteString(`},"ext":{"appnexus":{"placementId":10433394}}}]}`)
+ buf.WriteString(`},"ext":{"appnexus":{"placementId":12883451}}}]}`)
return buf.Bytes()
}
diff --git a/endpoints/openrtb2/interstitial_test.go b/endpoints/openrtb2/interstitial_test.go
index e680478e63e..1c6eb2555db 100644
--- a/endpoints/openrtb2/interstitial_test.go
+++ b/endpoints/openrtb2/interstitial_test.go
@@ -22,7 +22,7 @@ var request = &openrtb.BidRequest{
},
},
Instl: 1,
- Ext: json.RawMessage(`{"appnexus": {"placementId": 10433394}}`),
+ Ext: json.RawMessage(`{"appnexus": {"placementId": 12883451}}`),
},
},
Device: &openrtb.Device{
diff --git a/endpoints/openrtb2/sample-requests/account-required/no-acct.json b/endpoints/openrtb2/sample-requests/account-required/no-acct.json
index 4ba8dec52c3..d84d797017d 100644
--- a/endpoints/openrtb2/sample-requests/account-required/no-acct.json
+++ b/endpoints/openrtb2/sample-requests/account-required/no-acct.json
@@ -28,7 +28,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/account-required/with-acct.json b/endpoints/openrtb2/sample-requests/account-required/with-acct.json
index d1ab715cdbe..fb4c6313051 100644
--- a/endpoints/openrtb2/sample-requests/account-required/with-acct.json
+++ b/endpoints/openrtb2/sample-requests/account-required/with-acct.json
@@ -29,7 +29,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/aliased/simple.json b/endpoints/openrtb2/sample-requests/aliased/simple.json
index e656be43ed5..e7f6ba21b83 100644
--- a/endpoints/openrtb2/sample-requests/aliased/simple.json
+++ b/endpoints/openrtb2/sample-requests/aliased/simple.json
@@ -13,7 +13,7 @@
},
"ext": {
"test1": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/aliased/site.json b/endpoints/openrtb2/sample-requests/aliased/site.json
index 981b69b5524..cf7e9a77533 100644
--- a/endpoints/openrtb2/sample-requests/aliased/site.json
+++ b/endpoints/openrtb2/sample-requests/aliased/site.json
@@ -23,10 +23,10 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
},
"test1": {
- "placementId": 10433394
+ "placementId": 12883451
},
"test2": {
"accountId": 1001,
diff --git a/endpoints/openrtb2/sample-requests/blacklisted/blacklisted-acct.json b/endpoints/openrtb2/sample-requests/blacklisted/blacklisted-acct.json
index 8977480de33..ee04a9464e9 100644
--- a/endpoints/openrtb2/sample-requests/blacklisted/blacklisted-acct.json
+++ b/endpoints/openrtb2/sample-requests/blacklisted/blacklisted-acct.json
@@ -42,7 +42,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
},
"districtm": {
"placementId": 105
diff --git a/endpoints/openrtb2/sample-requests/blacklisted/blacklisted-app.json b/endpoints/openrtb2/sample-requests/blacklisted/blacklisted-app.json
index 219595e409a..1ace4b53666 100644
--- a/endpoints/openrtb2/sample-requests/blacklisted/blacklisted-app.json
+++ b/endpoints/openrtb2/sample-requests/blacklisted/blacklisted-app.json
@@ -39,7 +39,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
},
"districtm": {
"placementId": 105
diff --git a/endpoints/openrtb2/sample-requests/disabled/bad/bad-alias.json b/endpoints/openrtb2/sample-requests/disabled/bad/bad-alias.json
index 8299f96ce6b..096c028cfe9 100644
--- a/endpoints/openrtb2/sample-requests/disabled/bad/bad-alias.json
+++ b/endpoints/openrtb2/sample-requests/disabled/bad/bad-alias.json
@@ -15,7 +15,7 @@
},
"ext": {
"test1": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/disabled/bad/bad-bidder.json b/endpoints/openrtb2/sample-requests/disabled/bad/bad-bidder.json
index f0313824456..1fa21b203e3 100644
--- a/endpoints/openrtb2/sample-requests/disabled/bad/bad-bidder.json
+++ b/endpoints/openrtb2/sample-requests/disabled/bad/bad-bidder.json
@@ -15,7 +15,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/disabled/good/partial.json b/endpoints/openrtb2/sample-requests/disabled/good/partial.json
index 0f6bf1dd005..fe0c492be2d 100644
--- a/endpoints/openrtb2/sample-requests/disabled/good/partial.json
+++ b/endpoints/openrtb2/sample-requests/disabled/good/partial.json
@@ -23,7 +23,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
},
"rubicon": {
"accountId": 1001,
diff --git a/endpoints/openrtb2/sample-requests/invalid-stored/bad_incoming_1.json b/endpoints/openrtb2/sample-requests/invalid-stored/bad_incoming_1.json
index ccb54c0547e..2a647d7d8c8 100644
--- a/endpoints/openrtb2/sample-requests/invalid-stored/bad_incoming_1.json
+++ b/endpoints/openrtb2/sample-requests/invalid-stored/bad_incoming_1.json
@@ -24,7 +24,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/invalid-stored/bad_incoming_2.json b/endpoints/openrtb2/sample-requests/invalid-stored/bad_incoming_2.json
index 6023f86970e..d18a20d7a13 100644
--- a/endpoints/openrtb2/sample-requests/invalid-stored/bad_incoming_2.json
+++ b/endpoints/openrtb2/sample-requests/invalid-stored/bad_incoming_2.json
@@ -24,7 +24,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/alias-bidder-self.json b/endpoints/openrtb2/sample-requests/invalid-whole/alias-bidder-self.json
index f081b365dd9..666253ec85b 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/alias-bidder-self.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/alias-bidder-self.json
@@ -13,7 +13,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/alias-unknown-core.json b/endpoints/openrtb2/sample-requests/invalid-whole/alias-unknown-core.json
index acf3bc0dd4f..6c1925d65b1 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/alias-unknown-core.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/alias-unknown-core.json
@@ -15,7 +15,7 @@
},
"ext": {
"unknown": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/app-bad-ext.json b/endpoints/openrtb2/sample-requests/invalid-whole/app-bad-ext.json
index 2516a268754..672b05724c8 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/app-bad-ext.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/app-bad-ext.json
@@ -32,7 +32,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/banner-h-only.json b/endpoints/openrtb2/sample-requests/invalid-whole/banner-h-only.json
index 7040e8dfc3c..515824e65d9 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/banner-h-only.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/banner-h-only.json
@@ -13,7 +13,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/banner-h-zero.json b/endpoints/openrtb2/sample-requests/invalid-whole/banner-h-zero.json
index d98cfba100b..f18f63e5e28 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/banner-h-zero.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/banner-h-zero.json
@@ -14,7 +14,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/banner-w-only.json b/endpoints/openrtb2/sample-requests/invalid-whole/banner-w-only.json
index 52a7bdd2ba2..70739a65834 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/banner-w-only.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/banner-w-only.json
@@ -13,7 +13,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/banner-w-zero.json b/endpoints/openrtb2/sample-requests/invalid-whole/banner-w-zero.json
index 0b927f26e3c..b3453ab4cb7 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/banner-w-zero.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/banner-w-zero.json
@@ -14,7 +14,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/bid-adjustment-invalid-bidder.json b/endpoints/openrtb2/sample-requests/invalid-whole/bid-adjustment-invalid-bidder.json
index 985f99126c4..569e16d2d20 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/bid-adjustment-invalid-bidder.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/bid-adjustment-invalid-bidder.json
@@ -13,7 +13,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/bid-adjustment-negative.json b/endpoints/openrtb2/sample-requests/invalid-whole/bid-adjustment-negative.json
index 984998000c5..4db6ee09bd8 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/bid-adjustment-negative.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/bid-adjustment-negative.json
@@ -13,7 +13,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/cache-nothing.json b/endpoints/openrtb2/sample-requests/invalid-whole/cache-nothing.json
index 605040c6cfc..d4b875498ae 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/cache-nothing.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/cache-nothing.json
@@ -15,7 +15,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/digitrust.json b/endpoints/openrtb2/sample-requests/invalid-whole/digitrust.json
index 2b65ed19db0..1be93853a0b 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/digitrust.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/digitrust.json
@@ -25,7 +25,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/format-empty-array.json b/endpoints/openrtb2/sample-requests/invalid-whole/format-empty-array.json
index e159601b6e8..15e41cc5fb2 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/format-empty-array.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/format-empty-array.json
@@ -13,7 +13,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/imp-id-duplicates.json b/endpoints/openrtb2/sample-requests/invalid-whole/imp-id-duplicates.json
index 095542ef59e..53517c268b6 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/imp-id-duplicates.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/imp-id-duplicates.json
@@ -18,7 +18,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
},
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/interstital-bad-perc.json b/endpoints/openrtb2/sample-requests/invalid-whole/interstital-bad-perc.json
index f04f3d8aa25..6854ea9a470 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/interstital-bad-perc.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/interstital-bad-perc.json
@@ -20,7 +20,7 @@
"instl": 1,
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/interstitial-empty.json b/endpoints/openrtb2/sample-requests/invalid-whole/interstitial-empty.json
index 5fa28059b0d..a69f287dfab 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/interstitial-empty.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/interstitial-empty.json
@@ -14,7 +14,7 @@
"instl": 1,
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/no-site-or-app.json b/endpoints/openrtb2/sample-requests/invalid-whole/no-site-or-app.json
index 1cbfdd501c2..c56dae324fc 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/no-site-or-app.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/no-site-or-app.json
@@ -12,7 +12,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/regs-ext-gdpr-invalid.json b/endpoints/openrtb2/sample-requests/invalid-whole/regs-ext-gdpr-invalid.json
index 6737295ae82..dff3023c702 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/regs-ext-gdpr-invalid.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/regs-ext-gdpr-invalid.json
@@ -17,7 +17,7 @@
"id": "/19968336/header-bid-tag-0",
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
},
"banner": {
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/regs-ext-gdpr-string.json b/endpoints/openrtb2/sample-requests/invalid-whole/regs-ext-gdpr-string.json
index 3abc88c70da..ce887889034 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/regs-ext-gdpr-string.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/regs-ext-gdpr-string.json
@@ -17,7 +17,7 @@
"id": "/19968336/header-bid-tag-0",
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
},
"banner": {
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/regs-ext-malformed.json b/endpoints/openrtb2/sample-requests/invalid-whole/regs-ext-malformed.json
index 7c2805fcdbb..a403103d6fb 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/regs-ext-malformed.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/regs-ext-malformed.json
@@ -17,7 +17,7 @@
"id": "/19968336/header-bid-tag-0",
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
},
"banner": {
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/site-app-both.json b/endpoints/openrtb2/sample-requests/invalid-whole/site-app-both.json
index abbcdac325f..4b643705640 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/site-app-both.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/site-app-both.json
@@ -16,7 +16,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/site-empty.json b/endpoints/openrtb2/sample-requests/invalid-whole/site-empty.json
index 430b25f67a0..3d53314dbb7 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/site-empty.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/site-empty.json
@@ -13,7 +13,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/site-ext-amp.json b/endpoints/openrtb2/sample-requests/invalid-whole/site-ext-amp.json
index 17cd68b9232..bebe4625578 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/site-ext-amp.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/site-ext-amp.json
@@ -28,7 +28,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/storedrequest-id-int.json b/endpoints/openrtb2/sample-requests/invalid-whole/storedrequest-id-int.json
index 3fe94a993ad..5d510d21dbd 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/storedrequest-id-int.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/storedrequest-id-int.json
@@ -15,7 +15,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/unknown-bidder.json b/endpoints/openrtb2/sample-requests/invalid-whole/unknown-bidder.json
index f11be6fd51c..3914ae7ae49 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/unknown-bidder.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/unknown-bidder.json
@@ -24,7 +24,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
},
"unknownbidder": {
"param1": "foobar",
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-consent-int.json b/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-consent-int.json
index c7a6a53b087..5bc0ed33eab 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-consent-int.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-consent-int.json
@@ -17,7 +17,7 @@
"id": "/19968336/header-bid-tag-0",
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
},
"banner": {
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-eids-eids-uids-empty.json b/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-eids-eids-uids-empty.json
index e9914e3b7db..ebbb4e2701c 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-eids-eids-uids-empty.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-eids-eids-uids-empty.json
@@ -17,7 +17,7 @@
"id": "/19968336/header-bid-tag-0",
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
},
"banner": {
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-eids-empty.json b/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-eids-empty.json
index 4f66917ff3f..3d73d73117e 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-eids-empty.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-eids-empty.json
@@ -17,7 +17,7 @@
"id": "/19968336/header-bid-tag-0",
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
},
"banner": {
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-eids-id-uids-empty.json b/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-eids-id-uids-empty.json
index 1ca50079a9a..bbd0dadfd70 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-eids-id-uids-empty.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-eids-id-uids-empty.json
@@ -17,7 +17,7 @@
"id": "/19968336/header-bid-tag-0",
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
},
"banner": {
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-eids-source-empty.json b/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-eids-source-empty.json
index 8526298047f..5efff0626ef 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-eids-source-empty.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-eids-source-empty.json
@@ -17,7 +17,7 @@
"id": "/19968336/header-bid-tag-0",
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
},
"banner": {
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-eids-source-unique.json b/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-eids-source-unique.json
index 52565d47228..e508b113aff 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-eids-source-unique.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-eids-source-unique.json
@@ -17,7 +17,7 @@
"id": "/19968336/header-bid-tag-0",
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
},
"banner": {
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-eids-uids-id-empty.json b/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-eids-uids-id-empty.json
index 33a33b9f416..3a9659b7327 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-eids-uids-id-empty.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-eids-uids-id-empty.json
@@ -17,7 +17,7 @@
"id": "/19968336/header-bid-tag-0",
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
},
"banner": {
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-prebid-buyeruids-empty.json b/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-prebid-buyeruids-empty.json
index d967463d2d1..44bee775844 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-prebid-buyeruids-empty.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-prebid-buyeruids-empty.json
@@ -18,7 +18,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-prebid-buyeruids-unknown.json b/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-prebid-buyeruids-unknown.json
index bad67e2d3d8..78773066744 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-prebid-buyeruids-unknown.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-prebid-buyeruids-unknown.json
@@ -18,7 +18,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-prebid-empty.json b/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-prebid-empty.json
index 8113a70be68..f2e497514b7 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-prebid-empty.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-prebid-empty.json
@@ -18,7 +18,7 @@
},
"ext": {
"appnexus":{
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/user-gdpr-badtype.json b/endpoints/openrtb2/sample-requests/invalid-whole/user-gdpr-badtype.json
index 3abc88c70da..ce887889034 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/user-gdpr-badtype.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/user-gdpr-badtype.json
@@ -17,7 +17,7 @@
"id": "/19968336/header-bid-tag-0",
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
},
"banner": {
diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/user-gdpr-invalid.json b/endpoints/openrtb2/sample-requests/invalid-whole/user-gdpr-invalid.json
index b2b554846ca..0729a22db80 100644
--- a/endpoints/openrtb2/sample-requests/invalid-whole/user-gdpr-invalid.json
+++ b/endpoints/openrtb2/sample-requests/invalid-whole/user-gdpr-invalid.json
@@ -17,7 +17,7 @@
"id": "/19968336/header-bid-tag-0",
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
},
"banner": {
diff --git a/endpoints/openrtb2/sample-requests/valid-whole/exemplary/all-ext.json b/endpoints/openrtb2/sample-requests/valid-whole/exemplary/all-ext.json
index 17b249a1494..3e2beedefac 100644
--- a/endpoints/openrtb2/sample-requests/valid-whole/exemplary/all-ext.json
+++ b/endpoints/openrtb2/sample-requests/valid-whole/exemplary/all-ext.json
@@ -39,7 +39,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
},
"districtm": {
"placementId": 105
diff --git a/endpoints/openrtb2/sample-requests/valid-whole/exemplary/prebid-test-ad.json b/endpoints/openrtb2/sample-requests/valid-whole/exemplary/prebid-test-ad.json
index b4fd8693953..fc4794328a4 100644
--- a/endpoints/openrtb2/sample-requests/valid-whole/exemplary/prebid-test-ad.json
+++ b/endpoints/openrtb2/sample-requests/valid-whole/exemplary/prebid-test-ad.json
@@ -23,7 +23,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/aliased-buyeruids.json b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/aliased-buyeruids.json
index 1eb74614340..82125592e46 100644
--- a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/aliased-buyeruids.json
+++ b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/aliased-buyeruids.json
@@ -16,7 +16,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/aliases.json b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/aliases.json
index 6c8608ba3c6..f6137e4a019 100644
--- a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/aliases.json
+++ b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/aliases.json
@@ -13,7 +13,7 @@
},
"ext": {
"unknown": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/app.json b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/app.json
index cad5e852e69..66e05d7636b 100644
--- a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/app.json
+++ b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/app.json
@@ -28,7 +28,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/bid-adjustments.json b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/bid-adjustments.json
index 2ce81b97b25..0cf52a8915f 100644
--- a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/bid-adjustments.json
+++ b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/bid-adjustments.json
@@ -13,7 +13,7 @@
},
"ext": {
"unknown": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/cache-bids.json b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/cache-bids.json
index 884ec898dab..a4c93b3d3cb 100644
--- a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/cache-bids.json
+++ b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/cache-bids.json
@@ -13,7 +13,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/cache-vast.json b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/cache-vast.json
index 7878767af78..fe9445358ba 100644
--- a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/cache-vast.json
+++ b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/cache-vast.json
@@ -13,7 +13,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/ccpa-invalid.json b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/ccpa-invalid.json
index bf04930420b..f3b677635c0 100644
--- a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/ccpa-invalid.json
+++ b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/ccpa-invalid.json
@@ -15,7 +15,7 @@
"id": "/19968336/header-bid-tag-0",
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
},
"banner": {
diff --git a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/digitrust.json b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/digitrust.json
index 0017f5e7203..ca8e090760d 100644
--- a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/digitrust.json
+++ b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/digitrust.json
@@ -23,7 +23,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/gdpr-no-consentstring.json b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/gdpr-no-consentstring.json
index 77f1f86bede..5a63c6d11ce 100644
--- a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/gdpr-no-consentstring.json
+++ b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/gdpr-no-consentstring.json
@@ -15,7 +15,7 @@
"id": "/19968336/header-bid-tag-0",
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
},
"banner": {
diff --git a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/gdpr.json b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/gdpr.json
index 1234f58ddce..ef9f10d0cd0 100644
--- a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/gdpr.json
+++ b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/gdpr.json
@@ -15,7 +15,7 @@
"id": "/19968336/header-bid-tag-0",
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
},
"banner": {
diff --git a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/interstitial-device-only.json b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/interstitial-device-only.json
index 2c85ef143d3..64146eaebe8 100644
--- a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/interstitial-device-only.json
+++ b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/interstitial-device-only.json
@@ -10,7 +10,7 @@
"instl": 1,
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/interstitial-no-extension.json b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/interstitial-no-extension.json
index 1e6604e7d2a..15cd832053f 100644
--- a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/interstitial-no-extension.json
+++ b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/interstitial-no-extension.json
@@ -17,7 +17,7 @@
"instl": 1,
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/interstitial.json b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/interstitial.json
index c5d373797ff..64fc2fe2653 100644
--- a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/interstitial.json
+++ b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/interstitial.json
@@ -17,7 +17,7 @@
"instl": 1,
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/site-amp.json b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/site-amp.json
index c0dbb355fea..30c0afc800a 100644
--- a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/site-amp.json
+++ b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/site-amp.json
@@ -26,7 +26,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/site.json b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/site.json
index f0a02103c34..7a25249c763 100644
--- a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/site.json
+++ b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/site.json
@@ -23,7 +23,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/timeout.json b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/timeout.json
index 611d96ca581..b3dbe1f5d4b 100644
--- a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/timeout.json
+++ b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/timeout.json
@@ -22,7 +22,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/user.json b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/user.json
index 951a7774fe4..243b0739b7b 100644
--- a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/user.json
+++ b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/user.json
@@ -23,7 +23,7 @@
},
"ext": {
"appnexus": {
- "placementId": 10433394
+ "placementId": 12883451
}
}
}
diff --git a/endpoints/openrtb2/video_auction.go b/endpoints/openrtb2/video_auction.go
index eecdc5f99d1..b8b21b762d7 100644
--- a/endpoints/openrtb2/video_auction.go
+++ b/endpoints/openrtb2/video_auction.go
@@ -65,7 +65,7 @@ func NewVideoEndpoint(ex exchange.Exchange, validator openrtb_ext.BidderParamVal
*/
func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
- ao := analytics.AuctionObject{
+ vo := analytics.VideoObject{
Status: http.StatusOK,
Errors: make([]error, 0),
}
@@ -82,7 +82,7 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re
defer func() {
deps.metricsEngine.RecordRequest(labels)
deps.metricsEngine.RecordRequestTime(labels, time.Since(start))
- deps.analytics.LogAuctionObject(&ao)
+ deps.analytics.LogVideoObject(&vo)
}()
lr := &io.LimitedReader{
@@ -91,7 +91,7 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re
}
requestJson, err := ioutil.ReadAll(lr)
if err != nil {
- handleError(&labels, w, []error{err}, &ao)
+ handleError(&labels, w, []error{err}, &vo)
return
}
@@ -102,35 +102,37 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re
if err != nil {
if deps.cfg.VideoStoredRequestRequired {
- handleError(&labels, w, []error{err}, &ao)
+ handleError(&labels, w, []error{err}, &vo)
return
}
} else {
storedRequest, errs := deps.loadStoredVideoRequest(context.Background(), storedRequestId)
if len(errs) > 0 {
- handleError(&labels, w, errs, &ao)
+ handleError(&labels, w, errs, &vo)
return
}
//merge incoming req with stored video req
resolvedRequest, err = jsonpatch.MergePatch(storedRequest, requestJson)
if err != nil {
- handleError(&labels, w, []error{err}, &ao)
+ handleError(&labels, w, []error{err}, &vo)
return
}
}
//unmarshal and validate combined result
videoBidReq, errL, podErrors := deps.parseVideoRequest(resolvedRequest)
if len(errL) > 0 {
- handleError(&labels, w, errL, &ao)
+ handleError(&labels, w, errL, &vo)
return
}
+ vo.VideoRequest = videoBidReq
+
var bidReq = &openrtb.BidRequest{}
if deps.defaultRequest {
if err := json.Unmarshal(deps.defReqJSON, bidReq); err != nil {
err = fmt.Errorf("Invalid JSON in Default Request Settings: %s", err)
- handleError(&labels, w, []error{err}, &ao)
+ handleError(&labels, w, []error{err}, &vo)
return
}
}
@@ -154,7 +156,7 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re
}
err := errors.New(fmt.Sprintf("all pods are incorrect: %s", strings.Join(resPodErr, "; ")))
errL = append(errL, err)
- handleError(&labels, w, errL, &ao)
+ handleError(&labels, w, errL, &vo)
return
}
@@ -166,7 +168,7 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re
errL = deps.validateRequest(bidReq)
if len(errL) > 0 {
- handleError(&labels, w, errL, &ao)
+ handleError(&labels, w, errL, &vo)
return
}
@@ -194,16 +196,16 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re
if acctIdErr := validateAccount(deps.cfg, labels.PubID); acctIdErr != nil {
errL = append(errL, acctIdErr)
- handleError(&labels, w, errL, &ao)
+ handleError(&labels, w, errL, &vo)
return
}
//execute auction logic
response, err := deps.ex.HoldAuction(ctx, bidReq, usersyncs, labels, &deps.categories)
- ao.Request = bidReq
- ao.Response = response
+ vo.Request = bidReq
+ vo.Response = response
if err != nil {
errL := []error{err}
- handleError(&labels, w, errL, &ao)
+ handleError(&labels, w, errL, &vo)
return
}
@@ -211,18 +213,20 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re
bidResp, err := buildVideoResponse(response, podErrors)
if err != nil {
errL := []error{err}
- handleError(&labels, w, errL, &ao)
+ handleError(&labels, w, errL, &vo)
return
}
if bidReq.Test == 1 {
bidResp.Ext = response.Ext
}
+ vo.VideoResponse = bidResp
+
resp, err := json.Marshal(bidResp)
//resp, err := json.Marshal(response)
if err != nil {
errL := []error{err}
- handleError(&labels, w, errL, &ao)
+ handleError(&labels, w, errL, &vo)
return
}
@@ -238,7 +242,7 @@ func cleanupVideoBidRequest(videoReq *openrtb_ext.BidRequestVideo, podErrors []P
return videoReq
}
-func handleError(labels *pbsmetrics.Labels, w http.ResponseWriter, errL []error, ao *analytics.AuctionObject) {
+func handleError(labels *pbsmetrics.Labels, w http.ResponseWriter, errL []error, vo *analytics.VideoObject) {
labels.RequestStatus = pbsmetrics.RequestStatusErr
var errors string
var status int = http.StatusInternalServerError
@@ -256,10 +260,10 @@ func handleError(labels *pbsmetrics.Labels, w http.ResponseWriter, errL []error,
errors = fmt.Sprintf("%s %s", errors, er.Error())
}
w.WriteHeader(status)
- ao.Status = status
+ vo.Status = status
fmt.Fprintf(w, "Critical error while running the video endpoint: %v", errors)
glog.Errorf("/openrtb2/video Critical error: %v", errors)
- ao.Errors = append(ao.Errors, errL...)
+ vo.Errors = append(vo.Errors, errL...)
}
func (deps *endpointDeps) createImpressions(videoReq *openrtb_ext.BidRequestVideo, podErrors []PodError) ([]openrtb.Imp, []PodError) {
diff --git a/endpoints/openrtb2/video_auction_test.go b/endpoints/openrtb2/video_auction_test.go
index e49a9f9cd1a..cd87041055a 100644
--- a/endpoints/openrtb2/video_auction_test.go
+++ b/endpoints/openrtb2/video_auction_test.go
@@ -650,7 +650,7 @@ func TestMergeOpenRTBToVideoRequest(t *testing.T) {
}
func TestHandleError(t *testing.T) {
- ao := analytics.AuctionObject{
+ vo := analytics.VideoObject{
Status: 200,
Errors: make([]error, 0),
}
@@ -667,14 +667,14 @@ func TestHandleError(t *testing.T) {
recorder := httptest.NewRecorder()
err1 := errors.New("Error for testing handleError 1")
err2 := errors.New("Error for testing handleError 2")
- handleError(&labels, recorder, []error{err1, err2}, &ao)
+ handleError(&labels, recorder, []error{err1, err2}, &vo)
assert.Equal(t, pbsmetrics.RequestStatusErr, labels.RequestStatus, "labels.RequestStatus should indicate an error")
assert.Equal(t, 500, recorder.Code, "Error status should be written to writer")
- assert.Equal(t, 500, ao.Status, "AnalyticsObject should have error status")
- assert.Equal(t, 2, len(ao.Errors), "New errors should be appended to AnalyticsObject Errors")
- assert.Equal(t, "Error for testing handleError 1", ao.Errors[0].Error(), "Error in AnalyticsObject should have test error message for first error")
- assert.Equal(t, "Error for testing handleError 2", ao.Errors[1].Error(), "Error in AnalyticsObject should have test error message for second error")
+ assert.Equal(t, 500, vo.Status, "Analytics object should have error status")
+ assert.Equal(t, 2, len(vo.Errors), "New errors should be appended to Analytics object Errors")
+ assert.Equal(t, "Error for testing handleError 1", vo.Errors[0].Error(), "Error in Analytics object should have test error message for first error")
+ assert.Equal(t, "Error for testing handleError 2", vo.Errors[1].Error(), "Error in Analytics object should have test error message for second error")
}
func TestHandleErrorMetrics(t *testing.T) {
@@ -692,11 +692,11 @@ func TestHandleErrorMetrics(t *testing.T) {
assert.Equal(t, int64(0), met.RequestStatuses[pbsmetrics.ReqTypeVideo][pbsmetrics.RequestStatusOK].Count(), "OK requests count should be 0")
assert.Equal(t, int64(1), met.RequestStatuses[pbsmetrics.ReqTypeVideo][pbsmetrics.RequestStatusErr].Count(), "Error requests count should be 1")
- assert.Equal(t, 1, len(mod.auctionObjects), "Mock AnalyticsModule should have 1 AuctionObject")
- assert.Equal(t, 500, mod.auctionObjects[0].Status, "AnalyticsObject should have 500 status")
- assert.Equal(t, 2, len(mod.auctionObjects[0].Errors), "AnalyticsObject should have Errors length of 2")
- assert.Equal(t, "request missing required field: PodConfig.DurationRangeSec", mod.auctionObjects[0].Errors[0].Error(), "First error in AnalyticsObject should have message regarding DurationRangeSec")
- assert.Equal(t, "request missing required field: PodConfig.Pods", mod.auctionObjects[0].Errors[1].Error(), "Second error in AnalyticsObject should have message regarding Pods")
+ assert.Equal(t, 1, len(mod.videoObjects), "Mock AnalyticsModule should have 1 AuctionObject")
+ assert.Equal(t, 500, mod.videoObjects[0].Status, "AnalyticsObject should have 500 status")
+ assert.Equal(t, 2, len(mod.videoObjects[0].Errors), "AnalyticsObject should have Errors length of 2")
+ assert.Equal(t, "request missing required field: PodConfig.DurationRangeSec", mod.videoObjects[0].Errors[0].Error(), "First error in AnalyticsObject should have message regarding DurationRangeSec")
+ assert.Equal(t, "request missing required field: PodConfig.Pods", mod.videoObjects[0].Errors[1].Error(), "Second error in AnalyticsObject should have message regarding Pods")
}
func mockDepsWithMetrics(t *testing.T, ex *mockExchangeVideo) (*endpointDeps, *pbsmetrics.Metrics, *mockAnalyticsModule) {
@@ -722,12 +722,17 @@ func mockDepsWithMetrics(t *testing.T, ex *mockExchangeVideo) (*endpointDeps, *p
type mockAnalyticsModule struct {
auctionObjects []*analytics.AuctionObject
+ videoObjects []*analytics.VideoObject
}
func (m *mockAnalyticsModule) LogAuctionObject(ao *analytics.AuctionObject) {
m.auctionObjects = append(m.auctionObjects, ao)
}
+func (m *mockAnalyticsModule) LogVideoObject(vo *analytics.VideoObject) {
+ m.videoObjects = append(m.videoObjects, vo)
+}
+
func (m *mockAnalyticsModule) LogCookieSyncObject(cso *analytics.CookieSyncObject) { return }
func (m *mockAnalyticsModule) LogSetUIDObject(so *analytics.SetUIDObject) { return }
diff --git a/exchange/adapter_map.go b/exchange/adapter_map.go
index 87931b32d14..3cb65275f1b 100644
--- a/exchange/adapter_map.go
+++ b/exchange/adapter_map.go
@@ -15,12 +15,14 @@ import (
"github.com/prebid/prebid-server/adapters/adpone"
"github.com/prebid/prebid-server/adapters/adtelligent"
"github.com/prebid/prebid-server/adapters/advangelists"
+ "github.com/prebid/prebid-server/adapters/applogy"
"github.com/prebid/prebid-server/adapters/appnexus"
"github.com/prebid/prebid-server/adapters/audienceNetwork"
"github.com/prebid/prebid-server/adapters/beachfront"
"github.com/prebid/prebid-server/adapters/brightroll"
"github.com/prebid/prebid-server/adapters/consumable"
"github.com/prebid/prebid-server/adapters/conversant"
+ "github.com/prebid/prebid-server/adapters/cpmstar"
"github.com/prebid/prebid-server/adapters/datablocks"
"github.com/prebid/prebid-server/adapters/emx_digital"
"github.com/prebid/prebid-server/adapters/engagebdr"
@@ -43,6 +45,7 @@ import (
"github.com/prebid/prebid-server/adapters/rtbhouse"
"github.com/prebid/prebid-server/adapters/rubicon"
"github.com/prebid/prebid-server/adapters/sharethrough"
+ "github.com/prebid/prebid-server/adapters/smartrtb"
"github.com/prebid/prebid-server/adapters/somoaudience"
"github.com/prebid/prebid-server/adapters/sonobi"
"github.com/prebid/prebid-server/adapters/sovrn"
@@ -72,11 +75,13 @@ func newAdapterMap(client *http.Client, cfg *config.Configuration, infos adapter
openrtb_ext.BidderAdpone: adpone.NewAdponeBidder(cfg.Adapters[string(openrtb_ext.BidderAdpone)].Endpoint),
openrtb_ext.BidderAdtelligent: adtelligent.NewAdtelligentBidder(cfg.Adapters[string(openrtb_ext.BidderAdtelligent)].Endpoint),
openrtb_ext.BidderAdvangelists: advangelists.NewAdvangelistsBidder(cfg.Adapters[string(openrtb_ext.BidderAdvangelists)].Endpoint),
+ openrtb_ext.BidderApplogy: applogy.NewApplogyBidder(cfg.Adapters[string(openrtb_ext.BidderApplogy)].Endpoint),
openrtb_ext.BidderAppnexus: appnexus.NewAppNexusBidder(client, cfg.Adapters[string(openrtb_ext.BidderAppnexus)].Endpoint, cfg.Adapters[string(openrtb_ext.BidderAppnexus)].PlatformID),
// TODO #615: Update the config setup so that the Beachfront URLs can be configured, and use those in TestRaceIntegration in exchange_test.go
openrtb_ext.BidderBeachfront: beachfront.NewBeachfrontBidder(),
openrtb_ext.BidderBrightroll: brightroll.NewBrightrollBidder(cfg.Adapters[string(openrtb_ext.BidderBrightroll)].Endpoint),
openrtb_ext.BidderConsumable: consumable.NewConsumableBidder(cfg.Adapters[string(openrtb_ext.BidderConsumable)].Endpoint),
+ openrtb_ext.BidderCpmstar: cpmstar.NewCpmstarBidder(cfg.Adapters[string(openrtb_ext.BidderCpmstar)].Endpoint),
openrtb_ext.BidderDatablocks: datablocks.NewDatablocksBidder(cfg.Adapters[string(openrtb_ext.BidderDatablocks)].Endpoint),
openrtb_ext.BidderEmxDigital: emx_digital.NewEmxDigitalBidder(cfg.Adapters[string(openrtb_ext.BidderEmxDigital)].Endpoint),
openrtb_ext.BidderEngageBDR: engagebdr.NewEngageBDRBidder(client, cfg.Adapters[string(openrtb_ext.BidderEngageBDR)].Endpoint),
@@ -107,6 +112,7 @@ func newAdapterMap(client *http.Client, cfg *config.Configuration, infos adapter
cfg.Adapters[string(openrtb_ext.BidderRubicon)].XAPI.Tracker),
openrtb_ext.BidderSharethrough: sharethrough.NewSharethroughBidder(cfg.Adapters[string(openrtb_ext.BidderSharethrough)].Endpoint),
+ openrtb_ext.BidderSmartRTB: smartrtb.NewSmartRTBBidder(cfg.Adapters[string(openrtb_ext.BidderSmartRTB)].Endpoint),
openrtb_ext.BidderSomoaudience: somoaudience.NewSomoaudienceBidder(cfg.Adapters[string(openrtb_ext.BidderSomoaudience)].Endpoint),
openrtb_ext.BidderSonobi: sonobi.NewSonobiBidder(client, cfg.Adapters[string(openrtb_ext.BidderSonobi)].Endpoint),
openrtb_ext.BidderSovrn: sovrn.NewSovrnBidder(client, cfg.Adapters[string(openrtb_ext.BidderSovrn)].Endpoint),
diff --git a/exchange/bidder.go b/exchange/bidder.go
index 5708660057f..d9a28fee175 100644
--- a/exchange/bidder.go
+++ b/exchange/bidder.go
@@ -8,6 +8,7 @@ import (
"fmt"
"io/ioutil"
"net/http"
+ "time"
"github.com/mxmCherry/openrtb"
nativeRequests "github.com/mxmCherry/openrtb/native/request"
@@ -295,6 +296,14 @@ func (bidder *bidderAdapter) doRequest(ctx context.Context, req *adapters.Reques
if err != nil {
if err == context.DeadlineExceeded {
err = &errortypes.Timeout{Message: err.Error()}
+ if tb, ok := bidder.Bidder.(adapters.TimeoutBidder); ok {
+ // Toss the timeout notification call into a go routine, as we are out of time'
+ // and cannot delay processing. We don't do anything result, as there is not much
+ // we can do about a timeout notification failure. We do not want to get stuck in
+ // a loop of trying to report timeouts to the timeout notifications.
+ go bidder.doTimeoutNotification(tb, req)
+ }
+
}
return &httpCallInfo{
request: req,
@@ -328,6 +337,21 @@ func (bidder *bidderAdapter) doRequest(ctx context.Context, req *adapters.Reques
}
}
+func (bidder *bidderAdapter) doTimeoutNotification(timeoutBidder adapters.TimeoutBidder, req *adapters.RequestData) {
+ ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond)
+ defer cancel()
+ toReq, errL := timeoutBidder.MakeTimeoutNotification(req)
+ if toReq != nil && len(errL) == 0 {
+ httpReq, err := http.NewRequest(toReq.Method, toReq.Uri, bytes.NewBuffer(toReq.Body))
+ if err == nil {
+ httpReq.Header = req.Headers
+ ctxhttp.Do(ctx, bidder.Client, httpReq)
+ // No validation yet on sending notifications
+ }
+ }
+
+}
+
type httpCallInfo struct {
request *adapters.RequestData
response *adapters.ResponseData
diff --git a/exchange/exchange.go b/exchange/exchange.go
index 071b4f8d771..8c6cac4cfcd 100644
--- a/exchange/exchange.go
+++ b/exchange/exchange.go
@@ -4,6 +4,7 @@ import (
"bytes"
"context"
"encoding/json"
+ "errors"
"fmt"
"math/rand"
"net/http"
@@ -146,10 +147,14 @@ func (e *exchange) HoldAuction(ctx context.Context, bidRequest *openrtb.BidReque
//If includebrandcategory is present in ext then CE feature is on.
if requestExt.Prebid.Targeting != nil && requestExt.Prebid.Targeting.IncludeBrandCategory != nil {
var err error
- bidCategory, adapterBids, err = applyCategoryMapping(ctx, requestExt, adapterBids, *categoriesFetcher, targData)
+ var rejections []string
+ bidCategory, adapterBids, rejections, err = applyCategoryMapping(ctx, requestExt, adapterBids, *categoriesFetcher, targData)
if err != nil {
return nil, fmt.Errorf("Error in category mapping : %s", err.Error())
}
+ for _, message := range rejections {
+ errs = append(errs, errors.New(message))
+ }
}
auc = newAuction(adapterBids, len(bidRequest.Imp))
@@ -324,6 +329,7 @@ func (e *exchange) buildBidResponse(ctx context.Context, liveAdapters []openrtb_
if adapterBids[a] != nil && len(adapterBids[a].bids) > 0 {
sb := e.makeSeatBid(adapterBids[a], a, adapterExtra, auc)
seatBids = append(seatBids, *sb)
+ bidResponse.Cur = adapterBids[a].currency
}
}
@@ -339,7 +345,7 @@ func (e *exchange) buildBidResponse(ctx context.Context, liveAdapters []openrtb_
return bidResponse, err
}
-func applyCategoryMapping(ctx context.Context, requestExt openrtb_ext.ExtRequest, seatBids map[openrtb_ext.BidderName]*pbsOrtbSeatBid, categoriesFetcher stored_requests.CategoryFetcher, targData *targetData) (map[string]string, map[openrtb_ext.BidderName]*pbsOrtbSeatBid, error) {
+func applyCategoryMapping(ctx context.Context, requestExt openrtb_ext.ExtRequest, seatBids map[openrtb_ext.BidderName]*pbsOrtbSeatBid, categoriesFetcher stored_requests.CategoryFetcher, targData *targetData) (map[string]string, map[openrtb_ext.BidderName]*pbsOrtbSeatBid, []string, error) {
res := make(map[string]string)
type bidDedupe struct {
@@ -358,6 +364,7 @@ func applyCategoryMapping(ctx context.Context, requestExt openrtb_ext.ExtRequest
var primaryAdServer string
var publisher string
var err error
+ var rejections []string
var translateCategories = true
if includeBrandCategory && brandCatExt.WithCategory {
@@ -369,7 +376,7 @@ func applyCategoryMapping(ctx context.Context, requestExt openrtb_ext.ExtRequest
//if ext.prebid.targeting.includebrandcategory present but primaryadserver/publisher not present then error out the request right away.
primaryAdServer, err = getPrimaryAdServer(brandCatExt.PrimaryAdServer) //1-Freewheel 2-DFP
if err != nil {
- return res, seatBids, err
+ return res, seatBids, rejections, err
}
publisher = brandCatExt.Publisher
}
@@ -381,6 +388,7 @@ func applyCategoryMapping(ctx context.Context, requestExt openrtb_ext.ExtRequest
bidsToRemove := make([]int, 0)
for bidInd := range seatBid.bids {
bid := seatBid.bids[bidInd]
+ bidID := bid.bid.ID
var duration int
var category string
var pb string
@@ -395,6 +403,7 @@ func applyCategoryMapping(ctx context.Context, requestExt openrtb_ext.ExtRequest
//TODO: add metrics
//on receiving bids from adapters if no unique IAB category is returned or if no ad server category is returned discard the bid
bidsToRemove = append(bidsToRemove, bidInd)
+ rejections = updateRejections(rejections, bidID, "Bid did not contain a category")
continue
}
if translateCategories {
@@ -404,6 +413,8 @@ func applyCategoryMapping(ctx context.Context, requestExt openrtb_ext.ExtRequest
//TODO: add metrics
//if mapping required but no mapping file is found then discard the bid
bidsToRemove = append(bidsToRemove, bidInd)
+ reason := fmt.Sprintf("Category mapping file for primary ad server: '%s', publisher: '%s' not found", primaryAdServer, publisher)
+ rejections = updateRejections(rejections, bidID, reason)
continue
}
} else {
@@ -423,6 +434,7 @@ func applyCategoryMapping(ctx context.Context, requestExt openrtb_ext.ExtRequest
//if the bid is above the range of the listed durations (and outside the buffer), reject the bid
if duration > durationRange[len(durationRange)-1] {
bidsToRemove = append(bidsToRemove, bidInd)
+ rejections = updateRejections(rejections, bidID, "Bid duration exceeds maximum allowed")
continue
}
for _, dur := range durationRange {
@@ -446,11 +458,13 @@ func applyCategoryMapping(ctx context.Context, requestExt openrtb_ext.ExtRequest
if dupe.bidderName == bidderName {
// An older bid from the current bidder
bidsToRemove = append(bidsToRemove, dupe.bidIndex)
+ rejections = updateRejections(rejections, dupe.bidID, "Bid was deduplicated")
} else {
// An older bid from a different seatBid we've already finished with
oldSeatBid := (seatBids)[dupe.bidderName]
if len(oldSeatBid.bids) == 1 {
seatBidsToRemove = append(seatBidsToRemove, bidderName)
+ rejections = updateRejections(rejections, dupe.bidID, "Bid was deduplicated")
} else {
oldSeatBid.bids = append(oldSeatBid.bids[:dupe.bidIndex], oldSeatBid.bids[dupe.bidIndex+1:]...)
}
@@ -459,11 +473,12 @@ func applyCategoryMapping(ctx context.Context, requestExt openrtb_ext.ExtRequest
} else {
// Remove this bid
bidsToRemove = append(bidsToRemove, bidInd)
+ rejections = updateRejections(rejections, bidID, "Bid was deduplicated")
continue
}
}
- res[bid.bid.ID] = categoryDuration
- dedupe[categoryDuration] = bidDedupe{bidderName: bidderName, bidIndex: bidInd, bidID: bid.bid.ID}
+ res[bidID] = categoryDuration
+ dedupe[categoryDuration] = bidDedupe{bidderName: bidderName, bidIndex: bidInd, bidID: bidID}
}
if len(bidsToRemove) > 0 {
@@ -482,19 +497,16 @@ func applyCategoryMapping(ctx context.Context, requestExt openrtb_ext.ExtRequest
}
}
- if len(seatBidsToRemove) > 0 {
- if len(seatBidsToRemove) == len(seatBids) {
- //delete all seat bids
- seatBids = nil
- } else {
- for _, seatBidInd := range seatBidsToRemove {
- delete(seatBids, seatBidInd)
- }
-
- }
+ for _, seatBidInd := range seatBidsToRemove {
+ seatBids[seatBidInd].bids = nil
}
- return res, seatBids, nil
+ return res, seatBids, rejections, nil
+}
+
+func updateRejections(rejections []string, bidID string, reason string) []string {
+ message := fmt.Sprintf("bid rejected [bid ID: %s] reason: %s", bidID, reason)
+ return append(rejections, message)
}
func getPrimaryAdServer(adServerId int) (string, error) {
diff --git a/exchange/exchange_test.go b/exchange/exchange_test.go
index 6718eb7df80..7e199d4b750 100644
--- a/exchange/exchange_test.go
+++ b/exchange/exchange_test.go
@@ -9,6 +9,7 @@ import (
"io/ioutil"
"net/http"
"net/http/httptest"
+ "regexp"
"strconv"
"strings"
"testing"
@@ -103,17 +104,17 @@ func TestCharacterEscape(t *testing.T) {
Imp: []openrtb.Imp{{
ID: "some-impression-id",
Banner: &openrtb.Banner{Format: []openrtb.Format{{W: 300, H: 250}, {W: 300, H: 600}}},
- Ext: json.RawMessage(`{"appnexus": {"placementId": 10433394}}`),
+ Ext: json.RawMessage(`{"appnexus": {"placementId": 1}}`),
}},
Site: &openrtb.Site{Page: "prebid.org", Ext: json.RawMessage(`{"amp":0}`)},
Device: &openrtb.Device{UA: "curl/7.54.0", IP: "::1"},
AT: 1,
TMax: 500,
- Ext: json.RawMessage(`{"id": "some-request-id","site": {"page": "prebid.org"},"imp": [{"id": "some-impression-id","banner": {"format": [{"w": 300,"h": 250},{"w": 300,"h": 600}]},"ext": {"appnexus": {"placementId": 10433394}}}],"tmax": 500}`),
+ Ext: json.RawMessage(`{"id": "some-request-id","site": {"page": "prebid.org"},"imp": [{"id": "some-impression-id","banner": {"format": [{"w": 300,"h": 250},{"w": 300,"h": 600}]},"ext": {"appnexus": {"placementId": 1}}}],"tmax": 500}`),
}
//resolvedRequest json.RawMessage
- resolvedRequest := json.RawMessage(`{"id": "some-request-id","site": {"page": "prebid.org"},"imp": [{"id": "some-impression-id","banner": {"format": [{"w": 300,"h": 250},{"w": 300,"h": 600}]},"ext": {"appnexus": {"placementId": 10433394}}}],"tmax": 500}`)
+ resolvedRequest := json.RawMessage(`{"id": "some-request-id","site": {"page": "prebid.org"},"imp": [{"id": "some-impression-id","banner": {"format": [{"w": 300,"h": 250},{"w": 300,"h": 600}]},"ext": {"appnexus": {"placementId": 1}}}],"tmax": 500}`)
//adapterExtra map[openrtb_ext.BidderName]*seatResponseExtra,
adapterExtra := make(map[openrtb_ext.BidderName]*seatResponseExtra, 1)
@@ -170,7 +171,7 @@ func TestGetBidCacheInfo(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(handlerNoBidServer))
defer server.Close()
- e := NewExchange(server.Client(), pbc.NewClient(&cfg.CacheURL, &cfg.ExtCacheURL, testEngine), cfg, pbsmetrics.NewMetrics(metrics.NewRegistry(), openrtb_ext.BidderList(), config.DisabledMetrics{}), adapters.ParseBidderInfos(cfg.Adapters, "../static/bidder-info", openrtb_ext.BidderList()), gdpr.AlwaysAllow{}, currencies.NewRateConverterDefault()).(*exchange)
+ e := NewExchange(server.Client(), pbc.NewClient(&http.Client{}, &cfg.CacheURL, &cfg.ExtCacheURL, testEngine), cfg, pbsmetrics.NewMetrics(metrics.NewRegistry(), openrtb_ext.BidderList(), config.DisabledMetrics{}), adapters.ParseBidderInfos(cfg.Adapters, "../static/bidder-info", openrtb_ext.BidderList()), gdpr.AlwaysAllow{}, currencies.NewRateConverterDefault()).(*exchange)
/* 3) Build all the parameters e.buildBidResponse(ctx.Background(), liveA... ) needs */
liveAdapters := []openrtb_ext.BidderName{bidderName}
@@ -231,7 +232,7 @@ func TestGetBidCacheInfo(t *testing.T) {
}
//resolvedRequest json.RawMessage
- resolvedRequest := json.RawMessage(`{"id": "some-request-id","site": {"page": "prebid.org"},"imp": [{"id": "some-impression-id","banner": {"format": [{"w": 300,"h": 250},{"w": 300,"h": 600}]},"ext": {"appnexus": {"placementId": 10433394}}}],"tmax": 500}`)
+ resolvedRequest := json.RawMessage(`{"id": "some-request-id","site": {"page": "prebid.org"},"imp": [{"id": "some-impression-id","banner": {"format": [{"w": 300,"h": 250},{"w": 300,"h": 600}]},"ext": {"appnexus": {"placementId": 1}}}],"tmax": 500}`)
//adapterExtra map[openrtb_ext.BidderName]*seatResponseExtra,
adapterExtra := map[openrtb_ext.BidderName]*seatResponseExtra{
@@ -259,7 +260,7 @@ func TestGetBidCacheInfo(t *testing.T) {
"siteId": 113932,
"zoneId": 535510
},
- "appnexus": { "placementId": 10433394 },
+ "appnexus": { "placementId": 1 },
"pubmatic": { "publisherId": "156209", "adSlot": "pubmatic_test2@300x250" },
"pulsepoint": { "cf": "300X250", "cp": 512379, "ct": 486653 },
"conversant": { "site_id": "108060" },
@@ -314,51 +315,145 @@ func TestGetBidCacheInfo(t *testing.T) {
assert.Equal(t, expCacheURL, cacheURL, "[TestGetBidCacheInfo] cacheId field in ext should equal \"%s\" \n", expCacheURL)
}
-func buildBidResponseParams(bidderName openrtb_ext.BidderName, bidRequest *openrtb.BidRequest) ([]openrtb_ext.BidderName, map[openrtb_ext.BidderName]*pbsOrtbSeatBid, json.RawMessage, map[openrtb_ext.BidderName]*seatResponseExtra) {
- //liveAdapters []openrtb_ext.BidderName,
- liveAdapters := []openrtb_ext.BidderName{bidderName}
+func TestBidResponseCurrency(t *testing.T) {
+ // Init objects
+ cfg := &config.Configuration{Adapters: make(map[string]config.Adapter, 1)}
+ cfg.Adapters["appnexus"] = config.Adapter{Endpoint: "http://ib.adnxs.com"}
- //adapterBids map[openrtb_ext.BidderName]*pbsOrtbSeatBid,
- adapterBids := map[openrtb_ext.BidderName]*pbsOrtbSeatBid{
- bidderName: {
- bids: []*pbsOrtbBid{
+ handlerNoBidServer := func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(204) }
+ server := httptest.NewServer(http.HandlerFunc(handlerNoBidServer))
+ defer server.Close()
+
+ e := NewExchange(server.Client(), nil, cfg, pbsmetrics.NewMetrics(metrics.NewRegistry(), openrtb_ext.BidderList(), config.DisabledMetrics{}), adapters.ParseBidderInfos(cfg.Adapters, "../static/bidder-info", openrtb_ext.BidderList()), gdpr.AlwaysAllow{}, currencies.NewRateConverterDefault()).(*exchange)
+
+ liveAdapters := make([]openrtb_ext.BidderName, 1)
+ liveAdapters[0] = "appnexus"
+
+ bidRequest := &openrtb.BidRequest{
+ ID: "some-request-id",
+ Imp: []openrtb.Imp{{
+ ID: "some-impression-id",
+ Banner: &openrtb.Banner{Format: []openrtb.Format{{W: 300, H: 250}, {W: 300, H: 600}}},
+ Ext: json.RawMessage(`{"appnexus": {"placementId": 10433394}}`),
+ }},
+ Site: &openrtb.Site{Page: "prebid.org", Ext: json.RawMessage(`{"amp":0}`)},
+ Device: &openrtb.Device{UA: "curl/7.54.0", IP: "::1"},
+ AT: 1,
+ TMax: 500,
+ Ext: json.RawMessage(`{"id": "some-request-id","site": {"page": "prebid.org"},"imp": [{"id": "some-impression-id","banner": {"format": [{"w": 300,"h": 250},{"w": 300,"h": 600}]},"ext": {"appnexus": {"placementId": 10433394}}}],"tmax": 500}`),
+ }
+
+ resolvedRequest := json.RawMessage(`{"id": "some-request-id","site": {"page": "prebid.org"},"imp": [{"id": "some-impression-id","banner": {"format": [{"w": 300,"h": 250},{"w": 300,"h": 600}]},"ext": {"appnexus": {"placementId": 1}}}],"tmax": 500}`)
+
+ adapterExtra := map[openrtb_ext.BidderName]*seatResponseExtra{
+ "appnexus": {ResponseTimeMillis: 5},
+ }
+
+ var errList []error
+
+ sampleBid := &openrtb.Bid{
+ ID: "some-imp-id",
+ Price: 9.517803,
+ W: 300,
+ H: 250,
+ Ext: nil,
+ }
+ aPbsOrtbBidArr := []*pbsOrtbBid{{bid: sampleBid, bidType: openrtb_ext.BidTypeBanner}}
+ sampleSeatBid := []openrtb.SeatBid{
+ {
+ Seat: "appnexus",
+ Bid: []openrtb.Bid{
{
- bid: &openrtb.Bid{
- ID: "some-imp-id",
- Price: 9.517803,
- W: 300,
- H: 250,
- },
- bidType: openrtb_ext.BidTypeBanner,
- bidTargets: map[string]string{
- "pricegranularity": "med",
- "includewinners": "true",
- "includebidderkeys": "false",
- },
+ ID: "some-imp-id",
+ Price: 9.517803,
+ W: 300,
+ H: 250,
+ Ext: json.RawMessage(`{"prebid":{"type":"banner"}}`),
},
},
- currency: "USD",
- //ext: bidRequest.Ext,
},
}
+ emptySeatBid := []openrtb.SeatBid{}
- //resolvedRequest json.RawMessage
- resolvedRequest := json.RawMessage(`{"id": "some-request-id","site": {"page": "prebid.org"},"imp": [{"id": "some-impression-id","banner": {"format": [{"w": 300,"h": 250},{"w": 300,"h": 600}]},"ext": {"appnexus": {"placementId": 10433394}}}],"tmax": 500}`)
-
- //adapterExtra map[openrtb_ext.BidderName]*seatResponseExtra,
- adapterExtra := map[openrtb_ext.BidderName]*seatResponseExtra{
- bidderName: {
- ResponseTimeMillis: 5,
- Errors: []openrtb_ext.ExtBidderError{
- {
- Code: 999,
- Message: "Post ib.adnxs.com/openrtb2?query1&query2: unsupported protocol scheme \"\"",
+ // Test cases
+ type aTest struct {
+ description string
+ adapterBids map[openrtb_ext.BidderName]*pbsOrtbSeatBid
+ expectedBidResponse *openrtb.BidResponse
+ }
+ testCases := []aTest{
+ {
+ description: "1) Adapter to bids map comes with a non-empty currency field and non-empty bid array",
+ adapterBids: map[openrtb_ext.BidderName]*pbsOrtbSeatBid{
+ openrtb_ext.BidderName("appnexus"): {
+ bids: aPbsOrtbBidArr,
+ currency: "USD",
+ },
+ },
+ expectedBidResponse: &openrtb.BidResponse{
+ ID: "some-request-id",
+ SeatBid: sampleSeatBid,
+ Cur: "USD",
+ Ext: json.RawMessage(`{"responsetimemillis":{"appnexus":5},"tmaxrequest":500}
+`),
+ },
+ },
+ {
+ description: "2) Adapter to bids map comes with a non-empty currency field but an empty bid array",
+ adapterBids: map[openrtb_ext.BidderName]*pbsOrtbSeatBid{
+ openrtb_ext.BidderName("appnexus"): {
+ bids: nil,
+ currency: "USD",
+ },
+ },
+ expectedBidResponse: &openrtb.BidResponse{
+ ID: "some-request-id",
+ SeatBid: emptySeatBid,
+ Cur: "",
+ Ext: json.RawMessage(`{"responsetimemillis":{"appnexus":5},"tmaxrequest":500}
+`),
+ },
+ },
+ {
+ description: "3) Adapter to bids map comes with an empty currency string and a non-empty bid array",
+ adapterBids: map[openrtb_ext.BidderName]*pbsOrtbSeatBid{
+ openrtb_ext.BidderName("appnexus"): {
+ bids: aPbsOrtbBidArr,
+ currency: "",
+ },
+ },
+ expectedBidResponse: &openrtb.BidResponse{
+ ID: "some-request-id",
+ SeatBid: sampleSeatBid,
+ Cur: "",
+ Ext: json.RawMessage(`{"responsetimemillis":{"appnexus":5},"tmaxrequest":500}
+`),
+ },
+ },
+ {
+ description: "4) Adapter to bids map comes with an empty currency string and an empty bid array",
+ adapterBids: map[openrtb_ext.BidderName]*pbsOrtbSeatBid{
+ openrtb_ext.BidderName("appnexus"): {
+ bids: nil,
+ currency: "",
},
},
+ expectedBidResponse: &openrtb.BidResponse{
+ ID: "some-request-id",
+ SeatBid: emptySeatBid,
+ Cur: "",
+ Ext: json.RawMessage(`{"responsetimemillis":{"appnexus":5},"tmaxrequest":500}
+`),
+ },
},
}
- return liveAdapters, adapterBids, resolvedRequest, adapterExtra
+ // Run tests
+ for i := range testCases {
+ actualBidResp, err := e.buildBidResponse(context.Background(), liveAdapters, testCases[i].adapterBids, bidRequest, resolvedRequest, adapterExtra, nil, errList)
+ assert.NoError(t, err, fmt.Sprintf("[TEST_FAILED] e.buildBidResponse resturns error in test: %s Error message: %s \n", testCases[i].description, err))
+ assert.Equalf(t, testCases[i].expectedBidResponse, actualBidResp, fmt.Sprintf("[TEST_FAILED] Objects must be equal for test: %s \n Expected: >>%s<< \n Actual: >>%s<< ", testCases[i].description, testCases[i].expectedBidResponse.Ext, actualBidResp.Ext))
+ }
}
// TestRaceIntegration runs an integration test using all the sample params from
@@ -836,9 +931,11 @@ func TestCategoryMapping(t *testing.T) {
adapterBids[bidderName1] = &seatBid
- bidCategory, adapterBids, err := applyCategoryMapping(nil, requestExt, adapterBids, categoriesFetcher, targData)
+ bidCategory, adapterBids, rejections, err := applyCategoryMapping(nil, requestExt, adapterBids, categoriesFetcher, targData)
assert.Equal(t, nil, err, "Category mapping error should be empty")
+ assert.Equal(t, 1, len(rejections), "There should be 1 bid rejection message")
+ assert.Equal(t, "bid rejected [bid ID: bid_id4] reason: Category mapping file for primary ad server: 'freewheel', publisher: '' not found", rejections[0], "Rejection message did not match expected")
assert.Equal(t, "10.00_Electronics_30s", bidCategory["bid_id1"], "Category mapping doesn't match")
assert.Equal(t, "20.00_Sports_50s", bidCategory["bid_id2"], "Category mapping doesn't match")
assert.Equal(t, "20.00_AdapterOverride_30s", bidCategory["bid_id3"], "Category mapping override from adapter didn't take")
@@ -889,9 +986,10 @@ func TestCategoryMappingNoIncludeBrandCategory(t *testing.T) {
adapterBids[bidderName1] = &seatBid
- bidCategory, adapterBids, err := applyCategoryMapping(nil, requestExt, adapterBids, categoriesFetcher, targData)
+ bidCategory, adapterBids, rejections, err := applyCategoryMapping(nil, requestExt, adapterBids, categoriesFetcher, targData)
assert.Equal(t, nil, err, "Category mapping error should be empty")
+ assert.Empty(t, rejections, "There should be no bid rejection messages")
assert.Equal(t, "10.00_30s", bidCategory["bid_id1"], "Category mapping doesn't match")
assert.Equal(t, "20.00_40s", bidCategory["bid_id2"], "Category mapping doesn't match")
assert.Equal(t, "20.00_30s", bidCategory["bid_id3"], "Category mapping doesn't match")
@@ -940,9 +1038,11 @@ func TestCategoryMappingTranslateCategoriesNil(t *testing.T) {
adapterBids[bidderName1] = &seatBid
- bidCategory, adapterBids, err := applyCategoryMapping(nil, requestExt, adapterBids, categoriesFetcher, targData)
+ bidCategory, adapterBids, rejections, err := applyCategoryMapping(nil, requestExt, adapterBids, categoriesFetcher, targData)
assert.Equal(t, nil, err, "Category mapping error should be empty")
+ assert.Equal(t, 1, len(rejections), "There should be 1 bid rejection message")
+ assert.Equal(t, "bid rejected [bid ID: bid_id3] reason: Category mapping file for primary ad server: 'freewheel', publisher: '' not found", rejections[0], "Rejection message did not match expected")
assert.Equal(t, "10.00_Electronics_30s", bidCategory["bid_id1"], "Category mapping doesn't match")
assert.Equal(t, "20.00_Sports_50s", bidCategory["bid_id2"], "Category mapping doesn't match")
assert.Equal(t, 2, len(adapterBids[bidderName1].bids), "Bidders number doesn't match")
@@ -1020,9 +1120,10 @@ func TestCategoryMappingTranslateCategoriesFalse(t *testing.T) {
adapterBids[bidderName1] = &seatBid
- bidCategory, adapterBids, err := applyCategoryMapping(nil, requestExt, adapterBids, categoriesFetcher, targData)
+ bidCategory, adapterBids, rejections, err := applyCategoryMapping(nil, requestExt, adapterBids, categoriesFetcher, targData)
assert.Equal(t, nil, err, "Category mapping error should be empty")
+ assert.Empty(t, rejections, "There should be no bid rejection messages")
assert.Equal(t, "10.00_IAB1-3_30s", bidCategory["bid_id1"], "Category should not be translated")
assert.Equal(t, "20.00_IAB1-4_50s", bidCategory["bid_id2"], "Category should not be translated")
assert.Equal(t, "20.00_IAB1-1000_30s", bidCategory["bid_id3"], "Bid should not be rejected")
@@ -1085,9 +1186,12 @@ func TestCategoryDedupe(t *testing.T) {
adapterBids[bidderName1] = &seatBid
- bidCategory, adapterBids, err := applyCategoryMapping(nil, requestExt, adapterBids, categoriesFetcher, targData)
+ bidCategory, adapterBids, rejections, err := applyCategoryMapping(nil, requestExt, adapterBids, categoriesFetcher, targData)
assert.Equal(t, nil, err, "Category mapping error should be empty")
+ assert.Equal(t, 2, len(rejections), "There should be 2 bid rejection messages")
+ assert.Regexpf(t, regexp.MustCompile(`bid rejected \[bid ID: bid_id(1|3)\] reason: Bid was deduplicated`), rejections[0], "Rejection message did not match expected")
+ assert.Equal(t, "bid rejected [bid ID: bid_id4] reason: Category mapping file for primary ad server: 'freewheel', publisher: '' not found", rejections[1], "Rejection message did not match expected")
assert.Equal(t, 2, len(adapterBids[bidderName1].bids), "Bidders number doesn't match")
assert.Equal(t, 2, len(bidCategory), "Bidders category mapping doesn't match")
@@ -1102,6 +1206,125 @@ func TestCategoryDedupe(t *testing.T) {
assert.NotEqual(t, numIterations, selectedBids["bid_id3"], "Bid 3 made it through every time")
}
+func TestBidRejectionErrors(t *testing.T) {
+ categoriesFetcher, error := newCategoryFetcher("./test/category-mapping")
+ if error != nil {
+ t.Errorf("Failed to create a category Fetcher: %v", error)
+ }
+
+ requestExt := newExtRequest()
+ requestExt.Prebid.Targeting.DurationRangeSec = []int{15, 30, 50}
+
+ targData := &targetData{
+ priceGranularity: requestExt.Prebid.Targeting.PriceGranularity,
+ includeWinners: true,
+ }
+
+ invalidReqExt := newExtRequest()
+ invalidReqExt.Prebid.Targeting.DurationRangeSec = []int{15, 30, 50}
+ invalidReqExt.Prebid.Targeting.IncludeBrandCategory.PrimaryAdServer = 2
+ invalidReqExt.Prebid.Targeting.IncludeBrandCategory.Publisher = "some_publisher"
+
+ adapterBids := make(map[openrtb_ext.BidderName]*pbsOrtbSeatBid)
+ bidderName := openrtb_ext.BidderName("appnexus")
+
+ testCases := []struct {
+ description string
+ reqExt openrtb_ext.ExtRequest
+ bids []*openrtb.Bid
+ duration int
+ expectedRejections []string
+ expectedCatDur string
+ }{
+ {
+ description: "Bid should be rejected due to not containing a category",
+ reqExt: requestExt,
+ bids: []*openrtb.Bid{
+ {ID: "bid_id1", ImpID: "imp_id1", Price: 10.0000, Cat: []string{}, W: 1, H: 1},
+ },
+ duration: 30,
+ expectedRejections: []string{
+ "bid rejected [bid ID: bid_id1] reason: Bid did not contain a category",
+ },
+ },
+ {
+ description: "Bid should be rejected due to missing category mapping file",
+ reqExt: invalidReqExt,
+ bids: []*openrtb.Bid{
+ {ID: "bid_id1", ImpID: "imp_id1", Price: 10.0000, Cat: []string{"IAB1-1"}, W: 1, H: 1},
+ },
+ duration: 30,
+ expectedRejections: []string{
+ "bid rejected [bid ID: bid_id1] reason: Category mapping file for primary ad server: 'dfp', publisher: 'some_publisher' not found",
+ },
+ },
+ {
+ description: "Bid should be rejected due to duration exceeding maximum",
+ reqExt: requestExt,
+ bids: []*openrtb.Bid{
+ {ID: "bid_id1", ImpID: "imp_id1", Price: 10.0000, Cat: []string{"IAB1-1"}, W: 1, H: 1},
+ },
+ duration: 70,
+ expectedRejections: []string{
+ "bid rejected [bid ID: bid_id1] reason: Bid duration exceeds maximum allowed",
+ },
+ },
+ {
+ description: "Bid should be rejected due to duplicate bid",
+ reqExt: requestExt,
+ bids: []*openrtb.Bid{
+ {ID: "bid_id1", ImpID: "imp_id1", Price: 10.0000, Cat: []string{"IAB1-1"}, W: 1, H: 1},
+ {ID: "bid_id1", ImpID: "imp_id1", Price: 10.0000, Cat: []string{"IAB1-1"}, W: 1, H: 1},
+ },
+ duration: 30,
+ expectedRejections: []string{
+ "bid rejected [bid ID: bid_id1] reason: Bid was deduplicated",
+ },
+ expectedCatDur: "10.00_VideoGames_30s",
+ },
+ }
+
+ for _, test := range testCases {
+ innerBids := []*pbsOrtbBid{}
+ for _, bid := range test.bids {
+ currentBid := pbsOrtbBid{
+ bid, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: test.duration},
+ }
+ innerBids = append(innerBids, ¤tBid)
+ }
+
+ seatBid := pbsOrtbSeatBid{innerBids, "USD", nil, nil}
+
+ adapterBids[bidderName] = &seatBid
+
+ bidCategory, adapterBids, rejections, err := applyCategoryMapping(nil, test.reqExt, adapterBids, categoriesFetcher, targData)
+
+ if len(test.expectedCatDur) > 0 {
+ // Bid deduplication case
+ assert.Equal(t, 1, len(adapterBids[bidderName].bids), "Bidders number doesn't match")
+ assert.Equal(t, 1, len(bidCategory), "Bidders category mapping doesn't match")
+ assert.Equal(t, test.expectedCatDur, bidCategory["bid_id1"], "Bid category did not contain expected hb_pb_cat_dur")
+ } else {
+ assert.Empty(t, adapterBids[bidderName].bids, "Bidders number doesn't match")
+ assert.Empty(t, bidCategory, "Bidders category mapping doesn't match")
+ }
+
+ assert.Empty(t, err, "Category mapping error should be empty")
+ assert.Equal(t, test.expectedRejections, rejections, test.description)
+ }
+}
+
+func TestUpdateRejections(t *testing.T) {
+ rejections := []string{}
+
+ rejections = updateRejections(rejections, "bid_id1", "some reason 1")
+ rejections = updateRejections(rejections, "bid_id2", "some reason 2")
+
+ assert.Equal(t, 2, len(rejections), "Rejections should contain 2 rejection messages")
+ assert.Containsf(t, rejections, "bid rejected [bid ID: bid_id1] reason: some reason 1", "Rejection message did not match expected")
+ assert.Containsf(t, rejections, "bid rejected [bid ID: bid_id2] reason: some reason 2", "Rejection message did not match expected")
+}
+
type exchangeSpec struct {
IncomingRequest exchangeRequest `json:"incomingRequest"`
OutgoingRequests map[string]*bidderSpec `json:"outgoingRequests"`
diff --git a/exchange/utils_test.go b/exchange/utils_test.go
index 4ccded46c68..edbe04a0d0f 100644
--- a/exchange/utils_test.go
+++ b/exchange/utils_test.go
@@ -153,7 +153,7 @@ func newAdapterAliasBidRequest(t *testing.T) *openrtb.BidRequest {
H: 600,
}},
},
- Ext: json.RawMessage(`{"appnexus": {"placementId": 10433394},"brightroll": {"placementId": 105}}`),
+ Ext: json.RawMessage(`{"appnexus": {"placementId": 1},"brightroll": {"placementId": 105}}`),
}},
Ext: json.RawMessage(`{"prebid":{"aliases":{"brightroll":"appnexus"}}}`),
}
@@ -199,7 +199,7 @@ func newCCPABidRequest(t *testing.T) *openrtb.BidRequest {
H: 600,
}},
},
- Ext: json.RawMessage(`{"appnexus": {"placementId": 10433394}}`),
+ Ext: json.RawMessage(`{"appnexus": {"placementId": 1}}`),
}},
}
}
diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go
index 80ee84706eb..197260d511e 100644
--- a/openrtb_ext/bidders.go
+++ b/openrtb_ext/bidders.go
@@ -27,11 +27,13 @@ const (
BidderAdpone BidderName = "adpone"
BidderAdtelligent BidderName = "adtelligent"
BidderAdvangelists BidderName = "advangelists"
+ BidderApplogy BidderName = "applogy"
BidderAppnexus BidderName = "appnexus"
BidderBeachfront BidderName = "beachfront"
BidderBrightroll BidderName = "brightroll"
BidderConsumable BidderName = "consumable"
BidderConversant BidderName = "conversant"
+ BidderCpmstar BidderName = "cpmstar"
BidderDatablocks BidderName = "datablocks"
BidderEmxDigital BidderName = "emx_digital"
BidderEngageBDR BidderName = "engagebdr"
@@ -56,6 +58,7 @@ const (
BidderRTBHouse BidderName = "rtbhouse"
BidderRubicon BidderName = "rubicon"
BidderSharethrough BidderName = "sharethrough"
+ BidderSmartRTB BidderName = "smartrtb"
BidderSomoaudience BidderName = "somoaudience"
BidderSonobi BidderName = "sonobi"
BidderSovrn BidderName = "sovrn"
@@ -80,11 +83,13 @@ var BidderMap = map[string]BidderName{
"adpone": BidderAdpone,
"adtelligent": BidderAdtelligent,
"advangelists": BidderAdvangelists,
+ "applogy": BidderApplogy,
"appnexus": BidderAppnexus,
"beachfront": BidderBeachfront,
"brightroll": BidderBrightroll,
"consumable": BidderConsumable,
"conversant": BidderConversant,
+ "cpmstar": BidderCpmstar,
"datablocks": BidderDatablocks,
"emx_digital": BidderEmxDigital,
"engagebdr": BidderEngageBDR,
@@ -109,6 +114,7 @@ var BidderMap = map[string]BidderName{
"rtbhouse": BidderRTBHouse,
"rubicon": BidderRubicon,
"sharethrough": BidderSharethrough,
+ "smartrtb": BidderSmartRTB,
"somoaudience": BidderSomoaudience,
"sonobi": BidderSonobi,
"sovrn": BidderSovrn,
diff --git a/openrtb_ext/imp.go b/openrtb_ext/imp.go
index 499d1f631bf..0e8f224b884 100644
--- a/openrtb_ext/imp.go
+++ b/openrtb_ext/imp.go
@@ -20,6 +20,9 @@ type ExtImp struct {
type ExtImpPrebid struct {
StoredRequest *ExtStoredRequest `json:"storedrequest"`
+ // Rewarded inventory signal, can be 0 or 1
+ IsRewardedInventory int8 `json:"is_rewarded_inventory"`
+
// NOTE: This is not part of the official API, we are not expecting clients
// migrate from imp[...].ext.${BIDDER} to imp[...].ext.prebid.bidder.${BIDDER}
// at this time
diff --git a/openrtb_ext/imp_applogy.go b/openrtb_ext/imp_applogy.go
new file mode 100644
index 00000000000..45774a05afb
--- /dev/null
+++ b/openrtb_ext/imp_applogy.go
@@ -0,0 +1,5 @@
+package openrtb_ext
+
+type ExtImpApplogy struct {
+ Token string `json:"token"`
+}
diff --git a/openrtb_ext/imp_cpmstar.go b/openrtb_ext/imp_cpmstar.go
new file mode 100644
index 00000000000..0b74f4d437d
--- /dev/null
+++ b/openrtb_ext/imp_cpmstar.go
@@ -0,0 +1,6 @@
+package openrtb_ext
+
+type ExtImpCpmstar struct {
+ PoolId int `json:"placementId"`
+ SubPoolId int `json:"subpoolId,omitempty"`
+}
diff --git a/openrtb_ext/imp_smartrtb.go b/openrtb_ext/imp_smartrtb.go
new file mode 100644
index 00000000000..d056046bf9d
--- /dev/null
+++ b/openrtb_ext/imp_smartrtb.go
@@ -0,0 +1,8 @@
+package openrtb_ext
+
+type ExtImpSmartRTB struct {
+ PubID string `json:"pub_id,omitempty"`
+ MedID string `json:"med_id,omitempty"`
+ ZoneID string `json:"zone_id,omitempty"`
+ ForceBid bool `json:"force_bid,omitempty"`
+}
diff --git a/openrtb_ext/imp_synacormedia.go b/openrtb_ext/imp_synacormedia.go
index 1b044ceaa9c..af48c7dfd01 100644
--- a/openrtb_ext/imp_synacormedia.go
+++ b/openrtb_ext/imp_synacormedia.go
@@ -3,4 +3,5 @@ package openrtb_ext
// ExtImpSynacormedia defines the contract for bidrequest.imp[i].ext.synacormedia
type ExtImpSynacormedia struct {
SeatId string `json:"seatId"`
+ TagId string `json:"tagId"`
}
diff --git a/pbs/pbsrequest_test.go b/pbs/pbsrequest_test.go
index 3e3b37b9fad..52cd6153323 100644
--- a/pbs/pbsrequest_test.go
+++ b/pbs/pbsrequest_test.go
@@ -199,7 +199,7 @@ var dummyConfig = `
"bidder": "appnexus",
"bid_id": "22222224",
"params": {
- "placementId": "10433394"
+ "placementId": "1"
}
}
]
diff --git a/prebid_cache_client/client.go b/prebid_cache_client/client.go
index 6da69f68243..a5730ce7914 100644
--- a/prebid_cache_client/client.go
+++ b/prebid_cache_client/client.go
@@ -4,6 +4,7 @@ import (
"bytes"
"context"
"encoding/json"
+ "errors"
"fmt"
"io/ioutil"
"net/http"
@@ -46,14 +47,9 @@ type Cacheable struct {
Key string
}
-func NewClient(conf *config.Cache, extCache *config.ExternalCache, metrics pbsmetrics.MetricsEngine) Client {
+func NewClient(httpClient *http.Client, conf *config.Cache, extCache *config.ExternalCache, metrics pbsmetrics.MetricsEngine) Client {
return &clientImpl{
- httpClient: &http.Client{
- Transport: &http.Transport{
- MaxIdleConns: 10,
- IdleConnTimeout: 65,
- },
- },
+ httpClient: httpClient,
putUrl: conf.GetBaseURL() + "/cache",
externalCacheHost: extCache.Host,
externalCachePath: extCache.Path,
@@ -92,15 +88,13 @@ func (c *clientImpl) PutJson(ctx context.Context, values []Cacheable) (uuids []s
postBody, err := encodeValues(values)
if err != nil {
- glog.Errorf("Error creating JSON for prebid cache: %v", err)
- errs = append(errs, fmt.Errorf("Error creating JSON for prebid cache: %v", err))
+ logError(&errs, "Error creating JSON for prebid cache: %v", err)
return uuidsToReturn, errs
}
httpReq, err := http.NewRequest("POST", c.putUrl, bytes.NewReader(postBody))
if err != nil {
- glog.Errorf("Error creating POST request to prebid cache: %v", err)
- errs = append(errs, fmt.Errorf("Error creating POST request to prebid cache: %v", err))
+ logError(&errs, "Error creating POST request to prebid cache: %v", err)
return uuidsToReturn, errs
}
@@ -112,9 +106,7 @@ func (c *clientImpl) PutJson(ctx context.Context, values []Cacheable) (uuids []s
elapsedTime := time.Since(startTime)
if err != nil {
c.metrics.RecordPrebidCacheRequestTime(false, elapsedTime)
- friendlyErr := fmt.Errorf("Error sending the request to Prebid Cache: %v; Duration=%v", err, elapsedTime)
- glog.Error(friendlyErr)
- errs = append(errs, friendlyErr)
+ logError(&errs, "Error sending the request to Prebid Cache: %v; Duration=%v, Items=%v, Payload Size=%v", err, elapsedTime, len(values), len(postBody))
return uuidsToReturn, errs
}
defer anResp.Body.Close()
@@ -122,23 +114,19 @@ func (c *clientImpl) PutJson(ctx context.Context, values []Cacheable) (uuids []s
responseBody, err := ioutil.ReadAll(anResp.Body)
if anResp.StatusCode != 200 {
- glog.Errorf("Prebid Cache call to %s returned %d: %s", putURL, anResp.StatusCode, responseBody)
- errs = append(errs, fmt.Errorf("Prebid Cache call to %s returned %d: %s", putURL, anResp.StatusCode, responseBody))
+ logError(&errs, "Prebid Cache call to %s returned %d: %s", putURL, anResp.StatusCode, responseBody)
return uuidsToReturn, errs
}
currentIndex := 0
processResponse := func(uuidObj []byte, _ jsonparser.ValueType, _ int, err error) {
if uuid, valueType, _, err := jsonparser.Get(uuidObj, "uuid"); err != nil {
- glog.Errorf("Prebid Cache returned a bad value at index %d. Error was: %v. Response body was: %s", currentIndex, err, string(responseBody))
- errs = append(errs, fmt.Errorf("Prebid Cache returned a bad value at index %d. Error was: %v. Response body was: %s", currentIndex, err, string(responseBody)))
+ logError(&errs, "Prebid Cache returned a bad value at index %d. Error was: %v. Response body was: %s", currentIndex, err, string(responseBody))
} else if valueType != jsonparser.String {
- glog.Errorf("Prebid Cache returned a %v at index %d in: %v", valueType, currentIndex, string(responseBody))
- errs = append(errs, fmt.Errorf("Prebid Cache returned a %v at index %d in: %v", valueType, currentIndex, string(responseBody)))
+ logError(&errs, "Prebid Cache returned a %v at index %d in: %v", valueType, currentIndex, string(responseBody))
} else {
if uuidsToReturn[currentIndex], err = jsonparser.ParseString(uuid); err != nil {
- glog.Errorf("Prebid Cache response index %d could not be parsed as string: %v", currentIndex, err)
- errs = append(errs, fmt.Errorf("Prebid Cache response index %d could not be parsed as string: %v", currentIndex, err))
+ logError(&errs, "Prebid Cache response index %d could not be parsed as string: %v", currentIndex, err)
uuidsToReturn[currentIndex] = ""
}
}
@@ -146,17 +134,20 @@ func (c *clientImpl) PutJson(ctx context.Context, values []Cacheable) (uuids []s
}
if _, err := jsonparser.ArrayEach(responseBody, processResponse, "responses"); err != nil {
- glog.Errorf("Error interpreting Prebid Cache response: %v\nResponse was: %s", err, string(responseBody))
- errs = append(errs, fmt.Errorf("Error interpreting Prebid Cache response: %v\nResponse was: %s", err, string(responseBody)))
+ logError(&errs, "Error interpreting Prebid Cache response: %v\nResponse was: %s", err, string(responseBody))
return uuidsToReturn, errs
}
return uuidsToReturn, errs
}
+func logError(errs *[]error, format string, a ...interface{}) {
+ msg := fmt.Sprintf(format, a...)
+ glog.Error(msg)
+ *errs = append(*errs, errors.New(msg))
+}
+
func encodeValues(values []Cacheable) ([]byte, error) {
- // This function assumes that m is non-nil and has at least one element.
- // clientImp.PutBids should respect this.
var buf bytes.Buffer
buf.WriteString(`{"puts":[`)
for i := 0; i < len(values); i++ {
diff --git a/prebid_cache_client/client_test.go b/prebid_cache_client/client_test.go
index d3b5ee4bfaf..5840d4ea564 100644
--- a/prebid_cache_client/client_test.go
+++ b/prebid_cache_client/client_test.go
@@ -4,6 +4,7 @@ import (
"bytes"
"context"
"encoding/json"
+ "fmt"
"net/http"
"net/http/httptest"
"strconv"
@@ -17,7 +18,6 @@ import (
"github.com/stretchr/testify/mock"
)
-// Prevents #197
func TestEmptyPut(t *testing.T) {
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
t.Errorf("The server should not be called.")
@@ -72,32 +72,70 @@ func TestBadResponse(t *testing.T) {
}
func TestCancelledContext(t *testing.T) {
- handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ testCases := []struct {
+ description string
+ cacheable []Cacheable
+ expectedItems int
+ expectedPayloadSize int
+ }{
+ {
+ description: "1 Item",
+ cacheable: []Cacheable{
+ {
+ Type: TypeJSON,
+ Data: json.RawMessage("true"),
+ },
+ },
+ expectedItems: 1,
+ expectedPayloadSize: 39,
+ },
+ {
+ description: "2 Items",
+ cacheable: []Cacheable{
+ {
+ Type: TypeJSON,
+ Data: json.RawMessage("true"),
+ },
+ {
+ Type: TypeJSON,
+ Data: json.RawMessage("false"),
+ },
+ },
+ expectedItems: 2,
+ expectedPayloadSize: 69,
+ },
+ }
+
+ // Initialize Stub Server
+ stubHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(200)
})
- server := httptest.NewServer(handler)
- defer server.Close()
+ stubServer := httptest.NewServer(stubHandler)
+ defer stubServer.Close()
- metricsMock := &pbsmetrics.MetricsEngineMock{}
- metricsMock.On("RecordPrebidCacheRequestTime", false, mock.Anything).Once()
+ // Run Tests
+ for _, testCase := range testCases {
+ metricsMock := &pbsmetrics.MetricsEngineMock{}
+ metricsMock.On("RecordPrebidCacheRequestTime", false, mock.Anything).Once()
- client := &clientImpl{
- httpClient: server.Client(),
- putUrl: server.URL,
- metrics: metricsMock,
- }
+ client := &clientImpl{
+ httpClient: stubServer.Client(),
+ putUrl: stubServer.URL,
+ metrics: metricsMock,
+ }
- ctx, cancel := context.WithCancel(context.Background())
- cancel()
- ids, _ := client.PutJson(ctx, []Cacheable{{
- Type: TypeJSON,
- Data: json.RawMessage("true"),
- },
- })
- assertIntEqual(t, len(ids), 1)
- assertStringEqual(t, ids[0], "")
+ ctx, cancel := context.WithCancel(context.Background())
+ cancel()
+ ids, errs := client.PutJson(ctx, testCase.cacheable)
- metricsMock.AssertExpectations(t)
+ expectedErrorMessage := fmt.Sprintf("Items=%v, Payload Size=%v", testCase.expectedItems, testCase.expectedPayloadSize)
+
+ assert.Equal(t, testCase.expectedItems, len(ids), testCase.description+":ids")
+ assert.Len(t, errs, 1)
+ assert.Contains(t, errs[0].Error(), "Error sending the request to Prebid Cache: context canceled", testCase.description+":error")
+ assert.Contains(t, errs[0].Error(), expectedErrorMessage, testCase.description+":error_dimensions")
+ metricsMock.AssertExpectations(t)
+ }
}
func TestSuccessfulPut(t *testing.T) {
@@ -195,11 +233,9 @@ func TestStripCacheHostAndPath(t *testing.T) {
},
}
for _, test := range testInput {
- //start client
- cacheClient := NewClient(&inCacheURL, &test.inExtCacheURL, &metricsConf.DummyMetricsEngine{})
+ cacheClient := NewClient(&http.Client{}, &inCacheURL, &test.inExtCacheURL, &metricsConf.DummyMetricsEngine{})
cHost, cPath := cacheClient.GetExtCacheData()
- //assert
assert.Equal(t, test.expectedHost, cHost)
assert.Equal(t, test.expectedPath, cPath)
}
diff --git a/router/router.go b/router/router.go
index 1994639110c..449ab65a448 100644
--- a/router/router.go
+++ b/router/router.go
@@ -183,7 +183,7 @@ func New(cfg *config.Configuration, rateConvertor *currencies.RateConverter) (r
glog.Infof("Could not read certificates file: %s \n", readCertErr.Error())
}
- theClient := &http.Client{
+ generalHttpClient := &http.Client{
Transport: &http.Transport{
MaxIdleConns: cfg.Client.MaxIdleConns,
MaxIdleConnsPerHost: cfg.Client.MaxIdleConnsPerHost,
@@ -191,13 +191,22 @@ func New(cfg *config.Configuration, rateConvertor *currencies.RateConverter) (r
TLSClientConfig: &tls.Config{RootCAs: certPool},
},
}
+
+ cacheHttpClient := &http.Client{
+ Transport: &http.Transport{
+ MaxIdleConns: cfg.CacheClient.MaxIdleConns,
+ MaxIdleConnsPerHost: cfg.CacheClient.MaxIdleConnsPerHost,
+ IdleConnTimeout: time.Duration(cfg.CacheClient.IdleConnTimeout) * time.Second,
+ },
+ }
+
// Hack because of how legacy handles districtm
legacyBidderList := openrtb_ext.BidderList()
legacyBidderList = append(legacyBidderList, openrtb_ext.BidderName("districtm"))
// Metrics engine
r.MetricsEngine = metricsConf.NewMetricsEngine(cfg, legacyBidderList)
- db, shutdown, fetcher, ampFetcher, categoriesFetcher, videoFetcher := storedRequestsConf.NewStoredRequests(cfg, r.MetricsEngine, theClient, r.Router)
+ db, shutdown, fetcher, ampFetcher, categoriesFetcher, videoFetcher := storedRequestsConf.NewStoredRequests(cfg, r.MetricsEngine, generalHttpClient, r.Router)
// todo(zachbadgett): better shutdown
r.Shutdown = shutdown
@@ -223,10 +232,11 @@ func New(cfg *config.Configuration, rateConvertor *currencies.RateConverter) (r
defaultAliases, defReqJSON := readDefaultRequest(cfg.DefReqConfig)
syncers := usersyncers.NewSyncerMap(cfg)
- gdprPerms := gdpr.NewPermissions(context.Background(), cfg.GDPR, adapters.GDPRAwareSyncerIDs(syncers), theClient)
+ gdprPerms := gdpr.NewPermissions(context.Background(), cfg.GDPR, adapters.GDPRAwareSyncerIDs(syncers), generalHttpClient)
exchanges = newExchangeMap(cfg)
- theExchange := exchange.NewExchange(theClient, pbc.NewClient(&cfg.CacheURL, &cfg.ExtCacheURL, r.MetricsEngine), cfg, r.MetricsEngine, bidderInfos, gdprPerms, rateConvertor)
+ cacheClient := pbc.NewClient(cacheHttpClient, &cfg.CacheURL, &cfg.ExtCacheURL, r.MetricsEngine)
+ theExchange := exchange.NewExchange(generalHttpClient, cacheClient, cfg, r.MetricsEngine, bidderInfos, gdprPerms, rateConvertor)
openrtbEndpoint, err := openrtb2.NewEndpoint(theExchange, paramsValidator, fetcher, categoriesFetcher, cfg, r.MetricsEngine, pbsAnalytics, disabledBidders, defReqJSON, activeBiddersMap)
diff --git a/static/bidder-info/applogy.yaml b/static/bidder-info/applogy.yaml
new file mode 100644
index 00000000000..bb908c94e70
--- /dev/null
+++ b/static/bidder-info/applogy.yaml
@@ -0,0 +1,13 @@
+maintainer:
+ email: work@applogy.com
+capabilities:
+ app:
+ mediaTypes:
+ - banner
+ - video
+ - native
+ site:
+ mediaTypes:
+ - banner
+ - video
+ - native
diff --git a/static/bidder-info/cpmstar.yaml b/static/bidder-info/cpmstar.yaml
new file mode 100644
index 00000000000..097dfddd5b0
--- /dev/null
+++ b/static/bidder-info/cpmstar.yaml
@@ -0,0 +1,11 @@
+maintainer:
+ email: "prebid@cpmstar.com"
+capabilities:
+ app:
+ mediaTypes:
+ - banner
+ - video
+ site:
+ mediaTypes:
+ - banner
+ - video
diff --git a/static/bidder-info/smartrtb.yaml b/static/bidder-info/smartrtb.yaml
new file mode 100644
index 00000000000..c26184f91b7
--- /dev/null
+++ b/static/bidder-info/smartrtb.yaml
@@ -0,0 +1,11 @@
+maintainer:
+ email: "engineering@smrtb.com"
+capabilities:
+ app:
+ mediaTypes:
+ - banner
+ - video
+ site:
+ mediaTypes:
+ - banner
+ - video
diff --git a/static/bidder-params/applogy.json b/static/bidder-params/applogy.json
new file mode 100644
index 00000000000..2650640c115
--- /dev/null
+++ b/static/bidder-params/applogy.json
@@ -0,0 +1,13 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "title": "Applogy Adapter Params",
+ "description": "A schema which validates params accepted by the Applogy adapter",
+ "type": "object",
+ "properties": {
+ "token": {
+ "type": "string",
+ "description": "Applogy token"
+ }
+ },
+ "required": ["token"]
+}
diff --git a/static/bidder-params/cpmstar.json b/static/bidder-params/cpmstar.json
new file mode 100644
index 00000000000..576b503e793
--- /dev/null
+++ b/static/bidder-params/cpmstar.json
@@ -0,0 +1,19 @@
+
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "title": "Cpmstar Adapter Params",
+ "description": "Schema to validate params accepted by the Cpmstar adapter",
+
+ "type": "object",
+ "properties": {
+ "placementId": {
+ "type": "integer",
+ "description": "Cpmstar-specific ID for ad pool"
+ },
+ "subpoolId": {
+ "type": "integer",
+ "description": "Cpmstar-specific ID for ad subpool"
+ }
+ },
+ "required": ["placementId"]
+ }
diff --git a/static/bidder-params/smartrtb.json b/static/bidder-params/smartrtb.json
new file mode 100644
index 00000000000..3bbaab10736
--- /dev/null
+++ b/static/bidder-params/smartrtb.json
@@ -0,0 +1,27 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "title": "SmartRTB Adapter Params",
+ "description": "Required parameters for the SmartRTB server adapter",
+ "type": "object",
+ "properties": {
+ "pub_id": {
+ "type": "string",
+ "description": "Assigned publisher ID",
+ "minLength": 4
+ },
+ "med_id": {
+ "type": "string",
+ "description": "Property ID not zone ID not provided"
+ },
+ "zone_id": {
+ "type": "string",
+ "description": "Specific zone ID for this placement, belonging to app/site",
+ "minLength": 20
+ },
+ "force_bid": {
+ "type": "boolean",
+ "description": "Force bids with a test creative"
+ }
+ },
+ "required": [ "pub_id" ]
+ }
diff --git a/static/bidder-params/synacormedia.json b/static/bidder-params/synacormedia.json
index b2dff8faca1..8c74ada2e85 100644
--- a/static/bidder-params/synacormedia.json
+++ b/static/bidder-params/synacormedia.json
@@ -8,6 +8,10 @@
"seatId": {
"type": "string",
"description": "The seat id."
+ },
+ "tagId": {
+ "type": "string",
+ "description": "The tag id."
}
},
diff --git a/static/bidder-params/ucfunnel.json b/static/bidder-params/ucfunnel.json
index 32acc4002f6..4ee75ec7ac3 100644
--- a/static/bidder-params/ucfunnel.json
+++ b/static/bidder-params/ucfunnel.json
@@ -12,6 +12,5 @@
"type": "string",
"description": "ID for partner"
}
- },
- "required": ["adunitid"]
+ }
}
diff --git a/usersync/usersyncers/syncer.go b/usersync/usersyncers/syncer.go
index c459ff1d510..347857e2024 100644
--- a/usersync/usersyncers/syncer.go
+++ b/usersync/usersyncers/syncer.go
@@ -19,6 +19,7 @@ import (
"github.com/prebid/prebid-server/adapters/brightroll"
"github.com/prebid/prebid-server/adapters/consumable"
"github.com/prebid/prebid-server/adapters/conversant"
+ "github.com/prebid/prebid-server/adapters/cpmstar"
"github.com/prebid/prebid-server/adapters/datablocks"
"github.com/prebid/prebid-server/adapters/emx_digital"
"github.com/prebid/prebid-server/adapters/engagebdr"
@@ -40,6 +41,7 @@ import (
"github.com/prebid/prebid-server/adapters/rtbhouse"
"github.com/prebid/prebid-server/adapters/rubicon"
"github.com/prebid/prebid-server/adapters/sharethrough"
+ "github.com/prebid/prebid-server/adapters/smartrtb"
"github.com/prebid/prebid-server/adapters/somoaudience"
"github.com/prebid/prebid-server/adapters/sonobi"
"github.com/prebid/prebid-server/adapters/sovrn"
@@ -75,6 +77,7 @@ func NewSyncerMap(cfg *config.Configuration) map[openrtb_ext.BidderName]usersync
insertIntoMap(cfg, syncers, openrtb_ext.BidderBrightroll, brightroll.NewBrightrollSyncer)
insertIntoMap(cfg, syncers, openrtb_ext.BidderConsumable, consumable.NewConsumableSyncer)
insertIntoMap(cfg, syncers, openrtb_ext.BidderConversant, conversant.NewConversantSyncer)
+ insertIntoMap(cfg, syncers, openrtb_ext.BidderCpmstar, cpmstar.NewCpmstarSyncer)
insertIntoMap(cfg, syncers, openrtb_ext.BidderDatablocks, datablocks.NewDatablocksSyncer)
insertIntoMap(cfg, syncers, openrtb_ext.BidderEmxDigital, emx_digital.NewEMXDigitalSyncer)
insertIntoMap(cfg, syncers, openrtb_ext.BidderEngageBDR, engagebdr.NewEngageBDRSyncer)
@@ -100,6 +103,7 @@ func NewSyncerMap(cfg *config.Configuration) map[openrtb_ext.BidderName]usersync
insertIntoMap(cfg, syncers, openrtb_ext.BidderSomoaudience, somoaudience.NewSomoaudienceSyncer)
insertIntoMap(cfg, syncers, openrtb_ext.BidderSonobi, sonobi.NewSonobiSyncer)
insertIntoMap(cfg, syncers, openrtb_ext.BidderSovrn, sovrn.NewSovrnSyncer)
+ insertIntoMap(cfg, syncers, openrtb_ext.BidderSmartRTB, smartrtb.NewSmartRTBSyncer)
insertIntoMap(cfg, syncers, openrtb_ext.BidderSynacormedia, synacormedia.NewSynacorMediaSyncer)
insertIntoMap(cfg, syncers, openrtb_ext.BidderTriplelift, triplelift.NewTripleliftSyncer)
insertIntoMap(cfg, syncers, openrtb_ext.BidderTripleliftNative, triplelift_native.NewTripleliftSyncer)
diff --git a/usersync/usersyncers/syncer_test.go b/usersync/usersyncers/syncer_test.go
index b120711fb78..f00d4c9c7b5 100644
--- a/usersync/usersyncers/syncer_test.go
+++ b/usersync/usersyncers/syncer_test.go
@@ -26,6 +26,7 @@ func TestNewSyncerMap(t *testing.T) {
string(openrtb_ext.BidderBrightroll): syncConfig,
string(openrtb_ext.BidderConsumable): syncConfig,
string(openrtb_ext.BidderConversant): syncConfig,
+ string(openrtb_ext.BidderCpmstar): syncConfig,
string(openrtb_ext.BidderDatablocks): syncConfig,
string(openrtb_ext.BidderEmxDigital): syncConfig,
string(openrtb_ext.BidderEngageBDR): syncConfig,
@@ -51,6 +52,7 @@ func TestNewSyncerMap(t *testing.T) {
string(openrtb_ext.BidderSomoaudience): syncConfig,
string(openrtb_ext.BidderSonobi): syncConfig,
string(openrtb_ext.BidderSovrn): syncConfig,
+ string(openrtb_ext.BidderSmartRTB): syncConfig,
string(openrtb_ext.BidderSynacormedia): syncConfig,
string(openrtb_ext.BidderTriplelift): syncConfig,
string(openrtb_ext.BidderTripleliftNative): syncConfig,
@@ -64,6 +66,7 @@ func TestNewSyncerMap(t *testing.T) {
}
adaptersWithoutSyncers := map[openrtb_ext.BidderName]bool{
+ openrtb_ext.BidderApplogy: true,
openrtb_ext.BidderTappx: true,
openrtb_ext.BidderKubient: true,
openrtb_ext.BidderPubnative: true,