From 2ad858d3baddf1a996d3986d6c12c2013712b588 Mon Sep 17 00:00:00 2001 From: Dany Gielow Date: Wed, 30 Oct 2024 06:58:22 +0100 Subject: [PATCH 01/11] New Adapter: AdUp Tech --- adapters/aduptech/aduptech.go | 156 ++++++++++++++++++ adapters/aduptech/aduptech_test.go | 19 +++ ...-banner-convert-currency-intermediate.json | 129 +++++++++++++++ .../simple-banner-convert-currency.json | 123 ++++++++++++++ .../exemplary/simple-banner-full-params.json | 107 ++++++++++++ .../aduptechtest/exemplary/simple-banner.json | 95 +++++++++++ .../aduptechtest/exemplary/simple-native.json | 118 +++++++++++++ adapters/aduptech/params_test.go | 60 +++++++ exchange/adapter_builders.go | 2 + openrtb_ext/bidders.go | 2 + openrtb_ext/imp_aduptech.go | 11 ++ static/bidder-info/aduptech.yaml | 27 +++ static/bidder-params/aduptech.json | 35 ++++ 13 files changed, 884 insertions(+) create mode 100644 adapters/aduptech/aduptech.go create mode 100644 adapters/aduptech/aduptech_test.go create mode 100644 adapters/aduptech/aduptechtest/exemplary/simple-banner-convert-currency-intermediate.json create mode 100644 adapters/aduptech/aduptechtest/exemplary/simple-banner-convert-currency.json create mode 100644 adapters/aduptech/aduptechtest/exemplary/simple-banner-full-params.json create mode 100644 adapters/aduptech/aduptechtest/exemplary/simple-banner.json create mode 100644 adapters/aduptech/aduptechtest/exemplary/simple-native.json create mode 100644 adapters/aduptech/params_test.go create mode 100644 openrtb_ext/imp_aduptech.go create mode 100644 static/bidder-info/aduptech.yaml create mode 100644 static/bidder-params/aduptech.json diff --git a/adapters/aduptech/aduptech.go b/adapters/aduptech/aduptech.go new file mode 100644 index 00000000000..6e30dd83eaf --- /dev/null +++ b/adapters/aduptech/aduptech.go @@ -0,0 +1,156 @@ +package aduptech + +import ( + "errors" + "fmt" + "net/http" + "strings" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/currency" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" +) + +type adapter struct { + endpoint string + extraInfo ExtraInfo +} + +type ExtraInfo struct { + TargetCurrency string `json:"target_currency,omitempty"` +} + +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + var extraInfo ExtraInfo + if err := jsonutil.Unmarshal([]byte(config.ExtraAdapterInfo), &extraInfo); err != nil { + return nil, fmt.Errorf("invalid extra info: %v", err) + } + + bidder := &adapter{ + endpoint: config.Endpoint, + extraInfo: extraInfo, + } + + return bidder, nil +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + for i := range request.Imp { + imp := &request.Imp[i] + // Check if imp comes with bid floor amount defined in a foreign currency + if imp.BidFloor > 0 && imp.BidFloorCur != "" && strings.ToUpper(imp.BidFloorCur) != a.extraInfo.TargetCurrency { + + convertedValue, err := a.convertCurrency(imp.BidFloor, imp.BidFloorCur, reqInfo) + if err != nil { + return nil, []error{err} + } + + imp.BidFloorCur = a.extraInfo.TargetCurrency + imp.BidFloor = convertedValue + } + } + + requestJSON, err := jsonutil.Marshal(request) + if err != nil { + return nil, []error{err} + } + + requestData := &adapters.RequestData{ + Method: http.MethodPost, + Uri: a.endpoint, + Body: requestJSON, + ImpIDs: openrtb_ext.GetImpIDs(request.Imp), + } + + return []*adapters.RequestData{requestData}, nil +} + +func (a *adapter) convertCurrency(value float64, cur string, reqInfo *adapters.ExtraRequestInfo) (float64, error) { + convertedValue, err := reqInfo.ConvertCurrency(value, cur, a.extraInfo.TargetCurrency) + + if err != nil { + var convErr currency.ConversionNotFoundError + if errors.As(err, &convErr) { + + // try again by first converting to USD + // then convert to target_currency + convertedValue, err = reqInfo.ConvertCurrency(value, cur, "USD") + + if err != nil { + return 0, err + } + + convertedValue, err = reqInfo.ConvertCurrency(convertedValue, "USD", a.extraInfo.TargetCurrency) + + if err != nil { + return 0, err + } + } else { + return 0, err + } + } + return convertedValue, nil +} + +func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { + switch responseData.StatusCode { + case http.StatusNoContent: + return nil, nil + case http.StatusBadRequest: + return nil, []error{&errortypes.BadInput{ + Message: fmt.Sprintf("Unexpected status code: 400. Run with request.debug = 1 for more info."), + }} + case http.StatusOK: + // we don't need to do anything here and this is just so we can use the default case for the unexpected status code + break + default: + return nil, []error{&errortypes.BadServerResponse{ + Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info.", responseData.StatusCode), + }} + + } + + var response openrtb2.BidResponse + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { + return nil, []error{err} + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) + bidResponse.Currency = response.Cur + + var errs []error + for i := range response.SeatBid { + seatBid := &response.SeatBid[i] + for j := range seatBid.Bid { + bid := &seatBid.Bid[j] + bidType, err := getBidType(bid.MType) + if err != nil { + errs = append(errs, err) + continue + } + bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ + Bid: bid, + BidType: bidType, + }) + } + } + + return bidResponse, errs +} + +func getBidType(markupType openrtb2.MarkupType) (openrtb_ext.BidType, error) { + switch markupType { + case openrtb2.MarkupNative: + return openrtb_ext.BidTypeNative, nil + case openrtb2.MarkupBanner: + return openrtb_ext.BidTypeBanner, nil + default: + return "", &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Unknown markup type: %d", markupType), + } + } +} diff --git a/adapters/aduptech/aduptech_test.go b/adapters/aduptech/aduptech_test.go new file mode 100644 index 00000000000..b3c0a57d6f0 --- /dev/null +++ b/adapters/aduptech/aduptech_test.go @@ -0,0 +1,19 @@ +package aduptech + +import ( + "github.com/stretchr/testify/assert" + "testing" + + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderAdUpTech, config.Adapter{ + Endpoint: "https://example.com/rtb/bid", ExtraAdapterInfo: "{\"target_currency\": \"EUR\"}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + assert.NoError(t, buildErr, "Builder returned unexpected error") + + adapterstest.RunJSONBidderTest(t, "aduptechtest", bidder) +} diff --git a/adapters/aduptech/aduptechtest/exemplary/simple-banner-convert-currency-intermediate.json b/adapters/aduptech/aduptechtest/exemplary/simple-banner-convert-currency-intermediate.json new file mode 100644 index 00000000000..c50f56f00bb --- /dev/null +++ b/adapters/aduptech/aduptechtest/exemplary/simple-banner-convert-currency-intermediate.json @@ -0,0 +1,129 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "https://good.site/url" + }, + "imp": [{ + "id": "test-imp-id", + "bidfloor": 1.0, + "bidfloorcur": "AUD", + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + }, + "ext": { + "bidder": { + "publisher": "123456", + "placement": "234567" + } + } + }], + "ext": { + "prebid": { + "currency": { + "rates": { + "EUR": { + "USD": 0.05 + }, + "USD": { + "AUD": 2.0 + } + }, + "usepbsrates": false + } + } + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://example.com/rtb/bid", + "body": { + "id": "test-request-id", + "site": { + "page": "https://good.site/url" + }, + "imp": [ + { + "id": "test-imp-id", + "bidfloor": 10, + "bidfloorcur": "EUR", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "publisher": "123456", + "placement": "234567" + } + } + } + ], + "ext": { + "prebid": { + "currency": { + "rates": { + "EUR": { + "USD": 0.05 + }, + "USD": { + "AUD": 2.0 + } + }, + "usepbsrates": false + } + } + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "958", + "bid": [{ + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "adomain": ["example.com"], + "crid": "29681110", + "h": 250, + "w": 300, + "mtype": 1 + }] + } + ], + "cur": "EUR" + } + } + }], + + "expectedBidResponses": [{ + "currency": "EUR", + "bids": [{ + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "adomain": ["example.com"], + "crid": "29681110", + "h": 250, + "w": 300, + "mtype": 1 + }, + "type": "banner" + }] + }] +} diff --git a/adapters/aduptech/aduptechtest/exemplary/simple-banner-convert-currency.json b/adapters/aduptech/aduptechtest/exemplary/simple-banner-convert-currency.json new file mode 100644 index 00000000000..05a0016f45b --- /dev/null +++ b/adapters/aduptech/aduptechtest/exemplary/simple-banner-convert-currency.json @@ -0,0 +1,123 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "https://good.site/url" + }, + "imp": [{ + "id": "test-imp-id", + "bidfloor": 1.0, + "bidfloorcur": "USD", + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + }, + "ext": { + "bidder": { + "publisher": "123456", + "placement": "234567" + } + } + }], + "ext": { + "prebid": { + "currency": { + "rates": { + "EUR": { + "USD": 0.05 + } + }, + "usepbsrates": false + } + } + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://example.com/rtb/bid", + "body": { + "id": "test-request-id", + "site": { + "page": "https://good.site/url" + }, + "imp": [ + { + "id": "test-imp-id", + "bidfloor": 20, + "bidfloorcur": "EUR", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "publisher": "123456", + "placement": "234567" + } + } + } + ], + "ext": { + "prebid": { + "currency": { + "rates": { + "EUR": { + "USD": 0.05 + } + }, + "usepbsrates": false + } + } + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "958", + "bid": [{ + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "adomain": ["example.com"], + "crid": "29681110", + "h": 250, + "w": 300, + "mtype": 1 + }] + } + ], + "cur": "EUR" + } + } + }], + + "expectedBidResponses": [{ + "currency": "EUR", + "bids": [{ + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "adomain": ["example.com"], + "crid": "29681110", + "h": 250, + "w": 300, + "mtype": 1 + }, + "type": "banner" + }] + }] +} diff --git a/adapters/aduptech/aduptechtest/exemplary/simple-banner-full-params.json b/adapters/aduptech/aduptechtest/exemplary/simple-banner-full-params.json new file mode 100644 index 00000000000..29a8c888c17 --- /dev/null +++ b/adapters/aduptech/aduptechtest/exemplary/simple-banner-full-params.json @@ -0,0 +1,107 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "https://good.site/url" + }, + "imp": [{ + "id": "test-imp-id", + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + }, + "ext": { + "bidder": { + "publisher": "123456", + "placement": "234567", + "adtest": true, + "debug": true, + "query": "abc,def", + "ext": { + "foo": "bar" + } + } + } + }] + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://example.com/rtb/bid", + "body": { + "id": "test-request-id", + "site": { + "page": "https://good.site/url" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "publisher": "123456", + "placement": "234567", + "adtest": true, + "debug": true, + "query": "abc,def", + "ext": { + "foo": "bar" + } + } + } + } + ] + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "958", + "bid": [{ + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "adomain": ["example.com"], + "crid": "29681110", + "h": 250, + "w": 300, + "mtype": 1 + }] + } + ], + "cur": "EUR" + } + } + }], + + "expectedBidResponses": [{ + "currency": "EUR", + "bids": [{ + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "adomain": ["example.com"], + "crid": "29681110", + "h": 250, + "w": 300, + "mtype": 1 + }, + "type": "banner" + }] + }] +} diff --git a/adapters/aduptech/aduptechtest/exemplary/simple-banner.json b/adapters/aduptech/aduptechtest/exemplary/simple-banner.json new file mode 100644 index 00000000000..69c7655418c --- /dev/null +++ b/adapters/aduptech/aduptechtest/exemplary/simple-banner.json @@ -0,0 +1,95 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "https://good.site/url" + }, + "imp": [{ + "id": "test-imp-id", + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + }, + "ext": { + "bidder": { + "publisher": "123456", + "placement": "234567" + } + } + }] + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://example.com/rtb/bid", + "body": { + "id": "test-request-id", + "site": { + "page": "https://good.site/url" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "publisher": "123456", + "placement": "234567" + } + } + } + ] + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "958", + "bid": [{ + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "adomain": ["example.com"], + "crid": "29681110", + "h": 250, + "w": 300, + "mtype": 1 + }] + } + ], + "cur": "EUR" + } + } + }], + + "expectedBidResponses": [{ + "currency": "EUR", + "bids": [{ + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "adomain": ["example.com"], + "crid": "29681110", + "h": 250, + "w": 300, + "mtype": 1 + }, + "type": "banner" + }] + }] +} diff --git a/adapters/aduptech/aduptechtest/exemplary/simple-native.json b/adapters/aduptech/aduptechtest/exemplary/simple-native.json new file mode 100644 index 00000000000..2c1086897fe --- /dev/null +++ b/adapters/aduptech/aduptechtest/exemplary/simple-native.json @@ -0,0 +1,118 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "id": "123", + "page": "https://good.site/url" + }, + "imp": [{ + "id": "test-imp-id", + "native": { + "ver": "1.2", + "request": "{\"context\":2,\"contextsubtype\":20,\"plcmttype\":4,\"plcmtcnt\":1,\"urlsupport\":0,\"privacy\":1,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"assets\":[{\"id\":123,\"required\":1,\"title\":{\"len\":140}},{\"id\":128,\"required\":0,\"img\":{\"wmin\":300,\"hmin\":250,\"type\":3}},{\"id\":129,\"required\":0,\"img\":{\"type\":2}},{\"id\":127,\"required\":1,\"data\":{\"type\":2,\"len\":140}}]}" + }, + "ext": { + "bidder": { + "publisher": "123456", + "placement": "234567" + } + } + }] + }, + + "httpCalls": [{ + "expectedRequest": { + "uri": "https://example.com/rtb/bid", + "body": { + "id": "test-request-id", + "site": { + "id": "123", + "page": "https://good.site/url" + }, + "imp": [{ + "id": "test-imp-id", + "native": { + "ver": "1.2", + "request": "{\"context\":2,\"contextsubtype\":20,\"plcmttype\":4,\"plcmtcnt\":1,\"urlsupport\":0,\"privacy\":1,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"assets\":[{\"id\":123,\"required\":1,\"title\":{\"len\":140}},{\"id\":128,\"required\":0,\"img\":{\"wmin\":300,\"hmin\":250,\"type\":3}},{\"id\":129,\"required\":0,\"img\":{\"type\":2}},{\"id\":127,\"required\":1,\"data\":{\"type\":2,\"len\":140}}]}" + }, + "ext": { + "bidder": { + "publisher": "123456", + "placement": "234567" + } + } + }] + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [{ + "seat": "grid", + "bid": [{ + "id": "some-id", + "impid": "test-imp-id", + "price": 0.010526, + "adm": "{\"native\":{\"ver\":\"1.2\",\"link\":{\"url\":\"some-url\"},\"assets\":[{\"title\":{\"text\":\"some title\"},\"id\":123},{\"img\":{\"url\":\"some-image\",\"w\":300,\"h\":250},\"id\":128},{\"data\":{\"value\":\"some-description\"},\"id\":127}],\"eventtrackers\":[{\"event\":1,\"method\":1,\"url\":\"some-click-url\"}],\"privacy\":\"https://www.adup-tech.com/oba/\"}}", + "adomain": [ + "example.com" + ], + "crid": "12345678", + "mtype": 4, + "ext": { + "dsa": { + "adrender": 0, + "behalf": "example.com", + "paid": "Example Site", + "transparency": [ + { + "domain": "adup-tech.com", + "params": [ + 2 + ] + } + ] + } + } + }] + }], + "currency": "EUR" + } + } + }], + + "expectedBidResponses": [{ + "currency": "EUR", + "bids": [{ + "bid": { + "id": "some-id", + "impid": "test-imp-id", + "price": 0.010526, + "adm": "{\"native\":{\"ver\":\"1.2\",\"link\":{\"url\":\"some-url\"},\"assets\":[{\"title\":{\"text\":\"some title\"},\"id\":123},{\"img\":{\"url\":\"some-image\",\"w\":300,\"h\":250},\"id\":128},{\"data\":{\"value\":\"some-description\"},\"id\":127}],\"eventtrackers\":[{\"event\":1,\"method\":1,\"url\":\"some-click-url\"}],\"privacy\":\"https://www.adup-tech.com/oba/\"}}", + "adomain": [ + "example.com" + ], + "crid": "12345678", + "mtype": 4, + "ext": { + "dsa": { + "adrender": 0, + "behalf": "example.com", + "paid": "Example Site", + "transparency": [ + { + "domain": "adup-tech.com", + "params": [ + 2 + ] + } + ] + } + } + }, + "type": "native" + }] + }] +} diff --git a/adapters/aduptech/params_test.go b/adapters/aduptech/params_test.go new file mode 100644 index 00000000000..16393782450 --- /dev/null +++ b/adapters/aduptech/params_test.go @@ -0,0 +1,60 @@ +package aduptech + +import ( + "encoding/json" + "github.com/stretchr/testify/assert" + "testing" + + "github.com/prebid/prebid-server/v3/openrtb_ext" +) + +var validParams = []string{ + `{ "publisher": "123456789", "placement": "234567890" }`, + `{ "publisher": "123456789", "placement": "234567890", "query": "test" }`, + `{ "publisher": "123456789", "placement": "234567890", "adtest": true }`, + `{ "publisher": "123456789", "placement": "234567890", "debug": true }`, + `{ "publisher": "123456789", "placement": "234567890", "query": "test", "adtest": true }`, + `{ "publisher": "123456789", "placement": "234567890", "ext": {"foo": "bar"} }`, + `{ "publisher": "123456789", "placement": "234567890", "ext": {} }`, +} + +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schemas. %v", err) + } + + for _, validParam := range validParams { + assert.NoErrorf(t, validator.Validate(openrtb_ext.BidderAdUpTech, json.RawMessage(validParam)), "Schema rejected Aduptech params: %s", validParam) + } +} + +var invalidParams = []string{ + ``, + `null`, + `true`, + `5`, + `4.2`, + `[]`, + `{}`, + `{ "publisher": "123456789" }`, + `{ "placement": "234567890" }`, + `{ "publisher": null, "placement": null }`, + `{ "publisher": "123456789", "placement": "234567890", "query": null }`, + `{ "publisher": "123456789", "placement": "234567890", "adtest": null }`, + `{ "publisher": "123456789", "placement": "234567890", "debug": null }`, + `{ "publisher": "123456789", "placement": "234567890", "ext": null }`, + `{ "publisher": "123456789", "placement": "234567890", "ext": 123 }`, + `{ "publisher": "123456789", "placement": "234567890", "ext": "abc" }`, +} + +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 { + assert.Errorf(t, validator.Validate(openrtb_ext.BidderAdUpTech, json.RawMessage(invalidParam)), "Schema allowed unexpected params: %s", invalidParam) + } +} diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 97a03dde2a5..71169163d40 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -28,6 +28,7 @@ import ( "github.com/prebid/prebid-server/v3/adapters/adtelligent" "github.com/prebid/prebid-server/v3/adapters/adtonos" "github.com/prebid/prebid-server/v3/adapters/adtrgtme" + "github.com/prebid/prebid-server/v3/adapters/aduptech" "github.com/prebid/prebid-server/v3/adapters/advangelists" "github.com/prebid/prebid-server/v3/adapters/adview" "github.com/prebid/prebid-server/v3/adapters/adxcg" @@ -258,6 +259,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderAdtrgtme: adtrgtme.Builder, openrtb_ext.BidderAdtelligent: adtelligent.Builder, openrtb_ext.BidderAdTonos: adtonos.Builder, + openrtb_ext.BidderAdUpTech: aduptech.Builder, openrtb_ext.BidderAdvangelists: advangelists.Builder, openrtb_ext.BidderAdView: adview.Builder, openrtb_ext.BidderAdxcg: adxcg.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 9e86ad86ec1..166d44b8935 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -44,6 +44,7 @@ var coreBidderNames []BidderName = []BidderName{ BidderAdtrgtme, BidderAdtelligent, BidderAdTonos, + BidderAdUpTech, BidderAdvangelists, BidderAdView, BidderAdxcg, @@ -374,6 +375,7 @@ const ( BidderAdtrgtme BidderName = "adtrgtme" BidderAdTonos BidderName = "adtonos" BidderAdtelligent BidderName = "adtelligent" + BidderAdUpTech BidderName = "aduptech" BidderAdvangelists BidderName = "advangelists" BidderAdView BidderName = "adview" BidderAdxcg BidderName = "adxcg" diff --git a/openrtb_ext/imp_aduptech.go b/openrtb_ext/imp_aduptech.go new file mode 100644 index 00000000000..184d33ca453 --- /dev/null +++ b/openrtb_ext/imp_aduptech.go @@ -0,0 +1,11 @@ +package openrtb_ext + +import "encoding/json" + +type ExtImpAduptech struct { + Publisher string `json:"publisher"` + Placement string `json:"placement"` + Query string `json:"query"` + AdTest string `json:"adtest"` + Ext json.RawMessage `json:"ext,omitempty"` +} diff --git a/static/bidder-info/aduptech.yaml b/static/bidder-info/aduptech.yaml new file mode 100644 index 00000000000..7645ddf319a --- /dev/null +++ b/static/bidder-info/aduptech.yaml @@ -0,0 +1,27 @@ +endpoint: "https://rtb.d.adup-tech.com/rtb/bid" +extra_info: "{\"target_currency\": \"EUR\"}" +geoscope: + - EEA + - CHE + - GBR +maintainer: + email: "support@adup-tech.com" +gvlVendorID: 647 +openrtb: + version: 2.6 +capabilities: + app: + mediaTypes: + - banner + - native + site: + mediaTypes: + - banner + - native +userSync: + redirect: + url: "https://rtb.adup-tech.com/service/usersync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}}" + userMacro: "[UID]" + iframe: + url: "https://rtb.adup-tech.com/service/usersync?iframe=1&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}}" + userMacro: "[UID]" \ No newline at end of file diff --git a/static/bidder-params/aduptech.json b/static/bidder-params/aduptech.json new file mode 100644 index 00000000000..512b634a362 --- /dev/null +++ b/static/bidder-params/aduptech.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "AdUp Tech adapter params", + "description": "A schema which validates params accepted by the AdUp Tech adapter", + "type": "object", + + "properties": { + "publisher": { + "type": "string", + "description": "Unique publisher identifier." + }, + "placement": { + "type": "string", + "description": "Unique placement identifier per publisher." + }, + "query": { + "type": "string", + "description": "Semicolon separated list of keywords." + }, + "adtest": { + "type": "boolean", + "description": "Deactivates tracking of impressions and clicks. **Should only be used for testing purposes!**" + }, + "debug": { + "type": "boolean", + "description": "Enables debug mode. **Should only be used for testing purposes!**" + }, + "ext": { + "type": "object", + "description": "Additional parameters to be included in the request." + } + }, + + "required": ["publisher", "placement"] + } \ No newline at end of file From 48deb93526794c9844cf543d494dbad23b43d3db Mon Sep 17 00:00:00 2001 From: Dany Gielow Date: Mon, 13 Jan 2025 13:34:40 +0100 Subject: [PATCH 02/11] feat(aduptech): added more tests, changed assert to require where sensible, fixed sync URL --- adapters/aduptech/aduptech.go | 37 +++++--- adapters/aduptech/aduptech_test.go | 13 ++- .../supplemental/broken-response.json | 95 +++++++++++++++++++ .../aduptechtest/supplemental/status-204.json | 54 +++++++++++ .../aduptechtest/supplemental/status-400.json | 59 ++++++++++++ .../aduptechtest/supplemental/status-500.json | 59 ++++++++++++ .../supplemental/unsupported-mtype.json | 91 ++++++++++++++++++ adapters/aduptech/params_test.go | 3 +- static/bidder-info/aduptech.yaml | 4 +- 9 files changed, 395 insertions(+), 20 deletions(-) create mode 100644 adapters/aduptech/aduptechtest/supplemental/broken-response.json create mode 100644 adapters/aduptech/aduptechtest/supplemental/status-204.json create mode 100644 adapters/aduptech/aduptechtest/supplemental/status-400.json create mode 100644 adapters/aduptech/aduptechtest/supplemental/status-500.json create mode 100644 adapters/aduptech/aduptechtest/supplemental/unsupported-mtype.json diff --git a/adapters/aduptech/aduptech.go b/adapters/aduptech/aduptech.go index 6e30dd83eaf..37052089000 100644 --- a/adapters/aduptech/aduptech.go +++ b/adapters/aduptech/aduptech.go @@ -27,7 +27,11 @@ type ExtraInfo struct { func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { var extraInfo ExtraInfo if err := jsonutil.Unmarshal([]byte(config.ExtraAdapterInfo), &extraInfo); err != nil { - return nil, fmt.Errorf("invalid extra info: %v", err) + return nil, fmt.Errorf("invalid extra info: %w", err) + } + + if extraInfo.TargetCurrency == "" { + return nil, fmt.Errorf("invalid extra info: TargetCurrency is empty, pls check") } bidder := &adapter{ @@ -69,27 +73,30 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E return []*adapters.RequestData{requestData}, nil } +// convertCurrency attempts to convert a given value from the specified currency (cur) to the +// target currency specified in the adapter's extraInfo. If the conversion directly to the +// target currency fails due to a ConversionNotFoundError, it attempts an intermediate conversion +// through USD. Returns the converted value or an error if conversion fails. func (a *adapter) convertCurrency(value float64, cur string, reqInfo *adapters.ExtraRequestInfo) (float64, error) { convertedValue, err := reqInfo.ConvertCurrency(value, cur, a.extraInfo.TargetCurrency) if err != nil { var convErr currency.ConversionNotFoundError - if errors.As(err, &convErr) { + if !errors.As(err, &convErr) { + return 0, err + } - // try again by first converting to USD - // then convert to target_currency - convertedValue, err = reqInfo.ConvertCurrency(value, cur, "USD") + // try again by first converting to USD + // then convert to target_currency + convertedValue, err = reqInfo.ConvertCurrency(value, cur, "USD") - if err != nil { - return 0, err - } + if err != nil { + return 0, err + } - convertedValue, err = reqInfo.ConvertCurrency(convertedValue, "USD", a.extraInfo.TargetCurrency) + convertedValue, err = reqInfo.ConvertCurrency(convertedValue, "USD", a.extraInfo.TargetCurrency) - if err != nil { - return 0, err - } - } else { + if err != nil { return 0, err } } @@ -102,14 +109,14 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R return nil, nil case http.StatusBadRequest: return nil, []error{&errortypes.BadInput{ - Message: fmt.Sprintf("Unexpected status code: 400. Run with request.debug = 1 for more info."), + Message: "Unexpected status code: 400. Run with request.debug = 1 for more info.", }} case http.StatusOK: // we don't need to do anything here and this is just so we can use the default case for the unexpected status code break default: return nil, []error{&errortypes.BadServerResponse{ - Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info.", responseData.StatusCode), + Message: fmt.Sprintf("Unexpected status code: %d.", responseData.StatusCode), }} } diff --git a/adapters/aduptech/aduptech_test.go b/adapters/aduptech/aduptech_test.go index b3c0a57d6f0..75cbe5d5c1f 100644 --- a/adapters/aduptech/aduptech_test.go +++ b/adapters/aduptech/aduptech_test.go @@ -1,9 +1,11 @@ package aduptech import ( - "github.com/stretchr/testify/assert" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" "github.com/prebid/prebid-server/v3/config" "github.com/prebid/prebid-server/v3/openrtb_ext" @@ -13,7 +15,14 @@ func TestJsonSamples(t *testing.T) { bidder, buildErr := Builder(openrtb_ext.BidderAdUpTech, config.Adapter{ Endpoint: "https://example.com/rtb/bid", ExtraAdapterInfo: "{\"target_currency\": \"EUR\"}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) - assert.NoError(t, buildErr, "Builder returned unexpected error") + require.NoError(t, buildErr, "Builder returned unexpected error") adapterstest.RunJSONBidderTest(t, "aduptechtest", bidder) } + +func TestInvalidExtraAdapterInfo(t *testing.T) { + _, buildErr := Builder(openrtb_ext.BidderAdUpTech, config.Adapter{ + Endpoint: "https://example.com/rtb/bid", ExtraAdapterInfo: "{\"foo\": \"bar\"}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + assert.EqualError(t, buildErr, "invalid extra info: TargetCurrency is empty, pls check") +} diff --git a/adapters/aduptech/aduptechtest/supplemental/broken-response.json b/adapters/aduptech/aduptechtest/supplemental/broken-response.json new file mode 100644 index 00000000000..69c7655418c --- /dev/null +++ b/adapters/aduptech/aduptechtest/supplemental/broken-response.json @@ -0,0 +1,95 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "https://good.site/url" + }, + "imp": [{ + "id": "test-imp-id", + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + }, + "ext": { + "bidder": { + "publisher": "123456", + "placement": "234567" + } + } + }] + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://example.com/rtb/bid", + "body": { + "id": "test-request-id", + "site": { + "page": "https://good.site/url" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "publisher": "123456", + "placement": "234567" + } + } + } + ] + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "958", + "bid": [{ + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "adomain": ["example.com"], + "crid": "29681110", + "h": 250, + "w": 300, + "mtype": 1 + }] + } + ], + "cur": "EUR" + } + } + }], + + "expectedBidResponses": [{ + "currency": "EUR", + "bids": [{ + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "adomain": ["example.com"], + "crid": "29681110", + "h": 250, + "w": 300, + "mtype": 1 + }, + "type": "banner" + }] + }] +} diff --git a/adapters/aduptech/aduptechtest/supplemental/status-204.json b/adapters/aduptech/aduptechtest/supplemental/status-204.json new file mode 100644 index 00000000000..2fbe824cfb4 --- /dev/null +++ b/adapters/aduptech/aduptechtest/supplemental/status-204.json @@ -0,0 +1,54 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "id": "123", + "page": "https://good.site/url" + }, + "imp": [{ + "id": "test-imp-id", + "native": { + "ver": "1.2", + "request": "{\"context\":2,\"contextsubtype\":20,\"plcmttype\":4,\"plcmtcnt\":1,\"urlsupport\":0,\"privacy\":1,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"assets\":[{\"id\":123,\"required\":1,\"title\":{\"len\":140}},{\"id\":128,\"required\":0,\"img\":{\"wmin\":300,\"hmin\":250,\"type\":3}},{\"id\":129,\"required\":0,\"img\":{\"type\":2}},{\"id\":127,\"required\":1,\"data\":{\"type\":2,\"len\":140}}]}" + }, + "ext": { + "bidder": { + "publisher": "123456", + "placement": "234567" + } + } + }] + }, + + "httpCalls": [{ + "expectedRequest": { + "uri": "https://example.com/rtb/bid", + "body": { + "id": "test-request-id", + "site": { + "id": "123", + "page": "https://good.site/url" + }, + "imp": [{ + "id": "test-imp-id", + "native": { + "ver": "1.2", + "request": "{\"context\":2,\"contextsubtype\":20,\"plcmttype\":4,\"plcmtcnt\":1,\"urlsupport\":0,\"privacy\":1,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"assets\":[{\"id\":123,\"required\":1,\"title\":{\"len\":140}},{\"id\":128,\"required\":0,\"img\":{\"wmin\":300,\"hmin\":250,\"type\":3}},{\"id\":129,\"required\":0,\"img\":{\"type\":2}},{\"id\":127,\"required\":1,\"data\":{\"type\":2,\"len\":140}}]}" + }, + "ext": { + "bidder": { + "publisher": "123456", + "placement": "234567" + } + } + }] + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 204 + } + }], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [] +} diff --git a/adapters/aduptech/aduptechtest/supplemental/status-400.json b/adapters/aduptech/aduptechtest/supplemental/status-400.json new file mode 100644 index 00000000000..11d3a7f8dd3 --- /dev/null +++ b/adapters/aduptech/aduptechtest/supplemental/status-400.json @@ -0,0 +1,59 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "id": "123", + "page": "https://good.site/url" + }, + "imp": [{ + "id": "test-imp-id", + "native": { + "ver": "1.2", + "request": "{\"context\":2,\"contextsubtype\":20,\"plcmttype\":4,\"plcmtcnt\":1,\"urlsupport\":0,\"privacy\":1,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"assets\":[{\"id\":123,\"required\":1,\"title\":{\"len\":140}},{\"id\":128,\"required\":0,\"img\":{\"wmin\":300,\"hmin\":250,\"type\":3}},{\"id\":129,\"required\":0,\"img\":{\"type\":2}},{\"id\":127,\"required\":1,\"data\":{\"type\":2,\"len\":140}}]}" + }, + "ext": { + "bidder": { + "publisher": "123456", + "placement": "234567" + } + } + }] + }, + + "httpCalls": [{ + "expectedRequest": { + "uri": "https://example.com/rtb/bid", + "body": { + "id": "test-request-id", + "site": { + "id": "123", + "page": "https://good.site/url" + }, + "imp": [{ + "id": "test-imp-id", + "native": { + "ver": "1.2", + "request": "{\"context\":2,\"contextsubtype\":20,\"plcmttype\":4,\"plcmtcnt\":1,\"urlsupport\":0,\"privacy\":1,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"assets\":[{\"id\":123,\"required\":1,\"title\":{\"len\":140}},{\"id\":128,\"required\":0,\"img\":{\"wmin\":300,\"hmin\":250,\"type\":3}},{\"id\":129,\"required\":0,\"img\":{\"type\":2}},{\"id\":127,\"required\":1,\"data\":{\"type\":2,\"len\":140}}]}" + }, + "ext": { + "bidder": { + "publisher": "123456", + "placement": "234567" + } + } + }] + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 400 + } + }], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info.", + "comparison": "literal" + } + ] +} diff --git a/adapters/aduptech/aduptechtest/supplemental/status-500.json b/adapters/aduptech/aduptechtest/supplemental/status-500.json new file mode 100644 index 00000000000..ea5800cd295 --- /dev/null +++ b/adapters/aduptech/aduptechtest/supplemental/status-500.json @@ -0,0 +1,59 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "id": "123", + "page": "https://good.site/url" + }, + "imp": [{ + "id": "test-imp-id", + "native": { + "ver": "1.2", + "request": "{\"context\":2,\"contextsubtype\":20,\"plcmttype\":4,\"plcmtcnt\":1,\"urlsupport\":0,\"privacy\":1,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"assets\":[{\"id\":123,\"required\":1,\"title\":{\"len\":140}},{\"id\":128,\"required\":0,\"img\":{\"wmin\":300,\"hmin\":250,\"type\":3}},{\"id\":129,\"required\":0,\"img\":{\"type\":2}},{\"id\":127,\"required\":1,\"data\":{\"type\":2,\"len\":140}}]}" + }, + "ext": { + "bidder": { + "publisher": "123456", + "placement": "234567" + } + } + }] + }, + + "httpCalls": [{ + "expectedRequest": { + "uri": "https://example.com/rtb/bid", + "body": { + "id": "test-request-id", + "site": { + "id": "123", + "page": "https://good.site/url" + }, + "imp": [{ + "id": "test-imp-id", + "native": { + "ver": "1.2", + "request": "{\"context\":2,\"contextsubtype\":20,\"plcmttype\":4,\"plcmtcnt\":1,\"urlsupport\":0,\"privacy\":1,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"assets\":[{\"id\":123,\"required\":1,\"title\":{\"len\":140}},{\"id\":128,\"required\":0,\"img\":{\"wmin\":300,\"hmin\":250,\"type\":3}},{\"id\":129,\"required\":0,\"img\":{\"type\":2}},{\"id\":127,\"required\":1,\"data\":{\"type\":2,\"len\":140}}]}" + }, + "ext": { + "bidder": { + "publisher": "123456", + "placement": "234567" + } + } + }] + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 500 + } + }], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 500.", + "comparison": "literal" + } + ] +} diff --git a/adapters/aduptech/aduptechtest/supplemental/unsupported-mtype.json b/adapters/aduptech/aduptechtest/supplemental/unsupported-mtype.json new file mode 100644 index 00000000000..f7256f4901d --- /dev/null +++ b/adapters/aduptech/aduptechtest/supplemental/unsupported-mtype.json @@ -0,0 +1,91 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "id": "123", + "page": "https://good.site/url" + }, + "imp": [{ + "id": "test-imp-id", + "native": { + "ver": "1.2", + "request": "{\"context\":2,\"contextsubtype\":20,\"plcmttype\":4,\"plcmtcnt\":1,\"urlsupport\":0,\"privacy\":1,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"assets\":[{\"id\":123,\"required\":1,\"title\":{\"len\":140}},{\"id\":128,\"required\":0,\"img\":{\"wmin\":300,\"hmin\":250,\"type\":3}},{\"id\":129,\"required\":0,\"img\":{\"type\":2}},{\"id\":127,\"required\":1,\"data\":{\"type\":2,\"len\":140}}]}" + }, + "ext": { + "bidder": { + "publisher": "123456", + "placement": "234567" + } + } + }] + }, + + "httpCalls": [{ + "expectedRequest": { + "uri": "https://example.com/rtb/bid", + "body": { + "id": "test-request-id", + "site": { + "id": "123", + "page": "https://good.site/url" + }, + "imp": [{ + "id": "test-imp-id", + "native": { + "ver": "1.2", + "request": "{\"context\":2,\"contextsubtype\":20,\"plcmttype\":4,\"plcmtcnt\":1,\"urlsupport\":0,\"privacy\":1,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"assets\":[{\"id\":123,\"required\":1,\"title\":{\"len\":140}},{\"id\":128,\"required\":0,\"img\":{\"wmin\":300,\"hmin\":250,\"type\":3}},{\"id\":129,\"required\":0,\"img\":{\"type\":2}},{\"id\":127,\"required\":1,\"data\":{\"type\":2,\"len\":140}}]}" + }, + "ext": { + "bidder": { + "publisher": "123456", + "placement": "234567" + } + } + }] + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [{ + "seat": "grid", + "bid": [{ + "id": "some-id", + "impid": "test-imp-id", + "price": 0.010526, + "adomain": [ + "example.com" + ], + "crid": "12345678", + "mtype": 3, + "ext": { + "dsa": { + "adrender": 0, + "behalf": "example.com", + "paid": "Example Site", + "transparency": [ + { + "domain": "adup-tech.com", + "params": [ + 2 + ] + } + ] + } + } + }] + }], + "currency": "EUR" + } + } + }], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "Unknown markup type: 3", + "comparison": "literal" + } + ] +} diff --git a/adapters/aduptech/params_test.go b/adapters/aduptech/params_test.go index 16393782450..40f077e39ad 100644 --- a/adapters/aduptech/params_test.go +++ b/adapters/aduptech/params_test.go @@ -2,9 +2,10 @@ package aduptech import ( "encoding/json" - "github.com/stretchr/testify/assert" "testing" + "github.com/stretchr/testify/assert" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) diff --git a/static/bidder-info/aduptech.yaml b/static/bidder-info/aduptech.yaml index 7645ddf319a..8c1e426c850 100644 --- a/static/bidder-info/aduptech.yaml +++ b/static/bidder-info/aduptech.yaml @@ -20,8 +20,8 @@ capabilities: - native userSync: redirect: - url: "https://rtb.adup-tech.com/service/usersync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}}" + url: "https://rtb.d.adup-tech.com/service/sync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}}" userMacro: "[UID]" iframe: - url: "https://rtb.adup-tech.com/service/usersync?iframe=1&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}}" + url: "https://rtb.d.adup-tech.com/service/sync?iframe=1&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}}" userMacro: "[UID]" \ No newline at end of file From 4f3580c5e5ce4088e53dc4c56b1f1f1862c058cc Mon Sep 17 00:00:00 2001 From: Dany Gielow Date: Mon, 13 Jan 2025 13:43:36 +0100 Subject: [PATCH 03/11] test: fixed broken-response and unsupported-mtype tests --- .../supplemental/broken-response.json | 27 ++++++------------- .../supplemental/unsupported-mtype.json | 2 +- 2 files changed, 9 insertions(+), 20 deletions(-) diff --git a/adapters/aduptech/aduptechtest/supplemental/broken-response.json b/adapters/aduptech/aduptechtest/supplemental/broken-response.json index 69c7655418c..c97da5a88fa 100644 --- a/adapters/aduptech/aduptechtest/supplemental/broken-response.json +++ b/adapters/aduptech/aduptechtest/supplemental/broken-response.json @@ -58,7 +58,7 @@ { "seat": "958", "bid": [{ - "id": "7706636740145184841", + "id":123, "impid": "test-imp-id", "price": 0.500000, "adm": "some-test-ad", @@ -74,22 +74,11 @@ } } }], - - "expectedBidResponses": [{ - "currency": "EUR", - "bids": [{ - "bid": { - "id": "7706636740145184841", - "impid": "test-imp-id", - "price": 0.500000, - "adm": "some-test-ad", - "adomain": ["example.com"], - "crid": "29681110", - "h": 250, - "w": 300, - "mtype": 1 - }, - "type": "banner" - }] - }] + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "cannot unmarshal openrtb2.Bid.ID: expects \" or n, but found 1", + "comparison": "literal" + } + ] } diff --git a/adapters/aduptech/aduptechtest/supplemental/unsupported-mtype.json b/adapters/aduptech/aduptechtest/supplemental/unsupported-mtype.json index f7256f4901d..5d4ab7bd7cb 100644 --- a/adapters/aduptech/aduptechtest/supplemental/unsupported-mtype.json +++ b/adapters/aduptech/aduptechtest/supplemental/unsupported-mtype.json @@ -81,7 +81,7 @@ } } }], - "expectedBidResponses": [], + "expectedBidResponses": [{"currency":"EUR","bids":[]}], "expectedMakeBidsErrors": [ { "value": "Unknown markup type: 3", From 1dc4b167b96da13706299548523bd986fce1ad2f Mon Sep 17 00:00:00 2001 From: Dany Gielow Date: Mon, 13 Jan 2025 14:06:14 +0100 Subject: [PATCH 04/11] test(aduptech): added currency-conversion-failure test --- .../currency-conversion-failure.json | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 adapters/aduptech/aduptechtest/supplemental/currency-conversion-failure.json diff --git a/adapters/aduptech/aduptechtest/supplemental/currency-conversion-failure.json b/adapters/aduptech/aduptechtest/supplemental/currency-conversion-failure.json new file mode 100644 index 00000000000..8b27a0c496e --- /dev/null +++ b/adapters/aduptech/aduptechtest/supplemental/currency-conversion-failure.json @@ -0,0 +1,45 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "https://good.site/url" + }, + "imp": [{ + "id": "test-imp-id", + "bidfloor": 1.0, + "bidfloorcur": "AUD", + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + }, + "ext": { + "bidder": { + "publisher": "123456", + "placement": "234567" + } + } + }], + "ext": { + "prebid": { + "currency": { + "rates": { + "USD": { + "AUD": 2.0 + } + }, + "usepbsrates": false + } + } + } + }, + "httpCalls": [], + "expectedBidResponses": [], + "expectedMakeRequestsErrors": [ + { + "value": "Currency conversion rate not found: 'USD' => 'EUR'", + "comparison": "literal" + } + ] +} From ec665c15d659f4033fdac479528f6f28533e11b2 Mon Sep 17 00:00:00 2001 From: Dany Gielow Date: Thu, 16 Jan 2025 07:01:15 +0100 Subject: [PATCH 05/11] style(aduptech): small code formatting changes --- adapters/aduptech/aduptech_test.go | 28 ++++++++++++++++++++++++---- adapters/aduptech/params_test.go | 14 ++++++++++++-- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/adapters/aduptech/aduptech_test.go b/adapters/aduptech/aduptech_test.go index 75cbe5d5c1f..f6322380b54 100644 --- a/adapters/aduptech/aduptech_test.go +++ b/adapters/aduptech/aduptech_test.go @@ -12,8 +12,18 @@ import ( ) func TestJsonSamples(t *testing.T) { - bidder, buildErr := Builder(openrtb_ext.BidderAdUpTech, config.Adapter{ - Endpoint: "https://example.com/rtb/bid", ExtraAdapterInfo: "{\"target_currency\": \"EUR\"}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + bidder, buildErr := Builder( + openrtb_ext.BidderAdUpTech, + config.Adapter{ + Endpoint: "https://example.com/rtb/bid", + ExtraAdapterInfo: `{"target_currency": "EUR"}`, + }, + config.Server{ + ExternalUrl: "http://hosturl.com", + GvlID: 1, + DataCenter: "2", + }, + ) require.NoError(t, buildErr, "Builder returned unexpected error") @@ -21,8 +31,18 @@ func TestJsonSamples(t *testing.T) { } func TestInvalidExtraAdapterInfo(t *testing.T) { - _, buildErr := Builder(openrtb_ext.BidderAdUpTech, config.Adapter{ - Endpoint: "https://example.com/rtb/bid", ExtraAdapterInfo: "{\"foo\": \"bar\"}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + _, buildErr := Builder( + openrtb_ext.BidderAdUpTech, + config.Adapter{ + Endpoint: "https://example.com/rtb/bid", + ExtraAdapterInfo: `{"foo": "bar"}`, + }, + config.Server{ + ExternalUrl: "http://hosturl.com", + GvlID: 1, + DataCenter: "2", + }, + ) assert.EqualError(t, buildErr, "invalid extra info: TargetCurrency is empty, pls check") } diff --git a/adapters/aduptech/params_test.go b/adapters/aduptech/params_test.go index 40f077e39ad..277304e7d2f 100644 --- a/adapters/aduptech/params_test.go +++ b/adapters/aduptech/params_test.go @@ -26,7 +26,12 @@ func TestValidParams(t *testing.T) { } for _, validParam := range validParams { - assert.NoErrorf(t, validator.Validate(openrtb_ext.BidderAdUpTech, json.RawMessage(validParam)), "Schema rejected Aduptech params: %s", validParam) + assert.NoErrorf( + t, + validator.Validate(openrtb_ext.BidderAdUpTech, json.RawMessage(validParam)), + "Schema rejected Aduptech params: %s", + validParam, + ) } } @@ -56,6 +61,11 @@ func TestInvalidParams(t *testing.T) { } for _, invalidParam := range invalidParams { - assert.Errorf(t, validator.Validate(openrtb_ext.BidderAdUpTech, json.RawMessage(invalidParam)), "Schema allowed unexpected params: %s", invalidParam) + assert.Errorf( + t, + validator.Validate(openrtb_ext.BidderAdUpTech, json.RawMessage(invalidParam)), + "Schema allowed unexpected params: %s", + invalidParam, + ) } } From 2a38edc0ca2c3a743e6644c7a431b65a501c64b6 Mon Sep 17 00:00:00 2001 From: Dany Gielow Date: Wed, 22 Jan 2025 13:33:58 +0100 Subject: [PATCH 06/11] feat(aduptech): using IsResponseStatusCodeNoContent and CheckResponseStatusCodeForErrors to check response status codes --- adapters/aduptech/aduptech.go | 19 +++++-------------- .../aduptechtest/supplemental/status-400.json | 2 +- .../aduptechtest/supplemental/status-500.json | 2 +- 3 files changed, 7 insertions(+), 16 deletions(-) diff --git a/adapters/aduptech/aduptech.go b/adapters/aduptech/aduptech.go index 37052089000..c3977e1d65e 100644 --- a/adapters/aduptech/aduptech.go +++ b/adapters/aduptech/aduptech.go @@ -31,7 +31,7 @@ func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server co } if extraInfo.TargetCurrency == "" { - return nil, fmt.Errorf("invalid extra info: TargetCurrency is empty, pls check") + return nil, errors.New("invalid extra info: TargetCurrency is empty, pls check") } bidder := &adapter{ @@ -104,21 +104,12 @@ func (a *adapter) convertCurrency(value float64, cur string, reqInfo *adapters.E } func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { - switch responseData.StatusCode { - case http.StatusNoContent: + if adapters.IsResponseStatusCodeNoContent(responseData) { return nil, nil - case http.StatusBadRequest: - return nil, []error{&errortypes.BadInput{ - Message: "Unexpected status code: 400. Run with request.debug = 1 for more info.", - }} - case http.StatusOK: - // we don't need to do anything here and this is just so we can use the default case for the unexpected status code - break - default: - return nil, []error{&errortypes.BadServerResponse{ - Message: fmt.Sprintf("Unexpected status code: %d.", responseData.StatusCode), - }} + } + if err := adapters.CheckResponseStatusCodeForErrors(responseData); err != nil { + return nil, []error{err} } var response openrtb2.BidResponse diff --git a/adapters/aduptech/aduptechtest/supplemental/status-400.json b/adapters/aduptech/aduptechtest/supplemental/status-400.json index 11d3a7f8dd3..6a6d3f031b4 100644 --- a/adapters/aduptech/aduptechtest/supplemental/status-400.json +++ b/adapters/aduptech/aduptechtest/supplemental/status-400.json @@ -52,7 +52,7 @@ "expectedBidResponses": [], "expectedMakeBidsErrors": [ { - "value": "Unexpected status code: 400. Run with request.debug = 1 for more info.", + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", "comparison": "literal" } ] diff --git a/adapters/aduptech/aduptechtest/supplemental/status-500.json b/adapters/aduptech/aduptechtest/supplemental/status-500.json index ea5800cd295..d7cf7ad07a9 100644 --- a/adapters/aduptech/aduptechtest/supplemental/status-500.json +++ b/adapters/aduptech/aduptechtest/supplemental/status-500.json @@ -52,7 +52,7 @@ "expectedBidResponses": [], "expectedMakeBidsErrors": [ { - "value": "Unexpected status code: 500.", + "value": "Unexpected status code: 500. Run with request.debug = 1 for more info", "comparison": "literal" } ] From 55f2048815a25cc60c54402f05d710cbfa151264 Mon Sep 17 00:00:00 2001 From: Dany Gielow Date: Wed, 22 Jan 2025 13:36:03 +0100 Subject: [PATCH 07/11] fix(aduptech): fixed types in ExtImpAduptech, added minlength constraint to publisher and placement param, added params tests --- adapters/aduptech/params_test.go | 3 +++ openrtb_ext/imp_aduptech.go | 3 ++- static/bidder-params/aduptech.json | 2 ++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/adapters/aduptech/params_test.go b/adapters/aduptech/params_test.go index 277304e7d2f..ce0ae7d1265 100644 --- a/adapters/aduptech/params_test.go +++ b/adapters/aduptech/params_test.go @@ -10,7 +10,9 @@ import ( ) var validParams = []string{ + `{ "publisher": "1", "placement": "2" }`, `{ "publisher": "123456789", "placement": "234567890" }`, + `{ "publisher": "123456789", "placement": "234567890", "query": "" }`, `{ "publisher": "123456789", "placement": "234567890", "query": "test" }`, `{ "publisher": "123456789", "placement": "234567890", "adtest": true }`, `{ "publisher": "123456789", "placement": "234567890", "debug": true }`, @@ -46,6 +48,7 @@ var invalidParams = []string{ `{ "publisher": "123456789" }`, `{ "placement": "234567890" }`, `{ "publisher": null, "placement": null }`, + `{ "publisher": "", "placement": "" }`, `{ "publisher": "123456789", "placement": "234567890", "query": null }`, `{ "publisher": "123456789", "placement": "234567890", "adtest": null }`, `{ "publisher": "123456789", "placement": "234567890", "debug": null }`, diff --git a/openrtb_ext/imp_aduptech.go b/openrtb_ext/imp_aduptech.go index 184d33ca453..b91b1d0da0d 100644 --- a/openrtb_ext/imp_aduptech.go +++ b/openrtb_ext/imp_aduptech.go @@ -6,6 +6,7 @@ type ExtImpAduptech struct { Publisher string `json:"publisher"` Placement string `json:"placement"` Query string `json:"query"` - AdTest string `json:"adtest"` + AdTest bool `json:"adtest"` + Debug bool `json:"debug,omitempty"` Ext json.RawMessage `json:"ext,omitempty"` } diff --git a/static/bidder-params/aduptech.json b/static/bidder-params/aduptech.json index 512b634a362..98c5086d5bf 100644 --- a/static/bidder-params/aduptech.json +++ b/static/bidder-params/aduptech.json @@ -7,10 +7,12 @@ "properties": { "publisher": { "type": "string", + "minLength": 1, "description": "Unique publisher identifier." }, "placement": { "type": "string", + "minLength": 1, "description": "Unique placement identifier per publisher." }, "query": { From 8315a5029d117d7a04a5341311eab4715b4a201c Mon Sep 17 00:00:00 2001 From: Dany Gielow Date: Wed, 22 Jan 2025 13:36:29 +0100 Subject: [PATCH 08/11] test(aduptech): added test for invalid bidfloor currency --- .../currency-conversion-invalid-currency.json | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 adapters/aduptech/aduptechtest/supplemental/currency-conversion-invalid-currency.json diff --git a/adapters/aduptech/aduptechtest/supplemental/currency-conversion-invalid-currency.json b/adapters/aduptech/aduptechtest/supplemental/currency-conversion-invalid-currency.json new file mode 100644 index 00000000000..d9d9e1e59ed --- /dev/null +++ b/adapters/aduptech/aduptechtest/supplemental/currency-conversion-invalid-currency.json @@ -0,0 +1,45 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "https://good.site/url" + }, + "imp": [{ + "id": "test-imp-id", + "bidfloor": 1.0, + "bidfloorcur": "INVALID", + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + }, + "ext": { + "bidder": { + "publisher": "123456", + "placement": "234567" + } + } + }], + "ext": { + "prebid": { + "currency": { + "rates": { + "EUR": { + "USD": 0.05 + } + }, + "usepbsrates": false + } + } + } + }, + "httpCalls": [], + "expectedBidResponses": [], + "expectedMakeRequestsErrors": [ + { + "value": "currency: tag is not well-formed", + "comparison": "literal" + } + ] +} From 37adf4249bfcd3bc2578ab91d0078eeec423f5a6 Mon Sep 17 00:00:00 2001 From: Dany Gielow Date: Mon, 27 Jan 2025 12:50:53 +0100 Subject: [PATCH 09/11] test(aduptech): added test for intermediate failures in currency conversion --- ...rency-conversion-intermediate-failure.json | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 adapters/aduptech/aduptechtest/supplemental/currency-conversion-intermediate-failure.json diff --git a/adapters/aduptech/aduptechtest/supplemental/currency-conversion-intermediate-failure.json b/adapters/aduptech/aduptechtest/supplemental/currency-conversion-intermediate-failure.json new file mode 100644 index 00000000000..0eab3944dc6 --- /dev/null +++ b/adapters/aduptech/aduptechtest/supplemental/currency-conversion-intermediate-failure.json @@ -0,0 +1,46 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "https://good.site/url" + }, + "imp": [{ + "id": "test-imp-id", + "bidfloor": 1.0, + "bidfloorcur": "AUD", + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + }, + "ext": { + "bidder": { + "publisher": "123456", + "placement": "234567" + } + } + }], + "ext": { + "prebid": { + "currency": { + "rates": { + "EUR": { + "USD": 0.05 + } + }, + "usepbsrates": false + } + } + } + }, + "httpCalls": [], + "expectedBidResponses": [], + "expectedMakeRequestsErrors": [ + { + "value": "Currency conversion rate not found: 'AUD' => 'USD'", + "comparison": "literal" + } + ] + } + \ No newline at end of file From 09f4c2ca07363e2e34d44446b1ecbca7744e3cd3 Mon Sep 17 00:00:00 2001 From: Dany Gielow Date: Tue, 28 Jan 2025 06:33:13 +0100 Subject: [PATCH 10/11] feat(aduptech): check target currency in Builder --- adapters/aduptech/aduptech.go | 11 +++++++++-- adapters/aduptech/aduptech_test.go | 17 +++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/adapters/aduptech/aduptech.go b/adapters/aduptech/aduptech.go index c3977e1d65e..964c9287eed 100644 --- a/adapters/aduptech/aduptech.go +++ b/adapters/aduptech/aduptech.go @@ -9,10 +9,11 @@ import ( "github.com/prebid/openrtb/v20/openrtb2" "github.com/prebid/prebid-server/v3/adapters" "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v3/currency" + prebidcurrency "github.com/prebid/prebid-server/v3/currency" "github.com/prebid/prebid-server/v3/errortypes" "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/prebid/prebid-server/v3/util/jsonutil" + "golang.org/x/text/currency" ) type adapter struct { @@ -34,6 +35,12 @@ func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server co return nil, errors.New("invalid extra info: TargetCurrency is empty, pls check") } + parsedCurrency, err := currency.ParseISO(extraInfo.TargetCurrency) + if err != nil { + return nil, fmt.Errorf("invalid extra info: invalid TargetCurrency %s, pls check", extraInfo.TargetCurrency) + } + extraInfo.TargetCurrency = parsedCurrency.String() + bidder := &adapter{ endpoint: config.Endpoint, extraInfo: extraInfo, @@ -81,7 +88,7 @@ func (a *adapter) convertCurrency(value float64, cur string, reqInfo *adapters.E convertedValue, err := reqInfo.ConvertCurrency(value, cur, a.extraInfo.TargetCurrency) if err != nil { - var convErr currency.ConversionNotFoundError + var convErr prebidcurrency.ConversionNotFoundError if !errors.As(err, &convErr) { return 0, err } diff --git a/adapters/aduptech/aduptech_test.go b/adapters/aduptech/aduptech_test.go index f6322380b54..64dc6b3d41c 100644 --- a/adapters/aduptech/aduptech_test.go +++ b/adapters/aduptech/aduptech_test.go @@ -46,3 +46,20 @@ func TestInvalidExtraAdapterInfo(t *testing.T) { assert.EqualError(t, buildErr, "invalid extra info: TargetCurrency is empty, pls check") } + +func TestInvalidTargetCurrency(t *testing.T) { + _, buildErr := Builder( + openrtb_ext.BidderAdUpTech, + config.Adapter{ + Endpoint: "https://example.com/rtb/bid", + ExtraAdapterInfo: `{"target_currency": "INVALID"}`, + }, + config.Server{ + ExternalUrl: "http://hosturl.com", + GvlID: 1, + DataCenter: "2", + }, + ) + + assert.EqualError(t, buildErr, "invalid extra info: invalid TargetCurrency INVALID, pls check") +} From 842d4e73cc2e196a80710ca19bf0dc2e5ce410b9 Mon Sep 17 00:00:00 2001 From: Dany Gielow Date: Wed, 29 Jan 2025 06:51:01 +0100 Subject: [PATCH 11/11] feat(aduptech): changed log messages in convertCurrency --- adapters/aduptech/aduptech.go | 4 ++-- .../supplemental/currency-conversion-failure.json | 2 +- .../currency-conversion-intermediate-failure.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/adapters/aduptech/aduptech.go b/adapters/aduptech/aduptech.go index 964c9287eed..dee3e679ef9 100644 --- a/adapters/aduptech/aduptech.go +++ b/adapters/aduptech/aduptech.go @@ -98,13 +98,13 @@ func (a *adapter) convertCurrency(value float64, cur string, reqInfo *adapters.E convertedValue, err = reqInfo.ConvertCurrency(value, cur, "USD") if err != nil { - return 0, err + return 0, fmt.Errorf("Currency conversion rate not found from '%s' to '%s'. Error converting from '%s' to 'USD': %w", cur, a.extraInfo.TargetCurrency, cur, err) } convertedValue, err = reqInfo.ConvertCurrency(convertedValue, "USD", a.extraInfo.TargetCurrency) if err != nil { - return 0, err + return 0, fmt.Errorf("Currency conversion rate not found from '%s' to '%s'. Error converting from 'USD' to '%s': %w", cur, a.extraInfo.TargetCurrency, a.extraInfo.TargetCurrency, err) } } return convertedValue, nil diff --git a/adapters/aduptech/aduptechtest/supplemental/currency-conversion-failure.json b/adapters/aduptech/aduptechtest/supplemental/currency-conversion-failure.json index 8b27a0c496e..bb818faa273 100644 --- a/adapters/aduptech/aduptechtest/supplemental/currency-conversion-failure.json +++ b/adapters/aduptech/aduptechtest/supplemental/currency-conversion-failure.json @@ -38,7 +38,7 @@ "expectedBidResponses": [], "expectedMakeRequestsErrors": [ { - "value": "Currency conversion rate not found: 'USD' => 'EUR'", + "value": "Currency conversion rate not found from 'AUD' to 'EUR'. Error converting from 'USD' to 'EUR': Currency conversion rate not found: 'USD' => 'EUR'", "comparison": "literal" } ] diff --git a/adapters/aduptech/aduptechtest/supplemental/currency-conversion-intermediate-failure.json b/adapters/aduptech/aduptechtest/supplemental/currency-conversion-intermediate-failure.json index 0eab3944dc6..a92fc2b4afe 100644 --- a/adapters/aduptech/aduptechtest/supplemental/currency-conversion-intermediate-failure.json +++ b/adapters/aduptech/aduptechtest/supplemental/currency-conversion-intermediate-failure.json @@ -38,7 +38,7 @@ "expectedBidResponses": [], "expectedMakeRequestsErrors": [ { - "value": "Currency conversion rate not found: 'AUD' => 'USD'", + "value": "Currency conversion rate not found from 'AUD' to 'EUR'. Error converting from 'AUD' to 'USD': Currency conversion rate not found: 'AUD' => 'USD'", "comparison": "literal" } ]