From 0c9c031ecea85b4461aa6f62d9a9703167267cc1 Mon Sep 17 00:00:00 2001 From: Gabriel Chicoye Date: Wed, 2 Apr 2025 13:00:06 +0200 Subject: [PATCH 01/16] initial commit --- adapters/nexx360/nexx360.go | 255 ++++++++++++++++++ adapters/nexx360/nexx360_test.go | 20 ++ .../exemplary/simple-banner-cookie-uid.json | 146 ++++++++++ .../exemplary/simple-banner-inapp.json | 139 ++++++++++ .../simple-banner-multiple-bids.json | 237 ++++++++++++++++ .../exemplary/simple-banner-placement.json | 110 ++++++++ .../nexx360test/exemplary/simple-banner.json | 110 ++++++++ .../exemplary/simple-multi-type-banner.json | 178 ++++++++++++ .../exemplary/simple-multi-type-video.json | 178 ++++++++++++ .../nexx360test/exemplary/simple-native.json | 120 +++++++++ .../nexx360test/exemplary/simple-video.json | 162 +++++++++++ .../supplemental/204-response.json | 121 +++++++++ .../supplemental/400-response.json | 127 +++++++++ .../supplemental/500-response.json | 127 +++++++++ .../supplemental/empty_seatbid.json | 125 +++++++++ .../nexx360/nexx360test/supplemental/ext.json | 33 +++ .../supplemental/wrong-payload.json | 82 ++++++ adapters/nexx360/params_test.go | 50 ++++ exchange/adapter_builders.go | 2 + openrtb_ext/bidders.go | 2 + openrtb_ext/imp_nexx360.go | 7 + static/bidder-info/1accord.yaml | 1 + static/bidder-info/easybid.yaml | 1 + static/bidder-info/nexx360.yaml | 17 ++ static/bidder-params/nexx360.json | 30 +++ 25 files changed, 2380 insertions(+) create mode 100644 adapters/nexx360/nexx360.go create mode 100644 adapters/nexx360/nexx360_test.go create mode 100755 adapters/nexx360/nexx360test/exemplary/simple-banner-cookie-uid.json create mode 100755 adapters/nexx360/nexx360test/exemplary/simple-banner-inapp.json create mode 100644 adapters/nexx360/nexx360test/exemplary/simple-banner-multiple-bids.json create mode 100644 adapters/nexx360/nexx360test/exemplary/simple-banner-placement.json create mode 100644 adapters/nexx360/nexx360test/exemplary/simple-banner.json create mode 100644 adapters/nexx360/nexx360test/exemplary/simple-multi-type-banner.json create mode 100644 adapters/nexx360/nexx360test/exemplary/simple-multi-type-video.json create mode 100644 adapters/nexx360/nexx360test/exemplary/simple-native.json create mode 100644 adapters/nexx360/nexx360test/exemplary/simple-video.json create mode 100644 adapters/nexx360/nexx360test/supplemental/204-response.json create mode 100644 adapters/nexx360/nexx360test/supplemental/400-response.json create mode 100644 adapters/nexx360/nexx360test/supplemental/500-response.json create mode 100644 adapters/nexx360/nexx360test/supplemental/empty_seatbid.json create mode 100644 adapters/nexx360/nexx360test/supplemental/ext.json create mode 100644 adapters/nexx360/nexx360test/supplemental/wrong-payload.json create mode 100644 adapters/nexx360/params_test.go create mode 100644 openrtb_ext/imp_nexx360.go create mode 100644 static/bidder-info/1accord.yaml create mode 100644 static/bidder-info/easybid.yaml create mode 100644 static/bidder-info/nexx360.yaml create mode 100644 static/bidder-params/nexx360.json diff --git a/adapters/nexx360/nexx360.go b/adapters/nexx360/nexx360.go new file mode 100644 index 00000000000..8efcff0a816 --- /dev/null +++ b/adapters/nexx360/nexx360.go @@ -0,0 +1,255 @@ +package nexx360 + +import ( + "encoding/json" + "fmt" + "net/http" + + "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/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" +) + +type Nexx360Adapter struct { + endpoint string +} + +type MakeImpOutput struct { + Imp []openrtb2.Imp + TagId string + Placement string +} + +type Ext struct { + Nexx360 ImpNexx360Ext `json:"nexx360"` +} + +type ImpNexx360Ext struct { + TagId string `json:"tagId,omitempty"` + Placement string `json:"placement,omitempty"` +} + +type Nexx360Caller struct { + Name string `json:"name,omitempty"` + Version string `json:"version,omitempty"` +} + +type ReqExt struct { + Nexx360 *ReqNexx360Ext `json:"nexx360,omitempty"` +} + +type ReqNexx360Ext struct { + Caller []Nexx360Caller `json:"caller,omitempty"` +} + +type Nexx360ResBidExt struct { + BidType string `json:"bidType,omitempty"` +} + +// CALLER Info used to track Prebid Server +// as one of the hops in the request to exchange +var CALLER = Nexx360Caller{"Prebid-Server", "n/a"} + +func makeImps(impList []openrtb2.Imp) (MakeImpOutput, error) { + var output MakeImpOutput + var imps []openrtb2.Imp + var tagId string + var placement string + for idx, imp := range impList { + if imp.Banner == nil && imp.Video == nil && imp.Audio == nil && imp.Native == nil { + return MakeImpOutput{}, &errortypes.BadInput{ + Message: fmt.Sprintf("Imp ID %s must have at least one of [Banner, Video, Audio, Native] defined", imp.ID), + } + } + var bidderExt adapters.ExtImpBidder + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { + return MakeImpOutput{}, &errortypes.BadInput{ + Message: err.Error(), + } + } + + var nexx360Ext openrtb_ext.ExtImpNexx360 + if err := jsonutil.Unmarshal(bidderExt.Bidder, &nexx360Ext); err != nil { + return MakeImpOutput{}, &errortypes.BadInput{ + Message: err.Error(), + } + } + + var impExt Ext + impExt.Nexx360.TagId = nexx360Ext.TagId + impExt.Nexx360.Placement = nexx360Ext.Placement + + + impExtJSON, err := json.Marshal(impExt) + if err != nil { + return MakeImpOutput{}, &errortypes.BadInput{ + Message: err.Error(), + } + } + + imp.Ext = impExtJSON + imps = append(imps, imp) + if idx == 0 { + tagId = nexx360Ext.TagId + placement = nexx360Ext.Placement + } + + } + output.Imp = imps + output.TagId = tagId + output.Placement = placement + return output, nil +} + + +func (a *Nexx360Adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + var makeImp, err = makeImps(request.Imp); + if err != nil { + return nil, []error{err} + } + + request.Imp = makeImp.Imp + + uri := a.endpoint + if(makeImp.Placement != "") { + uri = uri + "?placement=" + makeImp.Placement + } + if(makeImp.TagId != "") { + uri = uri + "?tag_id=" + makeImp.TagId + } + + + reqExt, err := makeReqExt(request) + if err != nil { + return nil, []error{err} + } + request.Ext = reqExt + + + // Last Step + reqJSON, err := json.Marshal(request) + if err != nil { + return nil, []error{err} + } + fmt.Printf("Nexx360: Request JSON: %s\n", string(reqJSON)) + + headers := http.Header{} + headers.Add("Content-Type", "application/json") + + adapter := &adapters.RequestData{ + Method: "POST", + Uri: uri, + Body: reqJSON, + Headers: headers, + ImpIDs: openrtb_ext.GetImpIDs(request.Imp), + }; + + return []*adapters.RequestData{adapter}, nil +} + +func makeReqExt(request *openrtb2.BidRequest) ([]byte, error) { + var reqExt ReqExt + + if len(request.Ext) > 0 { + if err := jsonutil.Unmarshal(request.Ext, &reqExt); err != nil { + return nil, err + } + } + + if reqExt.Nexx360 == nil { + reqExt.Nexx360 = &ReqNexx360Ext{} + } + + if reqExt.Nexx360.Caller == nil { + reqExt.Nexx360.Caller = make([]Nexx360Caller, 0) + } + + reqExt.Nexx360.Caller = append(reqExt.Nexx360.Caller, CALLER) + + return json.Marshal(reqExt) +} + +// MakeBids make the bids for the bid response. +func (a *Nexx360Adapter) MakeBids(request *openrtb2.BidRequest, externalRequest *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if responseData.StatusCode == http.StatusNoContent { + return nil, nil + } + + if responseData.StatusCode == http.StatusBadRequest { + return nil, []error{&errortypes.BadInput{ + Message: fmt.Sprintf("Unexpected http status code: %d", responseData.StatusCode), + }} + } + + if responseData.StatusCode != http.StatusOK { + fmt.Printf("Nexx360: Bad server response: %d\n", responseData.StatusCode) + return nil, []error{&errortypes.BadServerResponse{ + Message: fmt.Sprintf("Unexpected http status code: %d", responseData.StatusCode), + }} + } + + var response openrtb2.BidResponse + + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { + return nil, []error{err} + } + + var Bids []*adapters.TypedBid + var errors []error + for _, seatBid := range response.SeatBid { + for i, bid := range seatBid.Bid { + + bidType, err := getBidType(bid) + if err != nil { + errors = append(errors, err) + continue + } + Bids = append(Bids, &adapters.TypedBid{ + Bid: &seatBid.Bid[i], + BidType: bidType, + }) + } + } + if len(Bids) == 0 { + return nil, nil + } + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(Bids)) + bidResponse.Bids = Bids + bidResponse.Currency = response.Cur + + return bidResponse, errors +} + +func getBidType(bid openrtb2.Bid) (openrtb_ext.BidType, error) { + var bidExt Nexx360ResBidExt + err := jsonutil.Unmarshal(bid.Ext, &bidExt) + if(err == nil) { + if bidExt.BidType == "video" { + return openrtb_ext.BidTypeVideo, nil + } + if bidExt.BidType == "audio" { + return openrtb_ext.BidTypeAudio, nil + } + if (bidExt.BidType == "native") { + return openrtb_ext.BidTypeNative, nil + } + if (bidExt.BidType == "banner") { + return openrtb_ext.BidTypeBanner, nil + } + } + return "", &errortypes.BadServerResponse{ + Message: fmt.Sprintf("unable to fetch mediaType in multi-format: %s", bid.ImpID), + } +} + + +// Builder builds a new instance of the nexx360 adapter for the given bidder with the given config. +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + bidder := &Nexx360Adapter{ + endpoint: config.Endpoint, + } + return bidder, nil +} diff --git a/adapters/nexx360/nexx360_test.go b/adapters/nexx360/nexx360_test.go new file mode 100644 index 00000000000..1b8bae835c8 --- /dev/null +++ b/adapters/nexx360/nexx360_test.go @@ -0,0 +1,20 @@ +package nexx360 + +import ( + "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.BidderNexx360, config.Adapter{ + Endpoint: "http://fast.nexx360.io/prebid-server"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "Nexx360test", bidder) +} diff --git a/adapters/nexx360/nexx360test/exemplary/simple-banner-cookie-uid.json b/adapters/nexx360/nexx360test/exemplary/simple-banner-cookie-uid.json new file mode 100755 index 00000000000..28a575d7a8f --- /dev/null +++ b/adapters/nexx360/nexx360test/exemplary/simple-banner-cookie-uid.json @@ -0,0 +1,146 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "criteo.com" + }, + "device": { + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "user": { + "buyeruid": "nexx360-use-id" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "tagId": "testnexx" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://fast.nexx360.io/prebid-server?tag_id=testnexx", + "headers": { + "Content-Type": [ + "application/json" + ] + }, + "body": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "criteo.com" + }, + "device": { + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "user": { + "buyeruid": "nexx360-use-id" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "nexx360": { + "tagId": "testnexx" + } + } + } + ], + "ext": { + "nexx360": { + "caller": [ + { + "name": "Prebid-Server", + "version": "n/a" + } + ] + } + } + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "currency": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "test-ad", + "w": 300, + "h": 250, + "ext": { + "mediaType": "banner", + "bidType": "banner", + "tagId": "testnexx", + "ssp": "test" + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "test-ad", + "w": 300, + "h": 250, + "ext": { + "mediaType": "banner", + "bidType": "banner", + "tagId": "testnexx", + "ssp": "test" + } + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/nexx360/nexx360test/exemplary/simple-banner-inapp.json b/adapters/nexx360/nexx360test/exemplary/simple-banner-inapp.json new file mode 100755 index 00000000000..0b65b325855 --- /dev/null +++ b/adapters/nexx360/nexx360test/exemplary/simple-banner-inapp.json @@ -0,0 +1,139 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "bundle": "test.app.bundle" + }, + "device": { + "ifa": "test-ifa-123456", + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "tagId": "testnexx" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://fast.nexx360.io/prebid-server?tag_id=testnexx", + "headers": { + "Content-Type": [ + "application/json" + ] + }, + "body": { + "id": "test-request-id", + "app": { + "bundle": "test.app.bundle" + }, + "device": { + "ifa": "test-ifa-123456", + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "nexx360": { + "tagId": "testnexx" + } + } + } + ], + "ext": { + "nexx360": { + "caller": [ + { + "name": "Prebid-Server", + "version": "n/a" + } + ] + } + } + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "currency": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "

