From e7f7b558951684f1fb75bc4c180506cdc91b5f98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Fern=C3=A1ndez?= Date: Thu, 8 Jul 2021 19:29:46 +0200 Subject: [PATCH] New Adapter: Axonix (#1912) * New Axonix adapter * Changed endpoint * Rename adapter type * Leave in examplary only the basic test fixtures * PR comments --- adapters/axonix/axonix.go | 116 +++++++++++++ adapters/axonix/axonix_test.go | 30 ++++ .../exemplary/banner-and-video.json | 133 +++++++++++++++ .../exemplary/banner-video-native.json | 157 ++++++++++++++++++ .../axonixtest/exemplary/simple-banner.json | 105 ++++++++++++ .../axonixtest/exemplary/simple-video.json | 86 ++++++++++ .../axonix/axonixtest/params/race/banner.json | 3 + .../axonix/axonixtest/params/race/video.json | 3 + .../supplemental/bad-response-no-body.json | 57 +++++++ .../supplemental/status-bad-request.json | 58 +++++++ .../supplemental/status-no-content.json | 53 ++++++ .../supplemental/unexpected-status-code.json | 58 +++++++ .../supplemental/valid-extension.json | 86 ++++++++++ .../supplemental/valid-with-device.json | 93 +++++++++++ adapters/axonix/params_test.go | 59 +++++++ config/config.go | 1 + exchange/adapter_builders.go | 2 + openrtb_ext/bidders.go | 2 + openrtb_ext/imp_axonix.go | 5 + static/bidder-info/axonix.yaml | 15 ++ static/bidder-params/axonix.json | 14 ++ usersync/usersyncers/syncer_test.go | 1 + 22 files changed, 1137 insertions(+) create mode 100644 adapters/axonix/axonix.go create mode 100644 adapters/axonix/axonix_test.go create mode 100644 adapters/axonix/axonixtest/exemplary/banner-and-video.json create mode 100644 adapters/axonix/axonixtest/exemplary/banner-video-native.json create mode 100644 adapters/axonix/axonixtest/exemplary/simple-banner.json create mode 100644 adapters/axonix/axonixtest/exemplary/simple-video.json create mode 100644 adapters/axonix/axonixtest/params/race/banner.json create mode 100644 adapters/axonix/axonixtest/params/race/video.json create mode 100644 adapters/axonix/axonixtest/supplemental/bad-response-no-body.json create mode 100644 adapters/axonix/axonixtest/supplemental/status-bad-request.json create mode 100644 adapters/axonix/axonixtest/supplemental/status-no-content.json create mode 100644 adapters/axonix/axonixtest/supplemental/unexpected-status-code.json create mode 100644 adapters/axonix/axonixtest/supplemental/valid-extension.json create mode 100644 adapters/axonix/axonixtest/supplemental/valid-with-device.json create mode 100644 adapters/axonix/params_test.go create mode 100644 openrtb_ext/imp_axonix.go create mode 100644 static/bidder-info/axonix.yaml create mode 100644 static/bidder-params/axonix.json diff --git a/adapters/axonix/axonix.go b/adapters/axonix/axonix.go new file mode 100644 index 00000000000..d3016235319 --- /dev/null +++ b/adapters/axonix/axonix.go @@ -0,0 +1,116 @@ +package axonix + +import ( + "encoding/json" + "fmt" + "net/http" + + "github.com/mxmCherry/openrtb/v15/openrtb2" + "github.com/prebid/prebid-server/adapters" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/errortypes" + "github.com/prebid/prebid-server/openrtb_ext" +) + +type adapter struct { + URI string +} + +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter) (adapters.Bidder, error) { + bidder := &adapter{ + URI: config.Endpoint, + } + return bidder, nil +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + var errors []error + + var bidderExt adapters.ExtImpBidder + if err := json.Unmarshal(request.Imp[0].Ext, &bidderExt); err != nil { + errors = append(errors, &errortypes.BadInput{ + Message: err.Error(), + }) + + return nil, errors + } + + var axonixExt openrtb_ext.ExtImpAxonix + if err := json.Unmarshal(bidderExt.Bidder, &axonixExt); err != nil { + errors = append(errors, &errortypes.BadInput{ + Message: err.Error(), + }) + + return nil, errors + } + + thisURI := a.URI + if len(thisURI) == 0 { + thisURI = "https://openrtb-us-east-1.axonix.com/supply/prebid-server/" + axonixExt.SupplyId + } + + requestJSON, err := json.Marshal(request) + if err != nil { + errors = append(errors, err) + return nil, errors + } + + headers := http.Header{} + headers.Add("Content-Type", "application/json") + + requestData := &adapters.RequestData{ + Method: "POST", + Uri: thisURI, + Body: requestJSON, + Headers: headers, + } + + return []*adapters.RequestData{requestData}, nil +} + +func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if responseData.StatusCode == http.StatusNoContent { + return nil, nil + } + + if responseData.StatusCode != http.StatusOK { + err := &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Unexpected status code: %d.", responseData.StatusCode), + } + return nil, []error{err} + } + + var response openrtb2.BidResponse + if err := json.Unmarshal(responseData.Body, &response); err != nil { + return nil, []error{err} + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) + bidResponse.Currency = response.Cur + for _, seatBid := range response.SeatBid { + for _, bid := range seatBid.Bid { + bid := bid + b := &adapters.TypedBid{ + Bid: &bid, + BidType: getMediaType(bid.ImpID, request.Imp), + } + bidResponse.Bids = append(bidResponse.Bids, b) + } + } + + return bidResponse, nil +} + +func getMediaType(impId string, imps []openrtb2.Imp) openrtb_ext.BidType { + for _, imp := range imps { + if imp.ID == impId { + if imp.Native != nil { + return openrtb_ext.BidTypeNative + } else if imp.Video != nil { + return openrtb_ext.BidTypeVideo + } + return openrtb_ext.BidTypeBanner + } + } + return openrtb_ext.BidTypeBanner +} diff --git a/adapters/axonix/axonix_test.go b/adapters/axonix/axonix_test.go new file mode 100644 index 00000000000..6c4a3eb34d6 --- /dev/null +++ b/adapters/axonix/axonix_test.go @@ -0,0 +1,30 @@ +package axonix + +import ( + "testing" + + "github.com/prebid/prebid-server/adapters/adapterstest" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/openrtb_ext" +) + +func TestJsonSamplesWithConfiguredURI(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderAxonix, config.Adapter{ + Endpoint: "https://openrtb-us-east-1.axonix.com/supply/prebid-server/24cc9034-f861-47b8-a6a8-b7e0968c00b8"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "axonixtest", bidder) +} + +func TestJsonSamplesWithHardcodedURI(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderAxonix, config.Adapter{}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "axonixtest", bidder) +} diff --git a/adapters/axonix/axonixtest/exemplary/banner-and-video.json b/adapters/axonix/axonixtest/exemplary/banner-and-video.json new file mode 100644 index 00000000000..1755cd0ef22 --- /dev/null +++ b/adapters/axonix/axonixtest/exemplary/banner-and-video.json @@ -0,0 +1,133 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8" + } + } + }, + { + "id": "test-imp-video-id", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://openrtb-us-east-1.axonix.com/supply/prebid-server/24cc9034-f861-47b8-a6a8-b7e0968c00b8", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8" + } + } + }, + { + "id": "test-imp-video-id", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "958", + "bid": [{ + "id": "7706636740145184841", + "impid": "test-imp-video-id", + "price": 0.500000, + "adid": "29681110", + "adm": "some-test-ad", + "adomain": ["axonix.com"], + "cid": "958", + "crid": "29681110", + "h": 576, + "w": 1024 + }] + } + ], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + } + ], + + "expectedBidResponses": [ + { + "bids": [{ + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-video-id", + "price": 0.5, + "adm": "some-test-ad", + "adid": "29681110", + "adomain": ["axonix.com"], + "cid": "958", + "crid": "29681110", + "w": 1024, + "h": 576 + }, + "type": "video" + }] + } + ] + +} diff --git a/adapters/axonix/axonixtest/exemplary/banner-video-native.json b/adapters/axonix/axonixtest/exemplary/banner-video-native.json new file mode 100644 index 00000000000..3944eb358b9 --- /dev/null +++ b/adapters/axonix/axonixtest/exemplary/banner-video-native.json @@ -0,0 +1,157 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8" + } + } + }, + { + "id": "native-imp", + "native": { + "ver": "1.1", + "request": "{\"ver\":\"1.1\",\"context\":1,\"contextsubtype\":11,\"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}}]}" + }, + "ext": { + "bidder": { + "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8" + } + } + }, + { + "id": "test-imp-video-id", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://openrtb-us-east-1.axonix.com/supply/prebid-server/24cc9034-f861-47b8-a6a8-b7e0968c00b8", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8" + } + } + }, + { + "id": "native-imp", + "native": { + "ver": "1.1", + "request": "{\"ver\":\"1.1\",\"context\":1,\"contextsubtype\":11,\"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}}]}" + }, + "ext": { + "bidder": { + "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8" + } + } + }, + { + "id": "test-imp-video-id", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "958", + "bid": [{ + "id": "7706636740145184841", + "impid": "test-imp-video-id", + "price": 0.500000, + "adid": "29681110", + "adm": "some-test-ad", + "adomain": ["axonix.com"], + "cid": "958", + "crid": "29681110", + "h": 576, + "w": 1024 + }] + } + ], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + } + ], + + "expectedBidResponses": [ + { + "bids": [{ + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-video-id", + "price": 0.5, + "adm": "some-test-ad", + "adid": "29681110", + "adomain": ["axonix.com"], + "cid": "958", + "crid": "29681110", + "w": 1024, + "h": 576 + }, + "type": "video" + }] + } + ] + +} diff --git a/adapters/axonix/axonixtest/exemplary/simple-banner.json b/adapters/axonix/axonixtest/exemplary/simple-banner.json new file mode 100644 index 00000000000..581e59b9b9e --- /dev/null +++ b/adapters/axonix/axonixtest/exemplary/simple-banner.json @@ -0,0 +1,105 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8" + } + } + } + ] + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://openrtb-us-east-1.axonix.com/supply/prebid-server/24cc9034-f861-47b8-a6a8-b7e0968c00b8", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "958", + "bid": [{ + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.500000, + "adid": "29681110", + "adm": "some-test-ad", + "adomain": ["yahoo.com"], + "cid": "958", + "crid": "29681110", + "h": 250, + "w": 300 + }] + } + ], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + } + ], + + "expectedBidResponses": [ + { + "bids": [{ + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "adid": "29681110", + "adomain": ["yahoo.com"], + "cid": "958", + "crid": "29681110", + "w": 300, + "h": 250 + }, + "type": "banner" + }] + } + ] +} diff --git a/adapters/axonix/axonixtest/exemplary/simple-video.json b/adapters/axonix/axonixtest/exemplary/simple-video.json new file mode 100644 index 00000000000..c15d7876470 --- /dev/null +++ b/adapters/axonix/axonixtest/exemplary/simple-video.json @@ -0,0 +1,86 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 1024, + "h": 576 + }, + "ext":{ + "bidder":{ + "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8" + } + } + } + ] + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://openrtb-us-east-1.axonix.com/supply/prebid-server/24cc9034-f861-47b8-a6a8-b7e0968c00b8", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [ + { + "seat": "axonix", + "bid": [{ + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "crid_10", + "w": 1024, + "h": 576 + }] + } + ] + } + } + } + ], + + "expectedBidResponses": [ + { + "bids": [{ + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "crid": "crid_10", + "w": 1024, + "h": 576 + }, + "type": "video" + }] + } + ] +} diff --git a/adapters/axonix/axonixtest/params/race/banner.json b/adapters/axonix/axonixtest/params/race/banner.json new file mode 100644 index 00000000000..7217c9c394f --- /dev/null +++ b/adapters/axonix/axonixtest/params/race/banner.json @@ -0,0 +1,3 @@ +{ + "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8" +} diff --git a/adapters/axonix/axonixtest/params/race/video.json b/adapters/axonix/axonixtest/params/race/video.json new file mode 100644 index 00000000000..7217c9c394f --- /dev/null +++ b/adapters/axonix/axonixtest/params/race/video.json @@ -0,0 +1,3 @@ +{ + "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8" +} diff --git a/adapters/axonix/axonixtest/supplemental/bad-response-no-body.json b/adapters/axonix/axonixtest/supplemental/bad-response-no-body.json new file mode 100644 index 00000000000..f89f40f122d --- /dev/null +++ b/adapters/axonix/axonixtest/supplemental/bad-response-no-body.json @@ -0,0 +1,57 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 1024, + "h": 576 + }, + "ext":{ + "bidder":{ + "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8" + } + } + } + ] + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://openrtb-us-east-1.axonix.com/supply/prebid-server/24cc9034-f861-47b8-a6a8-b7e0968c00b8", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200 + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "unexpected end of JSON input", + "comparison": "literal" + } + ] +} diff --git a/adapters/axonix/axonixtest/supplemental/status-bad-request.json b/adapters/axonix/axonixtest/supplemental/status-bad-request.json new file mode 100644 index 00000000000..d64a855e348 --- /dev/null +++ b/adapters/axonix/axonixtest/supplemental/status-bad-request.json @@ -0,0 +1,58 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 1024, + "h": 576 + }, + "ext":{ + "bidder":{ + "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8" + } + } + } + ] + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://openrtb-us-east-1.axonix.com/supply/prebid-server/24cc9034-f861-47b8-a6a8-b7e0968c00b8", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8" + } + } + } + ] + } + }, + "mockResponse": { + "status": 400, + "body": {} + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400.", + "comparison": "literal" + } + ] +} diff --git a/adapters/axonix/axonixtest/supplemental/status-no-content.json b/adapters/axonix/axonixtest/supplemental/status-no-content.json new file mode 100644 index 00000000000..96dd899c1fb --- /dev/null +++ b/adapters/axonix/axonixtest/supplemental/status-no-content.json @@ -0,0 +1,53 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 1024, + "h": 576 + }, + "ext":{ + "bidder":{ + "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8" + } + } + } + ] + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://openrtb-us-east-1.axonix.com/supply/prebid-server/24cc9034-f861-47b8-a6a8-b7e0968c00b8", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8" + } + } + } + ] + } + }, + "mockResponse": { + "status": 204, + "body": {} + } + } + ], + "expectedMakeBidsErrors": [] +} diff --git a/adapters/axonix/axonixtest/supplemental/unexpected-status-code.json b/adapters/axonix/axonixtest/supplemental/unexpected-status-code.json new file mode 100644 index 00000000000..e7a7be7847e --- /dev/null +++ b/adapters/axonix/axonixtest/supplemental/unexpected-status-code.json @@ -0,0 +1,58 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 1024, + "h": 576 + }, + "ext":{ + "bidder":{ + "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8" + } + } + } + ] + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://openrtb-us-east-1.axonix.com/supply/prebid-server/24cc9034-f861-47b8-a6a8-b7e0968c00b8", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8" + } + } + } + ] + } + }, + "mockResponse": { + "status": 500, + "body": {} + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 500.", + "comparison": "literal" + } + ] +} diff --git a/adapters/axonix/axonixtest/supplemental/valid-extension.json b/adapters/axonix/axonixtest/supplemental/valid-extension.json new file mode 100644 index 00000000000..372f24d4f76 --- /dev/null +++ b/adapters/axonix/axonixtest/supplemental/valid-extension.json @@ -0,0 +1,86 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 1024, + "h": 576 + }, + "ext":{ + "bidder":{ + "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8" + } + } + } + ] + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://openrtb-us-east-1.axonix.com/supply/prebid-server/24cc9034-f861-47b8-a6a8-b7e0968c00b8", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [ + { + "seat": "axonix", + "bid": [{ + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "crid_10", + "w": 1024, + "h": 576 + }] + } + ] + } + } + } + ], + + "expectedBidResponses": [ + { + "bids": [{ + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "crid": "crid_10", + "w": 1024, + "h": 576 + }, + "type": "video" + }] + } + ] +} diff --git a/adapters/axonix/axonixtest/supplemental/valid-with-device.json b/adapters/axonix/axonixtest/supplemental/valid-with-device.json new file mode 100644 index 00000000000..62f4ea06b5a --- /dev/null +++ b/adapters/axonix/axonixtest/supplemental/valid-with-device.json @@ -0,0 +1,93 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "3.0.0.0", + "ua": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.170 Safari/537.36" + }, + "imp": [ + { + "id": "test-imp-video-id", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://openrtb-us-east-1.axonix.com/supply/prebid-server/24cc9034-f861-47b8-a6a8-b7e0968c00b8", + "body": { + "id": "test-request-id", + "device": { + "ip": "3.0.0.0", + "ua": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.170 Safari/537.36" + }, + "imp": [ + { + "id": "test-imp-video-id", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [ + { + "seat": "axonix", + "bid": [{ + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-video-id", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "crid_10", + "w": 1024, + "h": 576 + }] + } + ] + } + } + } + ], + + "expectedBidResponses": [ + { + "bids": [{ + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-video-id", + "price": 0.5, + "adm": "some-test-ad", + "crid": "crid_10", + "w": 1024, + "h": 576 + }, + "type": "video" + }] + } + ] +} diff --git a/adapters/axonix/params_test.go b/adapters/axonix/params_test.go new file mode 100644 index 00000000000..e9c0cc5b83e --- /dev/null +++ b/adapters/axonix/params_test.go @@ -0,0 +1,59 @@ +package axonix + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/openrtb_ext" +) + +// This file actually intends to test static/bidder-params/axonix.json +// +// These also validate the format of the external API: request.imp[i].ext.axonix + +// TestValidParams makes sure that the Axonix 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.BidderAxonix, json.RawMessage(validParam)); err != nil { + t.Errorf("Schema rejected Axonix params: %s", validParam) + } + } +} + +// TestInvalidParams makes sure that the Axonix 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.BidderAxonix, json.RawMessage(invalidParam)); err == nil { + t.Errorf("Schema allowed unexpected params: %s", invalidParam) + } + } +} + +var validParams = []string{ + `{"supplyId": "24cc9034-f861-47b8-a6a8-b7e0968c00b8"}`, + `{"supplyId": "test"}`, +} + +var invalidParams = []string{ + `{"supplyId": 100}`, + `{"supplyId": false}`, + `{"supplyId": true}`, + `{"supplyId": 123}`, + ``, + `null`, + `true`, + `9`, + `1.2`, + `[]`, + `{}`, +} diff --git a/config/config.go b/config/config.go index 34d941bc3ea..bc00a88fdb7 100644 --- a/config/config.go +++ b/config/config.go @@ -840,6 +840,7 @@ func SetupViper(v *viper.Viper, filename string) { v.SetDefault("adapters.audiencenetwork.disabled", true) v.SetDefault("adapters.audiencenetwork.endpoint", "https://an.facebook.com/placementbid.ortb") v.SetDefault("adapters.avocet.disabled", true) + v.SetDefault("adapters.axonix.disabled", true) v.SetDefault("adapters.beachfront.endpoint", "https://display.bfmio.com/prebid_display") v.SetDefault("adapters.beachfront.extra_info", "{\"video_endpoint\":\"https://reachms.bfmio.com/bid.json?exchange_id\"}") v.SetDefault("adapters.beintoo.endpoint", "https://ib.beintoo.com/um") diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 17e0d4f54eb..9adc9ebc671 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -29,6 +29,7 @@ import ( "github.com/prebid/prebid-server/adapters/appnexus" "github.com/prebid/prebid-server/adapters/audienceNetwork" "github.com/prebid/prebid-server/adapters/avocet" + "github.com/prebid/prebid-server/adapters/axonix" "github.com/prebid/prebid-server/adapters/beachfront" "github.com/prebid/prebid-server/adapters/beintoo" "github.com/prebid/prebid-server/adapters/between" @@ -152,6 +153,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderAppnexus: appnexus.Builder, openrtb_ext.BidderAudienceNetwork: audienceNetwork.Builder, openrtb_ext.BidderAvocet: avocet.Builder, + openrtb_ext.BidderAxonix: axonix.Builder, openrtb_ext.BidderBeachfront: beachfront.Builder, openrtb_ext.BidderBeintoo: beintoo.Builder, openrtb_ext.BidderBetween: between.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index f2dd9815e8e..780b75f60b8 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -100,6 +100,7 @@ const ( BidderAppnexus BidderName = "appnexus" BidderAudienceNetwork BidderName = "audienceNetwork" BidderAvocet BidderName = "avocet" + BidderAxonix BidderName = "axonix" BidderBeachfront BidderName = "beachfront" BidderBeintoo BidderName = "beintoo" BidderBetween BidderName = "between" @@ -223,6 +224,7 @@ func CoreBidderNames() []BidderName { BidderAppnexus, BidderAudienceNetwork, BidderAvocet, + BidderAxonix, BidderBeachfront, BidderBeintoo, BidderBetween, diff --git a/openrtb_ext/imp_axonix.go b/openrtb_ext/imp_axonix.go new file mode 100644 index 00000000000..7dd9f68418d --- /dev/null +++ b/openrtb_ext/imp_axonix.go @@ -0,0 +1,5 @@ +package openrtb_ext + +type ExtImpAxonix struct { + SupplyId string `json:"supplyId"` +} diff --git a/static/bidder-info/axonix.yaml b/static/bidder-info/axonix.yaml new file mode 100644 index 00000000000..3c73501d9cc --- /dev/null +++ b/static/bidder-info/axonix.yaml @@ -0,0 +1,15 @@ +maintainer: + email: support.axonix@emodoinc.com +gvlVendorID: 678 +modifyingVastXmlAllowed: true +capabilities: + app: + mediaTypes: + - banner + - video + - native + site: + mediaTypes: + - banner + - video + - native diff --git a/static/bidder-params/axonix.json b/static/bidder-params/axonix.json new file mode 100644 index 00000000000..7a3762ce5e2 --- /dev/null +++ b/static/bidder-params/axonix.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Axonix Adapter Params", + "description": "A schema which validates params accepted by the Axonix adapter", + "type": "object", + "properties": { + "supplyId": { + "type": "string", + "minLength": 1, + "description": "Unique supply identifier" + } + }, + "required": ["supplyId"] +} diff --git a/usersync/usersyncers/syncer_test.go b/usersync/usersyncers/syncer_test.go index 35ceb1b70b5..59ed67cca0b 100644 --- a/usersync/usersyncers/syncer_test.go +++ b/usersync/usersyncers/syncer_test.go @@ -117,6 +117,7 @@ func TestNewSyncerMap(t *testing.T) { openrtb_ext.BidderAdprime: true, openrtb_ext.BidderAlgorix: true, openrtb_ext.BidderApplogy: true, + openrtb_ext.BidderAxonix: true, openrtb_ext.BidderBidmachine: true, openrtb_ext.BidderBidsCube: true, openrtb_ext.BidderEpom: true,