Skip to content
This repository has been archived by the owner on Dec 22, 2022. It is now read-only.

Commit

Permalink
This CL introduces currency declaration support in adapters bid respo…
Browse files Browse the repository at this point in the history
…nses as described in prebid#280. (prebid#491)

This change covers:
* Introducing a new struct `BidderResponse` carrying the list of bids `TypedBid` and a currency as string
* Change the existing adapters using the new API `MakeBids` so it start using the new `BidderResponse` struct

This change doesn't cover:
* Doesn't change the former API using `Call` method
* Any check done on Pre-bid server side to discard any bid received with an invalid currency
  (such as unknown, or a one that wasn't authorized in a first place via trhe bid request)
* Any mechanisms on tranlating currency rates

As a nice next step, we should implement the mechanism to filter bids having invalid currencies on not allowed ones.
It will allow to protect both parties from currencies mismatch / discrepancies.
  • Loading branch information
benjaminch authored and dbemiller committed May 4, 2018
1 parent 87329a4 commit a863636
Show file tree
Hide file tree
Showing 29 changed files with 479 additions and 351 deletions.
27 changes: 18 additions & 9 deletions adapters/adapterstest/test_json.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,24 +101,28 @@ func runSpec(t *testing.T, filename string, spec *testSpec, bidder adapters.Bidd
diffErrorLists(t, fmt.Sprintf("%s: MakeRequests", filename), errs, spec.MakeRequestErrors)
diffHttpRequestLists(t, filename, actualReqs, spec.HttpCalls)

var bids = make([]*adapters.TypedBid, 0, len(spec.Bids))
bidResponses := make([]*adapters.BidderResponse, 0)

var bidsErrs = make([]error, 0, len(spec.MakeBidsErrors))
for i := 0; i < len(actualReqs); i++ {
theseBids, theseErrs := bidder.MakeBids(&spec.BidRequest, spec.HttpCalls[i].Request.ToRequestData(t), spec.HttpCalls[i].Response.ToResponseData(t))
bids = append(bids, theseBids...)
thisBidResponse, theseErrs := bidder.MakeBids(&spec.BidRequest, spec.HttpCalls[i].Request.ToRequestData(t), spec.HttpCalls[i].Response.ToResponseData(t))
bidsErrs = append(bidsErrs, theseErrs...)
bidResponses = append(bidResponses, thisBidResponse)
}

diffErrorLists(t, fmt.Sprintf("%s: MakeBids", filename), bidsErrs, spec.MakeBidsErrors)
diffBidLists(t, filename, bids, spec.Bids)

for i := 0; i < len(spec.BidResponses); i++ {
diffBidLists(t, filename, bidResponses[i].Bids, spec.BidResponses[i].Bids)
}
}

type testSpec struct {
BidRequest openrtb.BidRequest `json:"mockBidRequest"`
HttpCalls []httpCall `json:"httpCalls"`
Bids []expectedBid `json:"expectedBids"`
MakeRequestErrors []string `json:"expectedMakeRequestsErrors"`
MakeBidsErrors []string `json:"expectedMakeBidsErrors"`
BidRequest openrtb.BidRequest `json:"mockBidRequest"`
HttpCalls []httpCall `json:"httpCalls"`
BidResponses []expectedBidResponse `json:"expectedBidResponses"`
MakeRequestErrors []string `json:"expectedMakeRequestsErrors"`
MakeBidsErrors []string `json:"expectedMakeBidsErrors"`
}

func (spec *testSpec) expectsErrors() bool {
Expand Down Expand Up @@ -156,6 +160,11 @@ func (resp *httpResponse) ToResponseData(t *testing.T) *adapters.ResponseData {
}
}

type expectedBidResponse struct {
Bids []expectedBid `json:"bids"`
Currency string `json:"currency"`
}

type expectedBid struct {
Bid json.RawMessage `json:"bid"`
Type string `json:"type"`
Expand Down
14 changes: 7 additions & 7 deletions adapters/adform/adform.go
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ func openRtbToAdformRequest(request *openrtb.BidRequest) (*adformRequest, []erro
}, errors
}

func (a *AdformAdapter) MakeBids(internalRequest *openrtb.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) ([]*adapters.TypedBid, []error) {
func (a *AdformAdapter) MakeBids(internalRequest *openrtb.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) {
if response.StatusCode == http.StatusNoContent {
return nil, nil
}
Expand All @@ -366,13 +366,13 @@ func (a *AdformAdapter) MakeBids(internalRequest *openrtb.BidRequest, externalRe
return nil, []error{err}
}

bids := toOpenRtbBids(adformOutput, internalRequest)
bidResponse := toOpenRtbBidResponse(adformOutput, internalRequest)

return bids, nil
return bidResponse, nil
}

func toOpenRtbBids(adformBids []*adformBid, r *openrtb.BidRequest) []*adapters.TypedBid {
bids := make([]*adapters.TypedBid, 0, len(adformBids))
func toOpenRtbBidResponse(adformBids []*adformBid, r *openrtb.BidRequest) *adapters.BidderResponse {
bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(adformBids))

for i, bid := range adformBids {
if bid.Banner == "" || bid.ResponseType != "banner" {
Expand All @@ -388,8 +388,8 @@ func toOpenRtbBids(adformBids []*adformBid, r *openrtb.BidRequest) []*adapters.T
DealID: bid.DealId,
}

bids = append(bids, &adapters.TypedBid{Bid: &openRtbBid, BidType: openrtb_ext.BidTypeBanner})
bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{Bid: &openRtbBid, BidType: openrtb_ext.BidTypeBanner})
}

return bids
return bidResponse
}
28 changes: 14 additions & 14 deletions adapters/adform/adform_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -369,18 +369,18 @@ func TestOpenRTBStandardResponse(t *testing.T) {
httpResponse := &adapters.ResponseData{StatusCode: http.StatusOK, Body: responseBody}

bidder := new(AdformAdapter)
bids, errs := bidder.MakeBids(request, nil, httpResponse)
bidResponse, errs := bidder.MakeBids(request, nil, httpResponse)

if len(bids) != 2 {
t.Fatalf("Expected 2 bids. Got %d", len(bids))
if len(bidResponse.Bids) != 2 {
t.Fatalf("Expected 2 bids. Got %d", len(bidResponse.Bids))
}
if len(errs) != 0 {
t.Errorf("Expected 0 errors. Got %d", len(errs))
}

for _, typeBid := range bids {
for _, typeBid := range bidResponse.Bids {
if typeBid.BidType != openrtb_ext.BidTypeBanner {
t.Errorf("Expected a banner bid. Got: %s", bids[0].BidType)
t.Errorf("Expected a banner bid. Got: %s", bidResponse.Bids[0].BidType)
}
bid := typeBid.Bid
matched := false
Expand Down Expand Up @@ -411,22 +411,22 @@ func TestOpenRTBStandardResponse(t *testing.T) {
func TestOpenRTBSurpriseResponse(t *testing.T) {
bidder := new(AdformAdapter)

bids, errs := bidder.MakeBids(nil, nil,
bidResponse, errs := bidder.MakeBids(nil, nil,
&adapters.ResponseData{StatusCode: http.StatusNoContent, Body: []byte("")})
if bids != nil && errs != nil {
t.Fatalf("Expected no bids and no errors. Got %d bids and %d", len(bids), len(errs))
if bidResponse != nil && errs != nil {
t.Fatalf("Expected no bids and no errors. Got %d bids and %d", len(bidResponse.Bids), len(errs))
}

bids, errs = bidder.MakeBids(nil, nil,
bidResponse, errs = bidder.MakeBids(nil, nil,
&adapters.ResponseData{StatusCode: http.StatusServiceUnavailable, Body: []byte("")})
if bids != nil || len(errs) != 1 {
t.Fatalf("Expected one error and no bids. Got %d bids and %d", len(bids), len(errs))
if bidResponse != nil || len(errs) != 1 {
t.Fatalf("Expected one error and no bids. Got %d bids and %d", len(bidResponse.Bids), len(errs))
}

bids, errs = bidder.MakeBids(nil, nil,
bidResponse, errs = bidder.MakeBids(nil, nil,
&adapters.ResponseData{StatusCode: http.StatusOK, Body: []byte("{:'not-valid-json'}")})
if bids != nil || len(errs) != 1 {
t.Fatalf("Expected one error and no bids. Got %d bids and %d", len(bids), len(errs))
if bidResponse != nil || len(errs) != 1 {
t.Fatalf("Expected one error and no bids. Got %d bids and %d", len(bidResponse.Bids), len(errs))
}
}

Expand Down
9 changes: 4 additions & 5 deletions adapters/adtelligent/adtelligent.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func (a *AdtelligentAdapter) MakeRequests(request *openrtb.BidRequest) ([]*adapt

}

func (a *AdtelligentAdapter) MakeBids(bidReq *openrtb.BidRequest, unused *adapters.RequestData, httpRes *adapters.ResponseData) ([]*adapters.TypedBid, []error) {
func (a *AdtelligentAdapter) MakeBids(bidReq *openrtb.BidRequest, unused *adapters.RequestData, httpRes *adapters.ResponseData) (*adapters.BidderResponse, []error) {

if httpRes.StatusCode == http.StatusNoContent {
return nil, nil
Expand All @@ -98,7 +98,7 @@ func (a *AdtelligentAdapter) MakeBids(bidReq *openrtb.BidRequest, unused *adapte
}}
}

var bids []*adapters.TypedBid
bidResponse := adapters.NewBidderResponse()
var errors []error

var impOK bool
Expand All @@ -117,7 +117,6 @@ func (a *AdtelligentAdapter) MakeBids(bidReq *openrtb.BidRequest, unused *adapte
if imp.Video != nil {
mediaType = openrtb_ext.BidTypeVideo
break

}
}
}
Expand All @@ -129,14 +128,14 @@ func (a *AdtelligentAdapter) MakeBids(bidReq *openrtb.BidRequest, unused *adapte
continue
}

bids = append(bids, &adapters.TypedBid{
bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{
Bid: &bid,
BidType: mediaType,
})
}
}

return bids, errors
return bidResponse, errors
}

func validateImpression(imp *openrtb.Imp) (int, error) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,21 @@
}
}
],
"expectedBids": [
"expectedBidResponses": [
{
"bid": {
"id": "test-bid-id",
"impid": "test-imp-id",
"price": 3.5,
"w": 900,
"h": 250
},
"type": "video"
"currency": "USD",
"bids": [
{
"bid": {
"id": "test-bid-id",
"impid": "test-imp-id",
"price": 3.5,
"w": 900,
"h": 250
},
"type": "video"
}
]
}
]
}
8 changes: 4 additions & 4 deletions adapters/appnexus/appnexus.go
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ func makeKeywordStr(keywords []*openrtb_ext.ExtImpAppnexusKeyVal) string {
return strings.Join(kvs, ",")
}

func (a *AppNexusAdapter) MakeBids(internalRequest *openrtb.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) ([]*adapters.TypedBid, []error) {
func (a *AppNexusAdapter) MakeBids(internalRequest *openrtb.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) {
if response.StatusCode == http.StatusNoContent {
return nil, nil
}
Expand All @@ -417,14 +417,14 @@ func (a *AppNexusAdapter) MakeBids(internalRequest *openrtb.BidRequest, external
return nil, []error{err}
}

bids := make([]*adapters.TypedBid, 0, 5)
bidResponse := adapters.NewBidderResponseWithBidsCapacity(5)

var errs []error
for _, sb := range bidResp.SeatBid {
for i := 0; i < len(sb.Bid); i++ {
bid := sb.Bid[i]
if bidType, err := getMediaTypeForBid(&bid); err == nil {
bids = append(bids, &adapters.TypedBid{
bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{
Bid: &bid,
BidType: bidType,
})
Expand All @@ -433,7 +433,7 @@ func (a *AppNexusAdapter) MakeBids(internalRequest *openrtb.BidRequest, external
}
}
}
return bids, errs
return bidResponse, errs
}

// getMediaTypeForBid determines which type of bid.
Expand Down
55 changes: 30 additions & 25 deletions adapters/appnexus/appnexustest/exemplary/native-1.1.json
Original file line number Diff line number Diff line change
Expand Up @@ -103,33 +103,38 @@
}
}
],
"expectedBids": [
"expectedBidResponses": [
{
"bid": {
"id": "928185755156387460",
"impid": "some-imp-id",
"price": 1,
"adm": "{\"assets\":[{\"id\": 2,\"img\":{\"url\":\"http://vcdn.adnxs.com/p/creative-image/5e/b6/de/c3/5eb6dec3-4854-4dcd-980a-347f36ab502e.jpg\",\"w\": 3000,\"h\": 2250,\"ext\":{\"appnexus\":{\"prevent_crop\":0}}}},{\"id\": 1,\"title\":{\"text\":\"This is an example Prebid Native creative\"}},{\"id\": 3,\"data\":{\"value\":\"Prebid.org\"}},{\"id\": 4,\"data\":{\"value\":\"This is a Prebid Native Creative. There are many like it, but this one is mine.\"}}],\"link\":{\"url\":\"http://nym1-ib.adnxs.com/click?AAAAAAAA8D8AAAAAAADwPwAAAAAAAAAAAAAAAAAA8D8AAAAAAADwPwhdYz3ZyNFNG3fXpZUyLXNZ0o5aAAAAACrElgC-AwAAvgMAAAIAAAC98iUEeP4QAAAAAABVU0QAVVNEAAEAAQARIAAAAAABAgQCAAAAAAEAhBaSXgAAAAA./pp=${AUCTION_PRICE}/cnd=%21OwwGAQiGmooHEL3llyEY-PxDIAQoADoRZGVmYXVsdCNOWU0yOjQwMjM./bn=75922/test=1/referrer=prebid.org/clickenc=http%3A%2F%2Fprebid.org%2Fdev-docs%2Fshow-native-ads.html\"},\"imptrackers\":[\"http://nym1-ib.adnxs.com/openrtb_win?e=wqT_3QLFBqBFAwAAAwDWAAUBCNmku9QFEIi6jeuTm_LoTRib7t2u2tLMlnMqNgkAAAECCPA_EQEHEAAA8D8ZCQkIAAAhCQkI8D8pEQkAMQkJqAAAMKqI2wQ4vgdAvgdIAlC95ZchWPj8Q2AAaJFAeJLRBIABAYoBA1VTRJIFBvBQmAEBoAEBqAEBsAEAuAECwAEEyAEC0AEJ2AEA4AEB8AEAigI7dWYoJ2EnLCAxMzc2ODYwLCAxNTE5MzA5NDAxKTt1ZigncicsIDY5NTk1ODM3Nh4A8IqSAvUBIXRETkdfUWlHbW9vSEVMM2xseUVZQUNENF9FTXdBRGdBUUFSSXZnZFFxb2piQkZnQVlMTURhQUJ3QUhnQWdBRUFpQUVBa0FFQm1BRUJvQUVCcUFFRHNBRUF1UUVwaTRpREFBRHdQOEVCS1l1SWd3QUE4RF9KQVhfelYzek1zXzBfMlFFQUFBAQMkRHdQLUFCQVBVQgEOLEFKZ0NBS0FDQUxVQwUQBEwwCQjwTE1BQ0FNZ0NBT0FDQU9nQ0FQZ0NBSUFEQVpBREFKZ0RBYWdEaHBxS0I3b0RFV1JsWm1GMWJIUWpUbGxOTWpvME1ESXqaAjkhT3d3R0FRNvgA8E4tUHhESUFRb0FEb1JaR1ZtWVhWc2RDTk9XVTB5T2pRd01qTS7YAugH4ALH0wHqAgpwcmViaWQub3Jn8gIRCgZBRFZfSUQSBzEzNzY4NjDyARQMQ1BHXwEUNDM1MDMwOTjyAhEKBUNQARPwmQgxNDg0NzIzOIADAYgDAZADAJgDFKADAaoDAMADkBzIAwDYAwDgAwDoAwD4AwOABACSBAkvb3BlbnJ0YjKYBACiBAwxNTIuMTkzLjYuNzSoBJrMI7IEDAgAEAAYACAAMAA4ALgEAMAEAMgEANIEEWRlZmF1bHQjTllNMjo0MDIz2gQCCADgBADwBL3llyGIBQGYBQCgBf____8FA1ABqgULc29tZS1yZXEtaWTABQDJBQAFARTwP9IFCQkFC2QAAADYBQHgBQHwBd4C-gUECAAQAJAGAZgGAA..&s=08b1535744639c904684afe46e3c6c0e4786089f&test=1&referrer=prebid.org&pp=${AUCTION_PRICE}\"],\"jstracker\":\"<script src=\\\"http://www.dummyurl.js\\\"></script>\"}",
"adid": "69595837",
"adomain": [
"appnexus.com"
],
"iurl": "http://nym1-ib.adnxs.com/cr?id=69595837",
"cid": "958",
"crid": "69595837",
"cat": [
"IAB3-1"
],
"ext": {
"appnexus": {
"brand_id": 350,
"auction_id": 5607483846416358664,
"bidder_id": 2,
"bid_ad_type": 3
}
"currency": "USD",
"bids": [
{
"bid": {
"id": "928185755156387460",
"impid": "some-imp-id",
"price": 1,
"adm": "{\"assets\":[{\"id\": 2,\"img\":{\"url\":\"http://vcdn.adnxs.com/p/creative-image/5e/b6/de/c3/5eb6dec3-4854-4dcd-980a-347f36ab502e.jpg\",\"w\": 3000,\"h\": 2250,\"ext\":{\"appnexus\":{\"prevent_crop\":0}}}},{\"id\": 1,\"title\":{\"text\":\"This is an example Prebid Native creative\"}},{\"id\": 3,\"data\":{\"value\":\"Prebid.org\"}},{\"id\": 4,\"data\":{\"value\":\"This is a Prebid Native Creative. There are many like it, but this one is mine.\"}}],\"link\":{\"url\":\"http://nym1-ib.adnxs.com/click?AAAAAAAA8D8AAAAAAADwPwAAAAAAAAAAAAAAAAAA8D8AAAAAAADwPwhdYz3ZyNFNG3fXpZUyLXNZ0o5aAAAAACrElgC-AwAAvgMAAAIAAAC98iUEeP4QAAAAAABVU0QAVVNEAAEAAQARIAAAAAABAgQCAAAAAAEAhBaSXgAAAAA./pp=${AUCTION_PRICE}/cnd=%21OwwGAQiGmooHEL3llyEY-PxDIAQoADoRZGVmYXVsdCNOWU0yOjQwMjM./bn=75922/test=1/referrer=prebid.org/clickenc=http%3A%2F%2Fprebid.org%2Fdev-docs%2Fshow-native-ads.html\"},\"imptrackers\":[\"http://nym1-ib.adnxs.com/openrtb_win?e=wqT_3QLFBqBFAwAAAwDWAAUBCNmku9QFEIi6jeuTm_LoTRib7t2u2tLMlnMqNgkAAAECCPA_EQEHEAAA8D8ZCQkIAAAhCQkI8D8pEQkAMQkJqAAAMKqI2wQ4vgdAvgdIAlC95ZchWPj8Q2AAaJFAeJLRBIABAYoBA1VTRJIFBvBQmAEBoAEBqAEBsAEAuAECwAEEyAEC0AEJ2AEA4AEB8AEAigI7dWYoJ2EnLCAxMzc2ODYwLCAxNTE5MzA5NDAxKTt1ZigncicsIDY5NTk1ODM3Nh4A8IqSAvUBIXRETkdfUWlHbW9vSEVMM2xseUVZQUNENF9FTXdBRGdBUUFSSXZnZFFxb2piQkZnQVlMTURhQUJ3QUhnQWdBRUFpQUVBa0FFQm1BRUJvQUVCcUFFRHNBRUF1UUVwaTRpREFBRHdQOEVCS1l1SWd3QUE4RF9KQVhfelYzek1zXzBfMlFFQUFBAQMkRHdQLUFCQVBVQgEOLEFKZ0NBS0FDQUxVQwUQBEwwCQjwTE1BQ0FNZ0NBT0FDQU9nQ0FQZ0NBSUFEQVpBREFKZ0RBYWdEaHBxS0I3b0RFV1JsWm1GMWJIUWpUbGxOTWpvME1ESXqaAjkhT3d3R0FRNvgA8E4tUHhESUFRb0FEb1JaR1ZtWVhWc2RDTk9XVTB5T2pRd01qTS7YAugH4ALH0wHqAgpwcmViaWQub3Jn8gIRCgZBRFZfSUQSBzEzNzY4NjDyARQMQ1BHXwEUNDM1MDMwOTjyAhEKBUNQARPwmQgxNDg0NzIzOIADAYgDAZADAJgDFKADAaoDAMADkBzIAwDYAwDgAwDoAwD4AwOABACSBAkvb3BlbnJ0YjKYBACiBAwxNTIuMTkzLjYuNzSoBJrMI7IEDAgAEAAYACAAMAA4ALgEAMAEAMgEANIEEWRlZmF1bHQjTllNMjo0MDIz2gQCCADgBADwBL3llyGIBQGYBQCgBf____8FA1ABqgULc29tZS1yZXEtaWTABQDJBQAFARTwP9IFCQkFC2QAAADYBQHgBQHwBd4C-gUECAAQAJAGAZgGAA..&s=08b1535744639c904684afe46e3c6c0e4786089f&test=1&referrer=prebid.org&pp=${AUCTION_PRICE}\"],\"jstracker\":\"<script src=\\\"http://www.dummyurl.js\\\"></script>\"}",
"adid": "69595837",
"adomain": [
"appnexus.com"
],
"iurl": "http://nym1-ib.adnxs.com/cr?id=69595837",
"cid": "958",
"crid": "69595837",
"cat": [
"IAB3-1"
],
"ext": {
"appnexus": {
"brand_id": 350,
"auction_id": 5607483846416358664,
"bidder_id": 2,
"bid_ad_type": 3
}
}
},
"type": "native"
}
},
"type": "native"
]
}
]
}
51 changes: 28 additions & 23 deletions adapters/appnexus/appnexustest/exemplary/simple-banner.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,31 +95,36 @@
}
],

"expectedBids": [
"expectedBidResponses": [
{
"bid": {
"id": "7706636740145184841",
"impid": "test-imp-id",
"price": 0.5,
"adm": "some-test-ad",
"adid": "29681110",
"adomain": ["appnexus.com"],
"iurl": "http://nym1-ib.adnxs.com/cr?id=29681110",
"cid": "958",
"crid": "29681110",
"w": 300,
"h": 250,
"ext": {
"appnexus": {
"brand_id": 1,
"auction_id": 8189378542222915032,
"bid_ad_type": 0,
"bidder_id": 2,
"ranking_price": 0.000000
}
"currency": "USD",
"bids": [
{
"bid": {
"id": "7706636740145184841",
"impid": "test-imp-id",
"price": 0.5,
"adm": "some-test-ad",
"adid": "29681110",
"adomain": ["appnexus.com"],
"iurl": "http://nym1-ib.adnxs.com/cr?id=29681110",
"cid": "958",
"crid": "29681110",
"w": 300,
"h": 250,
"ext": {
"appnexus": {
"brand_id": 1,
"auction_id": 8189378542222915032,
"bid_ad_type": 0,
"bidder_id": 2,
"ranking_price": 0.000000
}
}
},
"type": "banner"
}
},
"type": "banner"
]
}
]
}
Loading

0 comments on commit a863636

Please sign in to comment.