test ad

", + "w": 300, + "h": 250, + "ext": { + "mediaType": "banner", + "bidType": "banner", + "tagId": "testnexx", + "ssp": "test" + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "

test ad

", + "w": 300, + "h": 250, + "ext": { + "mediaType": "banner", + "bidType": "banner", + "tagId": "testnexx", + "ssp": "test" + } + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/nexx360/nexx360test/exemplary/simple-banner-multiple-bids.json b/adapters/nexx360/nexx360test/exemplary/simple-banner-multiple-bids.json new file mode 100644 index 00000000000..d6354acde5b --- /dev/null +++ b/adapters/nexx360/nexx360test/exemplary/simple-banner-multiple-bids.json @@ -0,0 +1,237 @@ +{ + "mockBidRequest": { + "id": "test-request-id-multiple-bids", + "site": { + "id": "site-id", + "page": "criteo.com" + }, + "device": { + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "user": { + "ext": { + "eids": [ + { + "source": "criteo.com", + "uids": [ + { + "id": "criteo-eid" + } + ] + } + ] + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "tagId": "testnex1" + } + } + }, + { + "id": "test-imp-id2", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "tagId": "testnex2" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://fast.nexx360.io/prebid-server?tag_id=testnex1", + "headers": { + "Content-Type": [ + "application/json" + ] + }, + "body": { + "id": "test-request-id-multiple-bids", + "site": { + "id": "site-id", + "page": "criteo.com" + }, + "device": { + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "user": { + "ext": { + "eids": [ + { + "source": "criteo.com", + "uids": [ + { + "id": "criteo-eid" + } + ] + } + ] + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "nexx360": { + "tagId": "testnex1" + } + } + }, + { + "id": "test-imp-id2", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "nexx360": { + "tagId": "testnex2" + } + } + } + ], + "ext": { + "nexx360": { + "caller": [ + { + "name": "Prebid-Server", + "version": "n/a" + } + ] + } + } + }, + "impIDs": [ + "test-imp-id", + "test-imp-id2" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "currency": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "
Test Ad
", + "w": 300, + "h": 250, + "ext": { + "mediaType": "banner", + "bidType": "banner", + "tagId": "testnex1", + "ssp": "test" + } + } + ] + }, + { + "bid": [ + { + "id": "test-slot-id2", + "impid": "test-imp-id2", + "price": 0.5, + "crid": "creative-123", + "adm": "
Test Ad
", + "w": 300, + "h": 250, + "ext": { + "mediaType": "banner", + "bidType": "banner", + "tagId": "testnex2", + "ssp": "test" + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "
Test Ad
", + "w": 300, + "h": 250, + "ext": { + "mediaType": "banner", + "bidType": "banner", + "tagId": "testnex1", + "ssp": "test" + } + }, + "type": "banner" + }, + { + "bid": { + "id": "test-slot-id2", + "impid": "test-imp-id2", + "price": 0.5, + "crid": "creative-123", + "adm": "
Test Ad
", + "w": 300, + "h": 250, + "ext": { + "mediaType": "banner", + "bidType": "banner", + "tagId": "testnex2", + "ssp": "test" + } + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/nexx360/nexx360test/exemplary/simple-banner-placement.json b/adapters/nexx360/nexx360test/exemplary/simple-banner-placement.json new file mode 100644 index 00000000000..01d93798c60 --- /dev/null +++ b/adapters/nexx360/nexx360test/exemplary/simple-banner-placement.json @@ -0,0 +1,110 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "w": 728, + "h": 90 + }, + "ext": { + "bidder": { + "placement": "test" + + } + } + } + ], + "site": {} + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://fast.nexx360.io/prebid-server?placement=test", + "body": { + "ext": { + "nexx360": { + "caller": [ + { + "name": "Prebid-Server", + "version": "n/a" + } + ] + } + }, + "id": "test-request-id", + "imp": [ + { + "id":"test-imp-id", + "banner": { + "w": 728, + "h": 90 + }, + "ext": { + "nexx360": { + "placement": "test" + } + } + } + ], + "site": {} + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "testalias", + "bid": [{ + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-banner", + "crid": "crid_10", + "h": 90, + "w": 728, + "ext": { + "mediaType": "banner", + "bidType": "banner", + "tagId": "testnexx", + "ssp": "test" + } + }] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-banner", + "crid": "crid_10", + "w": 728, + "h": 90, + "ext": { + "mediaType": "banner", + "bidType": "banner", + "tagId": "testnexx", + "ssp": "test" + } + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/nexx360/nexx360test/exemplary/simple-banner.json b/adapters/nexx360/nexx360test/exemplary/simple-banner.json new file mode 100644 index 00000000000..53040b36ce8 --- /dev/null +++ b/adapters/nexx360/nexx360test/exemplary/simple-banner.json @@ -0,0 +1,110 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "w": 728, + "h": 90 + }, + "ext": { + "bidder": { + "tagId": "testnexx" + + } + } + } + ], + "site": {} + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://fast.nexx360.io/prebid-server?tag_id=testnexx", + "body": { + "ext": { + "nexx360": { + "caller": [ + { + "name": "Prebid-Server", + "version": "n/a" + } + ] + } + }, + "id": "test-request-id", + "imp": [ + { + "id":"test-imp-id", + "banner": { + "w": 728, + "h": 90 + }, + "ext": { + "nexx360": { + "tagId": "testnexx" + } + } + } + ], + "site": {} + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "testalias", + "bid": [{ + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-banner", + "crid": "crid_10", + "h": 90, + "w": 728, + "ext": { + "mediaType": "banner", + "bidType": "banner", + "tagId": "testnexx", + "ssp": "test" + } + }] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-banner", + "crid": "crid_10", + "w": 728, + "h": 90, + "ext": { + "mediaType": "banner", + "bidType": "banner", + "tagId": "testnexx", + "ssp": "test" + } + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/nexx360/nexx360test/exemplary/simple-multi-type-banner.json b/adapters/nexx360/nexx360test/exemplary/simple-multi-type-banner.json new file mode 100644 index 00000000000..ecc72dee184 --- /dev/null +++ b/adapters/nexx360/nexx360test/exemplary/simple-multi-type-banner.json @@ -0,0 +1,178 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "criteo.com" + }, + "device": { + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "user": { + "ext": { + "eids": [ + { + "source": "criteo.com", + "uids": [ + { + "id": "criteo-eid" + } + ] + } + ] + } + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 300, + "h": 250 + }, + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "tagId": "testnexx" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://fast.nexx360.io/prebid-server?tag_id=testnexx", + "headers": { + "Content-Type": [ + "application/json" + ] + }, + "body": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "criteo.com" + }, + "device": { + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "user": { + "ext": { + "eids": [ + { + "source": "criteo.com", + "uids": [ + { + "id": "criteo-eid" + } + ] + } + ] + } + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 300, + "h": 250 + }, + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "nexx360": { + "tagId": "testnexx" + } + } + } + ], + "ext": { + "nexx360": { + "caller": [ + { + "name": "Prebid-Server", + "version": "n/a" + } + ] + } + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "currency": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "

test ad

", + "h": 250, + "w": 300, + "ext": { + "mediaType": "banner", + "bidType": "banner", + "tagId": "testnexx", + "ssp": "test" + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "

test ad

", + "h": 250, + "w": 300, + "ext": { + "mediaType": "banner", + "bidType": "banner", + "tagId": "testnexx", + "ssp": "test" + } + }, + "type": "banner" + } + ] + } + ] +} + diff --git a/adapters/nexx360/nexx360test/exemplary/simple-multi-type-video.json b/adapters/nexx360/nexx360test/exemplary/simple-multi-type-video.json new file mode 100644 index 00000000000..754b3538dc7 --- /dev/null +++ b/adapters/nexx360/nexx360test/exemplary/simple-multi-type-video.json @@ -0,0 +1,178 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "criteo.com" + }, + "device": { + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "user": { + "ext": { + "eids": [ + { + "source": "criteo.com", + "uids": [ + { + "id": "criteo-eid" + } + ] + } + ] + } + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 300, + "h": 250 + }, + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "tagId": "testnexx" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://fast.nexx360.io/prebid-server?tag_id=testnexx", + "headers": { + "Content-Type": [ + "application/json" + ] + }, + "body": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "criteo.com" + }, + "device": { + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "user": { + "ext": { + "eids": [ + { + "source": "criteo.com", + "uids": [ + { + "id": "criteo-eid" + } + ] + } + ] + } + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 300, + "h": 250 + }, + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "nexx360": { + "tagId": "testnexx" + } + } + } + ], + "ext": { + "nexx360": { + "caller": [ + { + "name": "Prebid-Server", + "version": "n/a" + } + ] + } + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "currency": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "some-test-ad-vast", + "h": 250, + "w": 300, + "ext": { + "mediaType": "video", + "bidType": "video", + "tagId": "testnexx", + "ssp": "test" + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "some-test-ad-vast", + "h": 250, + "w": 300, + "ext": { + "mediaType": "video", + "bidType": "video", + "tagId": "testnexx", + "ssp": "test" + } + }, + "type": "video" + } + ] + } + ] +} + diff --git a/adapters/nexx360/nexx360test/exemplary/simple-native.json b/adapters/nexx360/nexx360test/exemplary/simple-native.json new file mode 100644 index 00000000000..1f0b9edcb2d --- /dev/null +++ b/adapters/nexx360/nexx360test/exemplary/simple-native.json @@ -0,0 +1,120 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "https://good.site/url" + }, + "imp": [ + { + "id": "test-imp-id", + "native": { + "ver": "1.2", + "request": "{\"ver\":\"1.2\",\"layout\":1,\"adunit\":1,\"plcmttype\":1,\"plcmtcnt\":1,\"seq\":0,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":60,\"hmin\":60,\"mimes\":[\"image/jpeg\",\"image/jpg\",\"image/png\"]}},{\"id\":3,\"required\":0,\"data\":{\"type\":2,\"len\":75}},{\"id\":4,\"required\":0,\"data\":{\"type\":6,\"len\":1000}},{\"id\":5,\"required\":0,\"data\":{\"type\":7,\"len\":1000}},{\"id\":6,\"required\":0,\"data\":{\"type\":11,\"len\":1000}}]}" + }, + "ext": { + "bidder": { + "tagId": "testnexx" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://fast.nexx360.io/prebid-server?tag_id=testnexx", + "body": { + "id": "test-request-id", + "site": { + "page": "https://good.site/url" + }, + "imp": [ + { + "id": "test-imp-id", + "native": { + "ver": "1.2", + "request": "{\"ver\":\"1.2\",\"layout\":1,\"adunit\":1,\"plcmttype\":1,\"plcmtcnt\":1,\"seq\":0,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":60,\"hmin\":60,\"mimes\":[\"image/jpeg\",\"image/jpg\",\"image/png\"]}},{\"id\":3,\"required\":0,\"data\":{\"type\":2,\"len\":75}},{\"id\":4,\"required\":0,\"data\":{\"type\":6,\"len\":1000}},{\"id\":5,\"required\":0,\"data\":{\"type\":7,\"len\":1000}},{\"id\":6,\"required\":0,\"data\":{\"type\":11,\"len\":1000}}]}" + }, + "ext": { + "nexx360": { + "tagId": "testnexx" + } + } + } + ], + "ext": { + "nexx360": { + "caller": [ + { + "name": "Prebid-Server", + "version": "n/a" + } + ] + } + } + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "grid", + "bid": [ + { + "id": "randomid", + "impid": "test-imp-id", + "price": 0.5, + "adid": "12345678", + "adm": "{\"ver\":\"1.0\",\"layout\":1,\"adunit\":1,\"plcmttype\":1,\"plcmtcnt\":1,\"seq\":0,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":60,\"hmin\":60,\"mimes\":[\"image/jpeg\",\"image/jpg\",\"image/png\"]}},{\"id\":3,\"required\":0,\"data\":{\"type\":2,\"len\":75}},{\"id\":4,\"required\":0,\"data\":{\"type\":6,\"len\":1000}},{\"id\":5,\"required\":0,\"data\":{\"type\":7,\"len\":1000}},{\"id\":6,\"required\":0,\"data\":{\"type\":11,\"len\":1000}}]}", + "ext": { + "mediaType": "native", + "bidType": "native", + "tagId": "testnexx", + "ssp": "test" + }, + "cid": "987", + "crid": "12345678", + "h": 250, + "w": 300 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "randomid", + "impid": "test-imp-id", + "price": 0.5, + "adm": "{\"ver\":\"1.0\",\"layout\":1,\"adunit\":1,\"plcmttype\":1,\"plcmtcnt\":1,\"seq\":0,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":60,\"hmin\":60,\"mimes\":[\"image/jpeg\",\"image/jpg\",\"image/png\"]}},{\"id\":3,\"required\":0,\"data\":{\"type\":2,\"len\":75}},{\"id\":4,\"required\":0,\"data\":{\"type\":6,\"len\":1000}},{\"id\":5,\"required\":0,\"data\":{\"type\":7,\"len\":1000}},{\"id\":6,\"required\":0,\"data\":{\"type\":11,\"len\":1000}}]}", + "adid": "12345678", + "cid": "987", + "crid": "12345678", + "w": 300, + "h": 250, + "ext": { + "mediaType": "native", + "bidType": "native", + "tagId": "testnexx", + "ssp": "test" + } + }, + "type": "native" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/nexx360/nexx360test/exemplary/simple-video.json b/adapters/nexx360/nexx360test/exemplary/simple-video.json new file mode 100644 index 00000000000..68ce33402d2 --- /dev/null +++ b/adapters/nexx360/nexx360test/exemplary/simple-video.json @@ -0,0 +1,162 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "criteo.com" + }, + "device": { + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "user": { + "ext": { + "eids": [ + { + "source": "criteo.com", + "uids": [ + { + "id": "criteo-eid" + } + ] + } + ] + } + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "tagId": "testnexx" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://fast.nexx360.io/prebid-server?tag_id=testnexx", + "headers": { + "Content-Type": [ + "application/json" + ] + }, + "body": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "criteo.com" + }, + "device": { + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "user": { + "ext": { + "eids": [ + { + "source": "criteo.com", + "uids": [ + { + "id": "criteo-eid" + } + ] + } + ] + } + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 300, + "h": 250 + }, + "ext": { + "nexx360": { + "tagId": "testnexx" + } + } + } + ], + "ext": { + "nexx360": { + "caller": [ + { + "name": "Prebid-Server", + "version": "n/a" + } + ] + } + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "currency": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "some-test-ad-vast", + "h": 250, + "w": 300, + "ext": { + "mediaType": "video", + "bidType": "video", + "tagId": "testnexx", + "ssp": "test" + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "some-test-ad-vast", + "h": 250, + "w": 300, + "ext": { + "mediaType": "video", + "bidType": "video", + "tagId": "testnexx", + "ssp": "test" + } + }, + "type": "video" + } + ] + } + ] +} + diff --git a/adapters/nexx360/nexx360test/supplemental/204-response.json b/adapters/nexx360/nexx360test/supplemental/204-response.json new file mode 100644 index 00000000000..6a9cc7e5dac --- /dev/null +++ b/adapters/nexx360/nexx360test/supplemental/204-response.json @@ -0,0 +1,121 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "app": { + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ], + "bundle": "com.app.awesome", + "name": "Awesome App", + "domain": "awesomeapp.com", + "id": "123456789" + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "ext": { + "bidder": { + "tagId": "testnexx" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json" + ] + }, + "uri": "http://fast.nexx360.io/prebid-server?tag_id=testnexx", + "body": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "some-impression-id", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 120, + "maxduration": 150, + "w": 640, + "h": 480 + }, + "tagid": "ogTAGID", + "ext": { + "nexx360": { + "tagId": "testnexx" + } + } + } + ], + "app": { + "id": "123456789", + "name": "Awesome App", + "bundle": "com.app.awesome", + "domain": "awesomeapp.com", + "cat": [ + "IAB22-1" + ], + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000, + "ext": { + "nexx360": { + "caller": [ + { + "name": "Prebid-Server", + "version": "n/a" + } + ] + } + } + }, + "impIDs": [ + "some-impression-id" + ] + }, + "mockResponse": { + "status": 204 + } + } + ], + "expectedBidResponses": [] +} \ No newline at end of file diff --git a/adapters/nexx360/nexx360test/supplemental/400-response.json b/adapters/nexx360/nexx360test/supplemental/400-response.json new file mode 100644 index 00000000000..e430851e884 --- /dev/null +++ b/adapters/nexx360/nexx360test/supplemental/400-response.json @@ -0,0 +1,127 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "app": { + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ], + "bundle": "com.app.awesome", + "name": "Awesome App", + "domain": "awesomeapp.com", + "id": "123456789" + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "ext": { + "bidder": { + "tagId": "testnexx" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json" + ] + }, + "uri": "http://fast.nexx360.io/prebid-server?tag_id=testnexx", + "body": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "some-impression-id", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 120, + "maxduration": 150, + "w": 640, + "h": 480 + }, + "tagid": "ogTAGID", + "ext": { + "nexx360": { + "tagId": "testnexx" + } + } + } + ], + "app": { + "id": "123456789", + "name": "Awesome App", + "bundle": "com.app.awesome", + "domain": "awesomeapp.com", + "cat": [ + "IAB22-1" + ], + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000, + "ext": { + "nexx360": { + "caller": [ + { + "name": "Prebid-Server", + "version": "n/a" + } + ] + } + } + }, + "impIDs": [ + "some-impression-id" + ] + }, + "mockResponse": { + "status": 400 + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected http status code: 400", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/nexx360/nexx360test/supplemental/500-response.json b/adapters/nexx360/nexx360test/supplemental/500-response.json new file mode 100644 index 00000000000..4a06526ee16 --- /dev/null +++ b/adapters/nexx360/nexx360test/supplemental/500-response.json @@ -0,0 +1,127 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "app": { + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ], + "bundle": "com.app.awesome", + "name": "Awesome App", + "domain": "awesomeapp.com", + "id": "123456789" + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "ext": { + "bidder": { + "tagId": "testnexx" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json" + ] + }, + "uri": "http://fast.nexx360.io/prebid-server?tag_id=testnexx", + "body": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "some-impression-id", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 120, + "maxduration": 150, + "w": 640, + "h": 480 + }, + "tagid": "ogTAGID", + "ext": { + "nexx360": { + "tagId": "testnexx" + } + } + } + ], + "app": { + "id": "123456789", + "name": "Awesome App", + "bundle": "com.app.awesome", + "domain": "awesomeapp.com", + "cat": [ + "IAB22-1" + ], + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000, + "ext": { + "nexx360": { + "caller": [ + { + "name": "Prebid-Server", + "version": "n/a" + } + ] + } + } + }, + "impIDs": [ + "some-impression-id" + ] + }, + "mockResponse": { + "status": 500 + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected http status code: 500", + "comparison": "literal" + } + ] +} diff --git a/adapters/nexx360/nexx360test/supplemental/empty_seatbid.json b/adapters/nexx360/nexx360test/supplemental/empty_seatbid.json new file mode 100644 index 00000000000..1abf64d3e58 --- /dev/null +++ b/adapters/nexx360/nexx360test/supplemental/empty_seatbid.json @@ -0,0 +1,125 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "app": { + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ], + "bundle": "com.app.awesome", + "name": "Awesome App", + "domain": "awesomeapp.com", + "id": "123456789" + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "ext": { + "bidder": { + "tagId": "testnexx" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json" + ] + }, + "uri": "http://fast.nexx360.io/prebid-server?tag_id=testnexx", + "body": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "some-impression-id", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 120, + "maxduration": 150, + "w": 640, + "h": 480 + }, + "tagid": "ogTAGID", + "ext": { + "nexx360": { + "tagId": "testnexx" + } + } + } + ], + "app": { + "id": "123456789", + "name": "Awesome App", + "bundle": "com.app.awesome", + "domain": "awesomeapp.com", + "cat": [ + "IAB22-1" + ], + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000, + "ext": { + "nexx360": { + "caller": [ + { + "name": "Prebid-Server", + "version": "n/a" + } + ] + } + } + }, + "impIDs": [ + "some-impression-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [] + } + } + } + ], + "expectedBidResponses": [] +} \ No newline at end of file diff --git a/adapters/nexx360/nexx360test/supplemental/ext.json b/adapters/nexx360/nexx360test/supplemental/ext.json new file mode 100644 index 00000000000..68584236617 --- /dev/null +++ b/adapters/nexx360/nexx360test/supplemental/ext.json @@ -0,0 +1,33 @@ +{ + "mockBidRequest": { + "id": "testid", + "imp": [ + { + "id": "testimpid", + "banner": { + "format": [ + { + "w": 320, + "h": 250 + }, + { + "w": 320, + "h": 300 + } + ], + "w": 320, + "h": 250 + }, + "ext": { + "placement_id": "1265" + } + } + ] + }, + "expectedMakeRequestsErrors": [ + { + "value": "expect { or n, but found", + "comparison": "startswith" + } + ] +} diff --git a/adapters/nexx360/nexx360test/supplemental/wrong-payload.json b/adapters/nexx360/nexx360test/supplemental/wrong-payload.json new file mode 100644 index 00000000000..bbcf590683c --- /dev/null +++ b/adapters/nexx360/nexx360test/supplemental/wrong-payload.json @@ -0,0 +1,82 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "w": 728, + "h": 90 + }, + "ext": { + "bidder": { + "tagId": "testnexx" + + } + } + } + ], + "site": {} + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://fast.nexx360.io/prebid-server?tag_id=testnexx", + "body": { + "ext": { + "nexx360": { + "caller": [ + { + "name": "Prebid-Server", + "version": "n/a" + } + ] + } + }, + "id": "test-request-id", + "imp": [ + { + "id":"test-imp-id", + "banner": { + "w": 728, + "h": 90 + }, + "ext": { + "nexx360": { + "tagId": "testnexx" + } + } + } + ], + "site": {} + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "testalias", + "bid": [{ + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-banner", + "crid": "crid_10", + "h": 90, + "w": 728, + "ext": { + } + }] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/nexx360/params_test.go b/adapters/nexx360/params_test.go new file mode 100644 index 00000000000..812bcf09df5 --- /dev/null +++ b/adapters/nexx360/params_test.go @@ -0,0 +1,50 @@ +package nexx360 + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v3/openrtb_ext" +) + +// This file actually intends to test static/bidder-params/nexx360.json +// +// These also validate the format of the external API: request.imp[i].ext.prebid.bidder.nexx360 + +// TestValidParams makes sure that the Nexx360 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.BidderNexx360, json.RawMessage(validParam)); err != nil { + t.Errorf("Schema rejected Nexx360 params: %s", validParam) + } + } +} + +// TestInvalidParams makes sure that the Nexx360 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.BidderNexx360, json.RawMessage(invalidParam)); err == nil { + t.Errorf("Schema allowed unexpected params: %s", invalidParam) + } + } +} + +var validParams = []string{ + `{"tagId": "testnexx"}`, + `{"placement": "testnexx"}`, + `{"tagId": "testnexx", "placement": "testnexx"}`, +} + +var invalidParams = []string{ + `{"productId": "inview"}`, +} diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 7647de71786..7b36388ad54 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -156,6 +156,7 @@ import ( "github.com/prebid/prebid-server/v3/adapters/motorik" "github.com/prebid/prebid-server/v3/adapters/nativo" "github.com/prebid/prebid-server/v3/adapters/nextmillennium" + "github.com/prebid/prebid-server/v3/adapters/nexx360" "github.com/prebid/prebid-server/v3/adapters/nobid" "github.com/prebid/prebid-server/v3/adapters/ogury" "github.com/prebid/prebid-server/v3/adapters/oms" @@ -406,6 +407,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderMotorik: motorik.Builder, openrtb_ext.BidderNativo: nativo.Builder, openrtb_ext.BidderNextMillennium: nextmillennium.Builder, + openrtb_ext.BidderNexx360: nexx360.Builder, openrtb_ext.BidderNoBid: nobid.Builder, openrtb_ext.BidderOgury: ogury.Builder, openrtb_ext.BidderOms: oms.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 10755dfd7fd..a3820f099a7 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -174,6 +174,7 @@ var coreBidderNames []BidderName = []BidderName{ BidderMotorik, BidderNativo, BidderNextMillennium, + BidderNexx360, BidderNoBid, BidderOgury, BidderOms, @@ -528,6 +529,7 @@ const ( BidderMotorik BidderName = "motorik" BidderNativo BidderName = "nativo" BidderNextMillennium BidderName = "nextmillennium" + BidderNexx360 BidderName = "nexx360" BidderNoBid BidderName = "nobid" BidderOgury BidderName = "ogury" BidderOms BidderName = "oms" diff --git a/openrtb_ext/imp_nexx360.go b/openrtb_ext/imp_nexx360.go new file mode 100644 index 00000000000..318e6ca6d1a --- /dev/null +++ b/openrtb_ext/imp_nexx360.go @@ -0,0 +1,7 @@ +package openrtb_ext + +// ExtNexx360 defines the contract for bidrequest.imp[i].ext.prebid.bidder.nexx360 +type ExtImpNexx360 struct { + TagId string `json:"tagId,omitempty"` + Placement string `json:"placement,omitempty"` // Placement ID +} diff --git a/static/bidder-info/1accord.yaml b/static/bidder-info/1accord.yaml new file mode 100644 index 00000000000..4a6b8199be9 --- /dev/null +++ b/static/bidder-info/1accord.yaml @@ -0,0 +1 @@ +aliasOf: "nexx360" diff --git a/static/bidder-info/easybid.yaml b/static/bidder-info/easybid.yaml new file mode 100644 index 00000000000..4a6b8199be9 --- /dev/null +++ b/static/bidder-info/easybid.yaml @@ -0,0 +1 @@ +aliasOf: "nexx360" diff --git a/static/bidder-info/nexx360.yaml b/static/bidder-info/nexx360.yaml new file mode 100644 index 00000000000..9e89d13eb30 --- /dev/null +++ b/static/bidder-info/nexx360.yaml @@ -0,0 +1,17 @@ +endpoint: "http://fast.nexx360.io/prebid-server" +maintainer: + email: "tech@nexx360.io" +endpointCompression: gzip +geoscope: + - global +capabilities: + app: + mediaTypes: + - banner + - video + - native + site: + mediaTypes: + - banner + - video + - native diff --git a/static/bidder-params/nexx360.json b/static/bidder-params/nexx360.json new file mode 100644 index 00000000000..f504f6080a8 --- /dev/null +++ b/static/bidder-params/nexx360.json @@ -0,0 +1,30 @@ + +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Nexx360 Adapter Params", + "description": "A schema which validates params accepted by the Nexx360 adapter", + + "type": "object", + "properties": { + "tagId": { + "type": "string", + "description": "TagId" + }, + "placement": { + "type": "string", + "description": "Placement" + } + }, + "anyOf": [ + { + "required": [ + "tagId" + ] + }, + { + "required": [ + "placement" + ] + } + ] + } \ No newline at end of file From b620c8201b0b722eee8e1abc5750b9810b103f38 Mon Sep 17 00:00:00 2001 From: Gabriel Chicoye Date: Wed, 2 Apr 2025 14:27:36 +0200 Subject: [PATCH 02/16] adapter name fix --- adapters/nexx360/nexx360.go | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/adapters/nexx360/nexx360.go b/adapters/nexx360/nexx360.go index 8efcff0a816..9342041f312 100644 --- a/adapters/nexx360/nexx360.go +++ b/adapters/nexx360/nexx360.go @@ -13,7 +13,7 @@ import ( "github.com/prebid/prebid-server/v3/util/jsonutil" ) -type Nexx360Adapter struct { +type adapter struct { endpoint string } @@ -49,6 +49,7 @@ type Nexx360ResBidExt struct { BidType string `json:"bidType,omitempty"` } + // CALLER Info used to track Prebid Server // as one of the hops in the request to exchange var CALLER = Nexx360Caller{"Prebid-Server", "n/a"} @@ -105,7 +106,7 @@ func makeImps(impList []openrtb2.Imp) (MakeImpOutput, error) { } -func (a *Nexx360Adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { var makeImp, err = makeImps(request.Imp); if err != nil { return nil, []error{err} @@ -173,7 +174,7 @@ func makeReqExt(request *openrtb2.BidRequest) ([]byte, error) { } // MakeBids make the bids for the bid response. -func (a *Nexx360Adapter) MakeBids(request *openrtb2.BidRequest, externalRequest *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { +func (a *adapter) MakeBids(request *openrtb2.BidRequest, externalRequest *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { if responseData.StatusCode == http.StatusNoContent { return nil, nil } @@ -245,11 +246,6 @@ func getBidType(bid openrtb2.Bid) (openrtb_ext.BidType, error) { } } - -// Builder builds a new instance of the nexx360 adapter for the given bidder with the given config. -func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { - bidder := &Nexx360Adapter{ - endpoint: config.Endpoint, - } - return bidder, nil +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + return &adapter{endpoint: config.Endpoint}, nil } From a6a8b9dc2bd735fbe1f9b884010e637180c3d7b2 Mon Sep 17 00:00:00 2001 From: Gabriel Chicoye Date: Wed, 2 Apr 2025 14:29:44 +0200 Subject: [PATCH 03/16] test fix --- adapters/nexx360/nexx360_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adapters/nexx360/nexx360_test.go b/adapters/nexx360/nexx360_test.go index 1b8bae835c8..f7a8741f176 100644 --- a/adapters/nexx360/nexx360_test.go +++ b/adapters/nexx360/nexx360_test.go @@ -16,5 +16,5 @@ func TestJsonSamples(t *testing.T) { t.Fatalf("Builder returned unexpected error %v", buildErr) } - adapterstest.RunJSONBidderTest(t, "Nexx360test", bidder) + adapterstest.RunJSONBidderTest(t, "nexx360test", bidder) } From ddf884077c7158ce3d3fbc9fc1872c5693279fc7 Mon Sep 17 00:00:00 2001 From: Gabriel Chicoye Date: Mon, 7 Apr 2025 12:19:07 +0200 Subject: [PATCH 04/16] review fixes --- adapters/nexx360/nexx360.go | 32 ++--- .../simple-banner-placement-tagid.json | 112 ++++++++++++++++++ static/bidder-info/nexx360.yaml | 2 + 3 files changed, 130 insertions(+), 16 deletions(-) create mode 100644 adapters/nexx360/nexx360test/exemplary/simple-banner-placement-tagid.json diff --git a/adapters/nexx360/nexx360.go b/adapters/nexx360/nexx360.go index 9342041f312..8adec3e676f 100644 --- a/adapters/nexx360/nexx360.go +++ b/adapters/nexx360/nexx360.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "net/http" + "net/url" "github.com/prebid/openrtb/v20/openrtb2" "github.com/prebid/prebid-server/v3/adapters" @@ -57,14 +58,7 @@ var CALLER = Nexx360Caller{"Prebid-Server", "n/a"} func makeImps(impList []openrtb2.Imp) (MakeImpOutput, error) { var output MakeImpOutput var imps []openrtb2.Imp - var tagId string - var placement string for idx, imp := range impList { - if imp.Banner == nil && imp.Video == nil && imp.Audio == nil && imp.Native == nil { - return MakeImpOutput{}, &errortypes.BadInput{ - Message: fmt.Sprintf("Imp ID %s must have at least one of [Banner, Video, Audio, Native] defined", imp.ID), - } - } var bidderExt adapters.ExtImpBidder if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return MakeImpOutput{}, &errortypes.BadInput{ @@ -94,14 +88,12 @@ func makeImps(impList []openrtb2.Imp) (MakeImpOutput, error) { imp.Ext = impExtJSON imps = append(imps, imp) if idx == 0 { - tagId = nexx360Ext.TagId - placement = nexx360Ext.Placement + output.TagId = nexx360Ext.TagId + output.Placement = nexx360Ext.Placement } } output.Imp = imps - output.TagId = tagId - output.Placement = placement return output, nil } @@ -114,13 +106,21 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E request.Imp = makeImp.Imp - uri := a.endpoint - if(makeImp.Placement != "") { - uri = uri + "?placement=" + makeImp.Placement + urlBuilder, err := url.Parse(a.endpoint) + if err != nil { + return nil, []error{err} + } + + query := url.Values{} + if makeImp.Placement != "" { + query["placement"] = []string{makeImp.Placement} } - if(makeImp.TagId != "") { - uri = uri + "?tag_id=" + makeImp.TagId + if makeImp.TagId != "" { + query["tag_id"] = []string{makeImp.TagId} } + urlBuilder.RawQuery = query.Encode() + + uri := urlBuilder.String() reqExt, err := makeReqExt(request) diff --git a/adapters/nexx360/nexx360test/exemplary/simple-banner-placement-tagid.json b/adapters/nexx360/nexx360test/exemplary/simple-banner-placement-tagid.json new file mode 100644 index 00000000000..1866265c49f --- /dev/null +++ b/adapters/nexx360/nexx360test/exemplary/simple-banner-placement-tagid.json @@ -0,0 +1,112 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "w": 728, + "h": 90 + }, + "ext": { + "bidder": { + "tagId": "testnexx", + "placement": "test" + + } + } + } + ], + "site": {} + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://fast.nexx360.io/prebid-server?placement=test&tag_id=testnexx", + "body": { + "ext": { + "nexx360": { + "caller": [ + { + "name": "Prebid-Server", + "version": "n/a" + } + ] + } + }, + "id": "test-request-id", + "imp": [ + { + "id":"test-imp-id", + "banner": { + "w": 728, + "h": 90 + }, + "ext": { + "nexx360": { + "placement": "test", + "tagId": "testnexx" + } + } + } + ], + "site": {} + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "testalias", + "bid": [{ + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-banner", + "crid": "crid_10", + "h": 90, + "w": 728, + "ext": { + "mediaType": "banner", + "bidType": "banner", + "tagId": "testnexx", + "ssp": "test" + } + }] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-banner", + "crid": "crid_10", + "w": 728, + "h": 90, + "ext": { + "mediaType": "banner", + "bidType": "banner", + "tagId": "testnexx", + "ssp": "test" + } + }, + "type": "banner" + } + ] + } + ] +} diff --git a/static/bidder-info/nexx360.yaml b/static/bidder-info/nexx360.yaml index 9e89d13eb30..0a0b186ec91 100644 --- a/static/bidder-info/nexx360.yaml +++ b/static/bidder-info/nexx360.yaml @@ -10,8 +10,10 @@ capabilities: - banner - video - native + - audio site: mediaTypes: - banner - video - native + - audio From d383c49e2325dbdd97932968fcfb023288939f77 Mon Sep 17 00:00:00 2001 From: Gabriel Chicoye Date: Tue, 8 Apr 2025 09:59:31 +0200 Subject: [PATCH 05/16] gofmt fix --- adapters/nexx360/nexx360.go | 39 ++++++++++++++----------------- openrtb_ext/bidders.go | 2 +- openrtb_ext/imp_nexx360.go | 2 +- static/bidder-info/prismassp.yaml | 1 + 4 files changed, 20 insertions(+), 24 deletions(-) create mode 100644 static/bidder-info/prismassp.yaml diff --git a/adapters/nexx360/nexx360.go b/adapters/nexx360/nexx360.go index 8adec3e676f..1e541fa1a7a 100644 --- a/adapters/nexx360/nexx360.go +++ b/adapters/nexx360/nexx360.go @@ -19,8 +19,8 @@ type adapter struct { } type MakeImpOutput struct { - Imp []openrtb2.Imp - TagId string + Imp []openrtb2.Imp + TagId string Placement string } @@ -29,7 +29,7 @@ type Ext struct { } type ImpNexx360Ext struct { - TagId string `json:"tagId,omitempty"` + TagId string `json:"tagId,omitempty"` Placement string `json:"placement,omitempty"` } @@ -50,7 +50,6 @@ type Nexx360ResBidExt struct { BidType string `json:"bidType,omitempty"` } - // CALLER Info used to track Prebid Server // as one of the hops in the request to exchange var CALLER = Nexx360Caller{"Prebid-Server", "n/a"} @@ -77,7 +76,6 @@ func makeImps(impList []openrtb2.Imp) (MakeImpOutput, error) { impExt.Nexx360.TagId = nexx360Ext.TagId impExt.Nexx360.Placement = nexx360Ext.Placement - impExtJSON, err := json.Marshal(impExt) if err != nil { return MakeImpOutput{}, &errortypes.BadInput{ @@ -88,48 +86,45 @@ func makeImps(impList []openrtb2.Imp) (MakeImpOutput, error) { imp.Ext = impExtJSON imps = append(imps, imp) if idx == 0 { - output.TagId = nexx360Ext.TagId + output.TagId = nexx360Ext.TagId output.Placement = nexx360Ext.Placement } - + } output.Imp = imps return output, nil } - func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { - var makeImp, err = makeImps(request.Imp); + var makeImp, err = makeImps(request.Imp) if err != nil { return nil, []error{err} } request.Imp = makeImp.Imp - + urlBuilder, err := url.Parse(a.endpoint) if err != nil { return nil, []error{err} } - + query := url.Values{} if makeImp.Placement != "" { - query["placement"] = []string{makeImp.Placement} + query["placement"] = []string{makeImp.Placement} } if makeImp.TagId != "" { - query["tag_id"] = []string{makeImp.TagId} + query["tag_id"] = []string{makeImp.TagId} } urlBuilder.RawQuery = query.Encode() uri := urlBuilder.String() - reqExt, err := makeReqExt(request) if err != nil { return nil, []error{err} } request.Ext = reqExt - // Last Step reqJSON, err := json.Marshal(request) if err != nil { @@ -146,7 +141,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E Body: reqJSON, Headers: headers, ImpIDs: openrtb_ext.GetImpIDs(request.Imp), - }; + } return []*adapters.RequestData{adapter}, nil } @@ -202,7 +197,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, externalRequest *adapte var errors []error for _, seatBid := range response.SeatBid { for i, bid := range seatBid.Bid { - + bidType, err := getBidType(bid) if err != nil { errors = append(errors, err) @@ -220,24 +215,24 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, externalRequest *adapte bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(Bids)) bidResponse.Bids = Bids bidResponse.Currency = response.Cur - + return bidResponse, errors } func getBidType(bid openrtb2.Bid) (openrtb_ext.BidType, error) { var bidExt Nexx360ResBidExt err := jsonutil.Unmarshal(bid.Ext, &bidExt) - if(err == nil) { + if err == nil { if bidExt.BidType == "video" { return openrtb_ext.BidTypeVideo, nil } if bidExt.BidType == "audio" { return openrtb_ext.BidTypeAudio, nil } - if (bidExt.BidType == "native") { + if bidExt.BidType == "native" { return openrtb_ext.BidTypeNative, nil } - if (bidExt.BidType == "banner") { + if bidExt.BidType == "banner" { return openrtb_ext.BidTypeBanner, nil } } @@ -246,6 +241,6 @@ func getBidType(bid openrtb2.Bid) (openrtb_ext.BidType, error) { } } -func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { return &adapter{endpoint: config.Endpoint}, nil } diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index a3820f099a7..71f6790a395 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -529,7 +529,7 @@ const ( BidderMotorik BidderName = "motorik" BidderNativo BidderName = "nativo" BidderNextMillennium BidderName = "nextmillennium" - BidderNexx360 BidderName = "nexx360" + BidderNexx360 BidderName = "nexx360" BidderNoBid BidderName = "nobid" BidderOgury BidderName = "ogury" BidderOms BidderName = "oms" diff --git a/openrtb_ext/imp_nexx360.go b/openrtb_ext/imp_nexx360.go index 318e6ca6d1a..29297aece2c 100644 --- a/openrtb_ext/imp_nexx360.go +++ b/openrtb_ext/imp_nexx360.go @@ -2,6 +2,6 @@ package openrtb_ext // ExtNexx360 defines the contract for bidrequest.imp[i].ext.prebid.bidder.nexx360 type ExtImpNexx360 struct { - TagId string `json:"tagId,omitempty"` + TagId string `json:"tagId,omitempty"` Placement string `json:"placement,omitempty"` // Placement ID } diff --git a/static/bidder-info/prismassp.yaml b/static/bidder-info/prismassp.yaml new file mode 100644 index 00000000000..4a6b8199be9 --- /dev/null +++ b/static/bidder-info/prismassp.yaml @@ -0,0 +1 @@ +aliasOf: "nexx360" From 70c6882f3225aceb4730d09f0e0abadf368ecc7a Mon Sep 17 00:00:00 2001 From: Gabriel Chicoye Date: Tue, 15 Apr 2025 11:52:42 +0200 Subject: [PATCH 06/16] various fixes --- adapters/nexx360/nexx360.go | 75 ++++++++----------- .../nexx360test/exemplary/simple-banner.json | 6 +- 2 files changed, 37 insertions(+), 44 deletions(-) diff --git a/adapters/nexx360/nexx360.go b/adapters/nexx360/nexx360.go index 1e541fa1a7a..636c79e36be 100644 --- a/adapters/nexx360/nexx360.go +++ b/adapters/nexx360/nexx360.go @@ -14,16 +14,12 @@ import ( "github.com/prebid/prebid-server/v3/util/jsonutil" ) +const defaultCurrency string = "USD" + type adapter struct { endpoint string } -type MakeImpOutput struct { - Imp []openrtb2.Imp - TagId string - Placement string -} - type Ext struct { Nexx360 ImpNexx360Ext `json:"nexx360"` } @@ -54,20 +50,19 @@ type Nexx360ResBidExt struct { // as one of the hops in the request to exchange var CALLER = Nexx360Caller{"Prebid-Server", "n/a"} -func makeImps(impList []openrtb2.Imp) (MakeImpOutput, error) { - var output MakeImpOutput +func processImps(impList []openrtb2.Imp) (imp []openrtb2.Imp, tagId string, placement string, error error) { var imps []openrtb2.Imp for idx, imp := range impList { var bidderExt adapters.ExtImpBidder if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { - return MakeImpOutput{}, &errortypes.BadInput{ + return nil, "", "", &errortypes.BadInput{ Message: err.Error(), } } var nexx360Ext openrtb_ext.ExtImpNexx360 if err := jsonutil.Unmarshal(bidderExt.Bidder, &nexx360Ext); err != nil { - return MakeImpOutput{}, &errortypes.BadInput{ + return nil, "", "", &errortypes.BadInput{ Message: err.Error(), } } @@ -78,7 +73,7 @@ func makeImps(impList []openrtb2.Imp) (MakeImpOutput, error) { impExtJSON, err := json.Marshal(impExt) if err != nil { - return MakeImpOutput{}, &errortypes.BadInput{ + return nil, "", "", &errortypes.BadInput{ Message: err.Error(), } } @@ -86,22 +81,32 @@ func makeImps(impList []openrtb2.Imp) (MakeImpOutput, error) { imp.Ext = impExtJSON imps = append(imps, imp) if idx == 0 { - output.TagId = nexx360Ext.TagId - output.Placement = nexx360Ext.Placement + tagId = nexx360Ext.TagId + placement = nexx360Ext.Placement } } - output.Imp = imps - return output, nil + + return imps, tagId, placement, nil +} + +func makeReqExt() ([]byte, error) { + var reqExt ReqExt + + reqExt.Nexx360 = &ReqNexx360Ext{} + reqExt.Nexx360.Caller = make([]Nexx360Caller, 0) + reqExt.Nexx360.Caller = append(reqExt.Nexx360.Caller, CALLER) + + return json.Marshal(reqExt) } func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { - var makeImp, err = makeImps(request.Imp) + var imp, tagId, placement, err = processImps(request.Imp) if err != nil { return nil, []error{err} } - request.Imp = makeImp.Imp + request.Imp = imp; urlBuilder, err := url.Parse(a.endpoint) if err != nil { @@ -109,17 +114,17 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E } query := url.Values{} - if makeImp.Placement != "" { - query["placement"] = []string{makeImp.Placement} + if placement != "" { + query["placement"] = []string{placement} } - if makeImp.TagId != "" { - query["tag_id"] = []string{makeImp.TagId} + if tagId != "" { + query["tag_id"] = []string{tagId} } urlBuilder.RawQuery = query.Encode() uri := urlBuilder.String() - reqExt, err := makeReqExt(request) + reqExt, err := makeReqExt() if err != nil { return nil, []error{err} } @@ -146,27 +151,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E return []*adapters.RequestData{adapter}, nil } -func makeReqExt(request *openrtb2.BidRequest) ([]byte, error) { - var reqExt ReqExt - if len(request.Ext) > 0 { - if err := jsonutil.Unmarshal(request.Ext, &reqExt); err != nil { - return nil, err - } - } - - if reqExt.Nexx360 == nil { - reqExt.Nexx360 = &ReqNexx360Ext{} - } - - if reqExt.Nexx360.Caller == nil { - reqExt.Nexx360.Caller = make([]Nexx360Caller, 0) - } - - reqExt.Nexx360.Caller = append(reqExt.Nexx360.Caller, CALLER) - - return json.Marshal(reqExt) -} // MakeBids make the bids for the bid response. func (a *adapter) MakeBids(request *openrtb2.BidRequest, externalRequest *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { @@ -214,7 +199,11 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, externalRequest *adapte } bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(Bids)) bidResponse.Bids = Bids - bidResponse.Currency = response.Cur + if response.Cur != "" { + bidResponse.Currency = response.Cur + } else { + bidResponse.Currency = defaultCurrency + } return bidResponse, errors } diff --git a/adapters/nexx360/nexx360test/exemplary/simple-banner.json b/adapters/nexx360/nexx360test/exemplary/simple-banner.json index 53040b36ce8..b8e7ba9f000 100644 --- a/adapters/nexx360/nexx360test/exemplary/simple-banner.json +++ b/adapters/nexx360/nexx360test/exemplary/simple-banner.json @@ -16,7 +16,11 @@ } } ], - "site": {} + "site": {}, + "ext": { + "nexx360": "Prebid-Server", + "test": 1 + } }, "httpCalls": [ From 5a6f521f425be240e7843d654039fc0bddbcf908 Mon Sep 17 00:00:00 2001 From: Gabriel Chicoye Date: Tue, 15 Apr 2025 16:33:20 +0200 Subject: [PATCH 07/16] fmt fix --- adapters/nexx360/nexx360.go | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/adapters/nexx360/nexx360.go b/adapters/nexx360/nexx360.go index 636c79e36be..dca3ae54aca 100644 --- a/adapters/nexx360/nexx360.go +++ b/adapters/nexx360/nexx360.go @@ -50,7 +50,7 @@ type Nexx360ResBidExt struct { // as one of the hops in the request to exchange var CALLER = Nexx360Caller{"Prebid-Server", "n/a"} -func processImps(impList []openrtb2.Imp) (imp []openrtb2.Imp, tagId string, placement string, error error) { +func processImps(impList []openrtb2.Imp) (imp []openrtb2.Imp, tagId string, placement string, error error) { var imps []openrtb2.Imp for idx, imp := range impList { var bidderExt adapters.ExtImpBidder @@ -62,7 +62,7 @@ func processImps(impList []openrtb2.Imp) (imp []openrtb2.Imp, tagId string, pla var nexx360Ext openrtb_ext.ExtImpNexx360 if err := jsonutil.Unmarshal(bidderExt.Bidder, &nexx360Ext); err != nil { - return nil, "", "", &errortypes.BadInput{ + return nil, "", "", &errortypes.BadInput{ Message: err.Error(), } } @@ -73,7 +73,7 @@ func processImps(impList []openrtb2.Imp) (imp []openrtb2.Imp, tagId string, pla impExtJSON, err := json.Marshal(impExt) if err != nil { - return nil, "", "", &errortypes.BadInput{ + return nil, "", "", &errortypes.BadInput{ Message: err.Error(), } } @@ -86,8 +86,8 @@ func processImps(impList []openrtb2.Imp) (imp []openrtb2.Imp, tagId string, pla } } - - return imps, tagId, placement, nil + + return imps, tagId, placement, nil } func makeReqExt() ([]byte, error) { @@ -106,7 +106,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E return nil, []error{err} } - request.Imp = imp; + request.Imp = imp urlBuilder, err := url.Parse(a.endpoint) if err != nil { @@ -151,8 +151,6 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E return []*adapters.RequestData{adapter}, nil } - - // MakeBids make the bids for the bid response. func (a *adapter) MakeBids(request *openrtb2.BidRequest, externalRequest *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { if responseData.StatusCode == http.StatusNoContent { From dfd21d738024509b3f33c8db98401f40b95060cf Mon Sep 17 00:00:00 2001 From: Gabriel Chicoye Date: Wed, 16 Apr 2025 10:44:21 +0200 Subject: [PATCH 08/16] version update --- adapters/nexx360/nexx360.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/adapters/nexx360/nexx360.go b/adapters/nexx360/nexx360.go index dca3ae54aca..d4ee7d350b5 100644 --- a/adapters/nexx360/nexx360.go +++ b/adapters/nexx360/nexx360.go @@ -12,6 +12,7 @@ import ( "github.com/prebid/prebid-server/v3/errortypes" "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/version" ) const defaultCurrency string = "USD" @@ -48,7 +49,15 @@ type Nexx360ResBidExt struct { // CALLER Info used to track Prebid Server // as one of the hops in the request to exchange -var CALLER = Nexx360Caller{"Prebid-Server", "n/a"} + +func getVersion() string { + if version.Ver != "" { + return version.Ver + } + return "n/a" +} + +var CALLER = Nexx360Caller{"Prebid-Server", getVersion()} func processImps(impList []openrtb2.Imp) (imp []openrtb2.Imp, tagId string, placement string, error error) { var imps []openrtb2.Imp From 54baa41efe4bbdbea0c6acb6482178c54db02b89 Mon Sep 17 00:00:00 2001 From: Gabriel Chicoye Date: Fri, 18 Apr 2025 10:57:16 +0200 Subject: [PATCH 09/16] fixes --- adapters/nexx360/nexx360.go | 38 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/adapters/nexx360/nexx360.go b/adapters/nexx360/nexx360.go index d4ee7d350b5..2bfc528e202 100644 --- a/adapters/nexx360/nexx360.go +++ b/adapters/nexx360/nexx360.go @@ -47,6 +47,10 @@ type Nexx360ResBidExt struct { BidType string `json:"bidType,omitempty"` } +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + return &adapter{endpoint: config.Endpoint}, nil +} + // CALLER Info used to track Prebid Server // as one of the hops in the request to exchange @@ -76,9 +80,12 @@ func processImps(impList []openrtb2.Imp) (imp []openrtb2.Imp, tagId string, plac } } - var impExt Ext - impExt.Nexx360.TagId = nexx360Ext.TagId - impExt.Nexx360.Placement = nexx360Ext.Placement + impExt := Ext{ + Nexx360: ImpNexx360Ext{ + TagId: nexx360Ext.TagId, + Placement: nexx360Ext.Placement, + }, + } impExtJSON, err := json.Marshal(impExt) if err != nil { @@ -100,11 +107,11 @@ func processImps(impList []openrtb2.Imp) (imp []openrtb2.Imp, tagId string, plac } func makeReqExt() ([]byte, error) { - var reqExt ReqExt - - reqExt.Nexx360 = &ReqNexx360Ext{} - reqExt.Nexx360.Caller = make([]Nexx360Caller, 0) - reqExt.Nexx360.Caller = append(reqExt.Nexx360.Caller, CALLER) + reqExt := ReqExt{ + Nexx360: &ReqNexx360Ext{ + Caller: []Nexx360Caller{CALLER}, + }, + } return json.Marshal(reqExt) } @@ -162,23 +169,16 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E // MakeBids make the bids for the bid response. func (a *adapter) MakeBids(request *openrtb2.BidRequest, externalRequest *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { - if responseData.StatusCode == http.StatusNoContent { + if adapters.IsResponseStatusCodeNoContent(responseData) { return nil, nil } - if responseData.StatusCode == http.StatusBadRequest { + if err := adapters.CheckResponseStatusCodeForErrors(responseData); err != nil { return nil, []error{&errortypes.BadInput{ Message: fmt.Sprintf("Unexpected http status code: %d", responseData.StatusCode), }} } - if responseData.StatusCode != http.StatusOK { - fmt.Printf("Nexx360: Bad server response: %d\n", responseData.StatusCode) - return nil, []error{&errortypes.BadServerResponse{ - Message: fmt.Sprintf("Unexpected http status code: %d", responseData.StatusCode), - }} - } - var response openrtb2.BidResponse if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { @@ -236,7 +236,3 @@ func getBidType(bid openrtb2.Bid) (openrtb_ext.BidType, error) { Message: fmt.Sprintf("unable to fetch mediaType in multi-format: %s", bid.ImpID), } } - -func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { - return &adapter{endpoint: config.Endpoint}, nil -} From 9959335771367e4ad6ff9f3c31d7f36e57090f7e Mon Sep 17 00:00:00 2001 From: Gabriel Chicoye Date: Fri, 18 Apr 2025 12:00:22 +0200 Subject: [PATCH 10/16] fixes --- adapters/nexx360/nexx360.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/adapters/nexx360/nexx360.go b/adapters/nexx360/nexx360.go index 2bfc528e202..0b9d1f6426c 100644 --- a/adapters/nexx360/nexx360.go +++ b/adapters/nexx360/nexx360.go @@ -15,8 +15,6 @@ import ( "github.com/prebid/prebid-server/v3/version" ) -const defaultCurrency string = "USD" - type adapter struct { endpoint string } @@ -208,8 +206,6 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, externalRequest *adapte bidResponse.Bids = Bids if response.Cur != "" { bidResponse.Currency = response.Cur - } else { - bidResponse.Currency = defaultCurrency } return bidResponse, errors From 9a656bc2169749b042f1c5ab1439135311798144 Mon Sep 17 00:00:00 2001 From: Gabriel Chicoye Date: Mon, 28 Apr 2025 10:51:30 +0200 Subject: [PATCH 11/16] const as key --- adapters/nexx360/nexx360.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/adapters/nexx360/nexx360.go b/adapters/nexx360/nexx360.go index 0b9d1f6426c..ebe1d17c7b2 100644 --- a/adapters/nexx360/nexx360.go +++ b/adapters/nexx360/nexx360.go @@ -128,11 +128,15 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E } query := url.Values{} + + const placementKey = "placement" if placement != "" { - query["placement"] = []string{placement} + query[placementKey] = []string{placement} } + + const tagIdKey = "tag_id" if tagId != "" { - query["tag_id"] = []string{tagId} + query[tagIdKey] = []string{tagId} } urlBuilder.RawQuery = query.Encode() From 60e490de264ac81a84a7bf8a1222b34681342a8b Mon Sep 17 00:00:00 2001 From: Gabriel Chicoye Date: Mon, 28 Apr 2025 11:04:35 +0200 Subject: [PATCH 12/16] gofmt fix --- adapters/nexx360/nexx360.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adapters/nexx360/nexx360.go b/adapters/nexx360/nexx360.go index ebe1d17c7b2..217c8ceedaa 100644 --- a/adapters/nexx360/nexx360.go +++ b/adapters/nexx360/nexx360.go @@ -133,7 +133,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E if placement != "" { query[placementKey] = []string{placement} } - + const tagIdKey = "tag_id" if tagId != "" { query[tagIdKey] = []string{tagId} From bc990bdac9ea635dd5c4c9dd4e719be5e97d9f0a Mon Sep 17 00:00:00 2001 From: Gabriel Chicoye Date: Wed, 30 Apr 2025 09:18:58 +0200 Subject: [PATCH 13/16] formatUpdate --- adapters/nexx360/nexx360.go | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/adapters/nexx360/nexx360.go b/adapters/nexx360/nexx360.go index 217c8ceedaa..7783e92ed60 100644 --- a/adapters/nexx360/nexx360.go +++ b/adapters/nexx360/nexx360.go @@ -20,12 +20,7 @@ type adapter struct { } type Ext struct { - Nexx360 ImpNexx360Ext `json:"nexx360"` -} - -type ImpNexx360Ext struct { - TagId string `json:"tagId,omitempty"` - Placement string `json:"placement,omitempty"` + Nexx360 json.RawMessage `json:"nexx360"` } type Nexx360Caller struct { @@ -79,10 +74,7 @@ func processImps(impList []openrtb2.Imp) (imp []openrtb2.Imp, tagId string, plac } impExt := Ext{ - Nexx360: ImpNexx360Ext{ - TagId: nexx360Ext.TagId, - Placement: nexx360Ext.Placement, - }, + Nexx360: bidderExt.Bidder, } impExtJSON, err := json.Marshal(impExt) @@ -95,6 +87,12 @@ func processImps(impList []openrtb2.Imp) (imp []openrtb2.Imp, tagId string, plac imp.Ext = impExtJSON imps = append(imps, imp) if idx == 0 { + var nexx360Ext openrtb_ext.ExtImpNexx360 + if err := jsonutil.Unmarshal(bidderExt.Bidder, &nexx360Ext); err != nil { + return nil, "", "", &errortypes.BadInput{ + Message: err.Error(), + } + } tagId = nexx360Ext.TagId placement = nexx360Ext.Placement } From cc882db7ddd5e65ebfe47a852e6f7ce743f577fb Mon Sep 17 00:00:00 2001 From: Gabriel Chicoye Date: Thu, 5 Jun 2025 13:44:00 +0200 Subject: [PATCH 14/16] params test fix --- adapters/nexx360/params_test.go | 5 +++++ static/bidder-params/nexx360.json | 2 ++ 2 files changed, 7 insertions(+) diff --git a/adapters/nexx360/params_test.go b/adapters/nexx360/params_test.go index 812bcf09df5..dc21d211347 100644 --- a/adapters/nexx360/params_test.go +++ b/adapters/nexx360/params_test.go @@ -47,4 +47,9 @@ var validParams = []string{ var invalidParams = []string{ `{"productId": "inview"}`, + `{"tagId": "" }`, + `{"placement": "" }`, + `{"tagId": "testnexx", "placement": "" }`, + `{"tagId": "", "placement": "testnexx"}`, + `{}`, } diff --git a/static/bidder-params/nexx360.json b/static/bidder-params/nexx360.json index f504f6080a8..a2f35276ace 100644 --- a/static/bidder-params/nexx360.json +++ b/static/bidder-params/nexx360.json @@ -8,10 +8,12 @@ "properties": { "tagId": { "type": "string", + "minLength": 1, "description": "TagId" }, "placement": { "type": "string", + "minLength": 1, "description": "Placement" } }, From 1ac372cd11067ca1ab172fb00b94623ab642f00f Mon Sep 17 00:00:00 2001 From: Gabriel Chicoye Date: Tue, 10 Jun 2025 11:07:57 +0200 Subject: [PATCH 15/16] various fix --- adapters/nexx360/nexx360.go | 21 +-- .../nexx360test/exemplary/simple-audio.json | 158 ++++++++++++++++++ .../supplemental/invalid-bid-response.json | 77 +++++++++ 3 files changed, 241 insertions(+), 15 deletions(-) create mode 100644 adapters/nexx360/nexx360test/exemplary/simple-audio.json create mode 100644 adapters/nexx360/nexx360test/supplemental/invalid-bid-response.json diff --git a/adapters/nexx360/nexx360.go b/adapters/nexx360/nexx360.go index 7783e92ed60..81b0354bff9 100644 --- a/adapters/nexx360/nexx360.go +++ b/adapters/nexx360/nexx360.go @@ -84,19 +84,13 @@ func processImps(impList []openrtb2.Imp) (imp []openrtb2.Imp, tagId string, plac } } - imp.Ext = impExtJSON - imps = append(imps, imp) + impCopy := imp + impCopy.Ext = impExtJSON + imps = append(imps, impCopy) if idx == 0 { - var nexx360Ext openrtb_ext.ExtImpNexx360 - if err := jsonutil.Unmarshal(bidderExt.Bidder, &nexx360Ext); err != nil { - return nil, "", "", &errortypes.BadInput{ - Message: err.Error(), - } - } tagId = nexx360Ext.TagId placement = nexx360Ext.Placement } - } return imps, tagId, placement, nil @@ -127,14 +121,12 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E query := url.Values{} - const placementKey = "placement" if placement != "" { - query[placementKey] = []string{placement} + query.Add("placement", placement) } - const tagIdKey = "tag_id" if tagId != "" { - query[tagIdKey] = []string{tagId} + query.Add("tag_id", tagId) } urlBuilder.RawQuery = query.Encode() @@ -151,13 +143,12 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E if err != nil { return nil, []error{err} } - fmt.Printf("Nexx360: Request JSON: %s\n", string(reqJSON)) headers := http.Header{} headers.Add("Content-Type", "application/json") adapter := &adapters.RequestData{ - Method: "POST", + Method: http.MethodPost, Uri: uri, Body: reqJSON, Headers: headers, diff --git a/adapters/nexx360/nexx360test/exemplary/simple-audio.json b/adapters/nexx360/nexx360test/exemplary/simple-audio.json new file mode 100644 index 00000000000..70997739ec7 --- /dev/null +++ b/adapters/nexx360/nexx360test/exemplary/simple-audio.json @@ -0,0 +1,158 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "criteo.com" + }, + "device": { + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "user": { + "ext": { + "eids": [ + { + "source": "criteo.com", + "uids": [ + { + "id": "criteo-eid" + } + ] + } + ] + } + }, + "imp": [ + { + "id": "test-imp-id", + "audio": { + "mimes": ["audio/mp3"], + "protocols": [2, 5], + "minduration": 10, + "maxduration": 30 + }, + "ext": { + "bidder": { + "tagId": "testnexx" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://fast.nexx360.io/prebid-server?tag_id=testnexx", + "headers": { + "Content-Type": [ + "application/json" + ] + }, + "body": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "criteo.com" + }, + "device": { + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "user": { + "ext": { + "eids": [ + { + "source": "criteo.com", + "uids": [ + { + "id": "criteo-eid" + } + ] + } + ] + } + }, + "imp": [ + { + "id": "test-imp-id", + "audio": { + "mimes": ["audio/mp3"], + "protocols": [2, 5], + "minduration": 10, + "maxduration": 30 + }, + "ext": { + "nexx360": { + "tagId": "testnexx" + } + } + } + ], + "ext": { + "nexx360": { + "caller": [ + { + "name": "Prebid-Server", + "version": "n/a" + } + ] + } + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "currency": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "some-test-ad-vast", + "ext": { + "mediaType": "audio", + "bidType": "audio", + "tagId": "testnexx", + "ssp": "test" + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "some-test-ad-vast", + "ext": { + "mediaType": "audio", + "bidType": "audio", + "tagId": "testnexx", + "ssp": "test" + } + }, + "type": "audio" + } + ] + } + ] +} + diff --git a/adapters/nexx360/nexx360test/supplemental/invalid-bid-response.json b/adapters/nexx360/nexx360test/supplemental/invalid-bid-response.json new file mode 100644 index 00000000000..b3b45b21128 --- /dev/null +++ b/adapters/nexx360/nexx360test/supplemental/invalid-bid-response.json @@ -0,0 +1,77 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "w": 728, + "h": 90 + }, + "ext": { + "bidder": { + "tagId": "testnexx" + } + } + } + ], + "site": {}, + "ext": { + "nexx360": "Prebid-Server", + "test": 1 + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://fast.nexx360.io/prebid-server?tag_id=testnexx", + "body": { + "ext": { + "nexx360": { + "caller": [ + { + "name": "Prebid-Server", + "version": "n/a" + } + ] + } + }, + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "w": 728, + "h": 90 + }, + "ext": { + "nexx360": { + "tagId": "testnexx" + } + } + } + ], + "site": {} + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": {}, + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "cannot unmarshal openrtb2.BidResponse.SeatBid: decode slice: expect [ or n, but found {", + "comparison": "literal" + } + ] +} \ No newline at end of file From b2beef7c8b402d98dcb5539e376a12362fec9d87 Mon Sep 17 00:00:00 2001 From: Gabriel Chicoye Date: Fri, 20 Jun 2025 07:03:56 +0200 Subject: [PATCH 16/16] test fix --- adapters/nexx360/nexx360.go | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/adapters/nexx360/nexx360.go b/adapters/nexx360/nexx360.go index 81b0354bff9..f91961918ce 100644 --- a/adapters/nexx360/nexx360.go +++ b/adapters/nexx360/nexx360.go @@ -66,13 +66,6 @@ func processImps(impList []openrtb2.Imp) (imp []openrtb2.Imp, tagId string, plac } } - var nexx360Ext openrtb_ext.ExtImpNexx360 - if err := jsonutil.Unmarshal(bidderExt.Bidder, &nexx360Ext); err != nil { - return nil, "", "", &errortypes.BadInput{ - Message: err.Error(), - } - } - impExt := Ext{ Nexx360: bidderExt.Bidder, } @@ -88,6 +81,12 @@ func processImps(impList []openrtb2.Imp) (imp []openrtb2.Imp, tagId string, plac impCopy.Ext = impExtJSON imps = append(imps, impCopy) if idx == 0 { + var nexx360Ext openrtb_ext.ExtImpNexx360 + if err := jsonutil.Unmarshal(bidderExt.Bidder, &nexx360Ext); err != nil { + return nil, "", "", &errortypes.BadInput{ + Message: err.Error(), + } + } tagId = nexx360Ext.TagId placement = nexx360Ext.Placement }