From 561edec0445f45bc3f8b49c4c7a9173cd3aa7cf6 Mon Sep 17 00:00:00 2001 From: Dmytro Shyrokov Date: Fri, 29 Sep 2023 11:58:47 +0300 Subject: [PATCH 1/7] iqx adapter init --- adapters/iqx/iqx.go | 161 ++++++++++ adapters/iqx/iqxtest_test.go | 27 ++ .../iqx/iqzonextest/exemplary/banner.json | 279 ++++++++++++++++++ .../iqx/iqzonextest/exemplary/native.json | 162 ++++++++++ adapters/iqx/iqzonextest/exemplary/video.json | 202 +++++++++++++ .../supplemental/bad-response.json | 106 +++++++ .../supplemental/empty-mediatype.json | 188 ++++++++++++ .../supplemental/empty-seatbid-0-bid.json | 111 +++++++ .../supplemental/empty-seatbid.json | 111 +++++++ .../invalid-ext-bidder-object.json | 49 +++ .../supplemental/invalid-ext-object.json | 47 +++ .../supplemental/invalid-mediatype.json | 190 ++++++++++++ .../iqzonextest/supplemental/status-204.json | 100 +++++++ .../iqzonextest/supplemental/status-400.json | 106 +++++++ .../iqzonextest/supplemental/status-503.json | 105 +++++++ .../supplemental/unexpected-status.json | 106 +++++++ adapters/iqx/params_test.go | 53 ++++ exchange/adapter_builders.go | 2 + openrtb_ext/bidders.go | 2 + openrtb_ext/imp_iqx.go | 6 + static/bidder-info/iqx.yaml | 19 ++ static/bidder-params/iqx.json | 22 ++ 22 files changed, 2154 insertions(+) create mode 100644 adapters/iqx/iqx.go create mode 100644 adapters/iqx/iqxtest_test.go create mode 100644 adapters/iqx/iqzonextest/exemplary/banner.json create mode 100644 adapters/iqx/iqzonextest/exemplary/native.json create mode 100644 adapters/iqx/iqzonextest/exemplary/video.json create mode 100644 adapters/iqx/iqzonextest/supplemental/bad-response.json create mode 100644 adapters/iqx/iqzonextest/supplemental/empty-mediatype.json create mode 100644 adapters/iqx/iqzonextest/supplemental/empty-seatbid-0-bid.json create mode 100644 adapters/iqx/iqzonextest/supplemental/empty-seatbid.json create mode 100644 adapters/iqx/iqzonextest/supplemental/invalid-ext-bidder-object.json create mode 100644 adapters/iqx/iqzonextest/supplemental/invalid-ext-object.json create mode 100644 adapters/iqx/iqzonextest/supplemental/invalid-mediatype.json create mode 100644 adapters/iqx/iqzonextest/supplemental/status-204.json create mode 100644 adapters/iqx/iqzonextest/supplemental/status-400.json create mode 100644 adapters/iqx/iqzonextest/supplemental/status-503.json create mode 100644 adapters/iqx/iqzonextest/supplemental/unexpected-status.json create mode 100644 adapters/iqx/params_test.go create mode 100644 openrtb_ext/imp_iqx.go create mode 100644 static/bidder-info/iqx.yaml create mode 100644 static/bidder-params/iqx.json diff --git a/adapters/iqx/iqx.go b/adapters/iqx/iqx.go new file mode 100644 index 00000000000..88bedb9184a --- /dev/null +++ b/adapters/iqx/iqx.go @@ -0,0 +1,161 @@ +package iqx + +import ( + "encoding/json" + "fmt" + "net/http" + "text/template" + + "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/adapters" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/errortypes" + "github.com/prebid/prebid-server/macros" + "github.com/prebid/prebid-server/openrtb_ext" +) + +type bidType struct { + Type string `json:"type"` +} + +type bidExt struct { + Prebid bidType `json:"prebid"` +} + +type adapter struct { + endpoint *template.Template +} + +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + tmpl, err := template.New("endpointTemplate").Parse(config.Endpoint) + if err != nil { + return nil, fmt.Errorf("unable to parse endpoint URL template: %v", err) + } + + bidder := &adapter{ + endpoint: tmpl, + } + + return bidder, nil +} + +func (a *adapter) buildEndpointFromRequest(imp *openrtb2.Imp) (string, error) { + var impExt adapters.ExtImpBidder + if err := json.Unmarshal(imp.Ext, &impExt); err != nil { + return "", &errortypes.BadInput{ + Message: fmt.Sprintf("Failed to deserialize bidder impression extension: %v", err), + } + } + + var iqzonexExt openrtb_ext.ExtIQX + if err := json.Unmarshal(impExt.Bidder, &iqzonexExt); err != nil { + return "", &errortypes.BadInput{ + Message: fmt.Sprintf("Failed to deserialize IQZonex extension: %v", err), + } + } + + endpointParams := macros.EndpointTemplateParams{ + Host: iqzonexExt.Env, + SourceId: iqzonexExt.Pid, + } + + return macros.ResolveMacros(a.endpoint, endpointParams) +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + var requests []*adapters.RequestData + var errs []error + + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + headers.Add("Accept", "application/json") + + requestCopy := *request + for _, imp := range request.Imp { + requestCopy.Imp = []openrtb2.Imp{imp} + + endpoint, err := a.buildEndpointFromRequest(&imp) + if err != nil { + errs = append(errs, err) + continue + } + + requestJSON, err := json.Marshal(requestCopy) + if err != nil { + errs = append(errs, err) + continue + } + + request := &adapters.RequestData{ + Method: http.MethodPost, + Body: requestJSON, + Uri: endpoint, + Headers: headers, + } + + requests = append(requests, request) + } + + return requests, errs +} + +func (a *adapter) MakeBids(openRTBRequest *openrtb2.BidRequest, requestToBidder *adapters.RequestData, bidderRawResponse *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if adapters.IsResponseStatusCodeNoContent(bidderRawResponse) { + return nil, nil + } + + if bidderRawResponse.StatusCode == http.StatusServiceUnavailable { + return nil, []error{&errortypes.BadInput{ + Message: "Bidder IQZonex is unavailable. Please contact the bidder support.", + }} + } + + if err := adapters.CheckResponseStatusCodeForErrors(bidderRawResponse); err != nil { + return nil, []error{err} + } + + var bidResp openrtb2.BidResponse + if err := json.Unmarshal(bidderRawResponse.Body, &bidResp); err != nil { + return nil, []error{err} + } + + if len(bidResp.SeatBid) == 0 { + return nil, []error{&errortypes.BadServerResponse{ + Message: "Array SeatBid cannot be empty", + }} + } + + return prepareBidResponse(bidResp.SeatBid) +} + +func prepareBidResponse(seats []openrtb2.SeatBid) (*adapters.BidderResponse, []error) { + errs := []error{} + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(seats)) + + for _, seatBid := range seats { + for bidId, bid := range seatBid.Bid { + var bidExt bidExt + if err := json.Unmarshal(bid.Ext, &bidExt); err != nil { + errs = append(errs, &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Failed to parse Bid[%d].Ext: %s", bidId, err.Error()), + }) + continue + } + + bidType, err := openrtb_ext.ParseBidType(bidExt.Prebid.Type) + if err != nil { + errs = append(errs, &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Bid[%d].Ext.Prebid.Type expects one of the following values: 'banner', 'native', 'video', 'audio', got '%s'", bidId, bidExt.Prebid.Type), + }) + continue + } + + bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ + Bid: &seatBid.Bid[bidId], + BidType: bidType, + }) + } + } + + return bidResponse, errs +} diff --git a/adapters/iqx/iqxtest_test.go b/adapters/iqx/iqxtest_test.go new file mode 100644 index 00000000000..18eaf5fa5ba --- /dev/null +++ b/adapters/iqx/iqxtest_test.go @@ -0,0 +1,27 @@ +package iqx + +import ( + "testing" + + "github.com/prebid/prebid-server/adapters/adapterstest" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/openrtb_ext" + "github.com/stretchr/testify/assert" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder( + openrtb_ext.BidderIQX, + config.Adapter{ + Endpoint: "http://rtb.iqzone.com/?pid={{.SourceId}}&host={{.Host}}&pbs=1", + }, + config.Server{ + ExternalUrl: "http://hosturl.com", + GvlID: 1, + DataCenter: "2", + }, + ) + + assert.NoError(t, buildErr) + adapterstest.RunJSONBidderTest(t, "iqzonextest", bidder) +} diff --git a/adapters/iqx/iqzonextest/exemplary/banner.json b/adapters/iqx/iqzonextest/exemplary/banner.json new file mode 100644 index 00000000000..88c4fce3457 --- /dev/null +++ b/adapters/iqx/iqzonextest/exemplary/banner.json @@ -0,0 +1,279 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "1", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250, + "pos": 0 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + }, + { + "id": "2", + "secure": 1, + "bidfloor": 0.2, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250, + "pos": 4 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": ["IAB12"], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://rtb.iqzone.com/?pid=3163e2c9e034770c0daaa98c7613b573&host=iqzonex-stage&pbs=1", + "body": { + "id": "id", + "imp": [ + { + "id": "1", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250, + "pos": 0 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": ["IAB12"], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "id", + "seatbid": [ + { + "bid": [ + { + "id": "id", + "impid": "1", + "price": 1.2, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "Test2", + "adomain": ["test.com"], + "cat": ["IAB1"], + "cid": "cid", + "crid": "crid1", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ], + "seat": "seat" + } + ], + "cur": "USD" + } + } + }, + { + "expectedRequest": { + "uri": "http://rtb.iqzone.com/?pid=3163e2c9e034770c0daaa98c7613b573&host=iqzonex-stage&pbs=1", + "body": { + "id": "id", + "imp": [ + { + "id": "2", + "secure": 1, + "bidfloor": 0.2, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250, + "pos": 4 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": ["IAB12"], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "id", + "seatbid": [ + { + "bid": [ + { + "id": "id", + "impid": "2", + "price": 2.4, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "Test3", + "adomain": ["test.com"], + "cat": ["IAB1"], + "cid": "cid", + "crid": "crid", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ], + "seat": "seat" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "id", + "impid": "1", + "price": 1.2, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "Test2", + "adomain": ["test.com"], + "cat": ["IAB1"], + "cid": "cid", + "crid": "crid1", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + }, + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "id", + "impid": "2", + "price": 2.4, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "Test3", + "adomain": ["test.com"], + "cat": ["IAB1"], + "cid": "cid", + "crid": "crid", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/iqx/iqzonextest/exemplary/native.json b/adapters/iqx/iqzonextest/exemplary/native.json new file mode 100644 index 00000000000..19f85cfd06e --- /dev/null +++ b/adapters/iqx/iqzonextest/exemplary/native.json @@ -0,0 +1,162 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "native": { + "request": "{\"ver\":\"1.1\",\"layout\":1,\"adunit\":2,\"plcmtcnt\":6,\"plcmttype\":4,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"wmin\":492,\"hmin\":328,\"type\":3,\"mimes\":[\"image/jpeg\",\"image/jpg\",\"image/png\"]}},{\"id\":4,\"required\":0,\"data\":{\"type\":6}},{\"id\":5,\"required\":0,\"data\":{\"type\":7}},{\"id\":6,\"required\":0,\"data\":{\"type\":1,\"len\":20}}]}", + "ver": "1.1" + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://rtb.iqzone.com/?pid=3163e2c9e034770c0daaa98c7613b573&host=iqzonex-stage&pbs=1", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "native": { + "request": "{\"ver\":\"1.1\",\"layout\":1,\"adunit\":2,\"plcmtcnt\":6,\"plcmttype\":4,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"wmin\":492,\"hmin\":328,\"type\":3,\"mimes\":[\"image/jpeg\",\"image/jpg\",\"image/png\"]}},{\"id\":4,\"required\":0,\"data\":{\"type\":6}},{\"id\":5,\"required\":0,\"data\":{\"type\":7}},{\"id\":6,\"required\":0,\"data\":{\"type\":1,\"len\":20}}]}", + "ver": "1.1" + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "id", + "bidid": "id", + "seatbid": [ + { + "bid": [ + { + "id": "id", + "impid": "id", + "price": 0.1, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "{}", + "adomain": [ + "test.com" + ], + "cat": [ + "IAB1" + ], + "cid": "cid", + "crid": "crid", + "ext": { + "prebid": { + "type": "native" + } + } + } + ], + "seat": "seat" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "id", + "impid": "id", + "price": 0.1, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "{}", + "adomain": [ + "test.com" + ], + "cat": [ + "IAB1" + ], + "cid": "cid", + "crid": "crid", + "ext": { + "prebid": { + "type": "native" + } + } + }, + "type": "native" + } + ] + } + ] +} diff --git a/adapters/iqx/iqzonextest/exemplary/video.json b/adapters/iqx/iqzonextest/exemplary/video.json new file mode 100644 index 00000000000..3364b09f66f --- /dev/null +++ b/adapters/iqx/iqzonextest/exemplary/video.json @@ -0,0 +1,202 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "video": { + "mimes": [ + "video/mp4", + "video/ogg", + "video/webm" + ], + "minduration": 3, + "maxduration": 3000, + "protocols": [ + 2, + 3, + 5, + 6, + 7, + 8 + ], + "w": 480, + "h": 320, + "linearity": 1, + "playbackmethod": [ + 2 + ], + "pos": 0 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://rtb.iqzone.com/?pid=3163e2c9e034770c0daaa98c7613b573&host=iqzonex-stage&pbs=1", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "video": { + "mimes": [ + "video/mp4", + "video/ogg", + "video/webm" + ], + "minduration": 3, + "maxduration": 3000, + "protocols": [ + 2, + 3, + 5, + 6, + 7, + 8 + ], + "w": 480, + "h": 320, + "linearity": 1, + "playbackmethod": [ + 2 + ], + "pos": 0 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "id", + "bidid": "id", + "seatbid": [ + { + "bid": [ + { + "id": "id", + "impid": "id", + "price": 0.1, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "", + "adomain": [ + "test.com" + ], + "cat": [ + "IAB1" + ], + "cid": "cid", + "crid": "crid", + "ext": { + "prebid": { + "type": "video" + } + } + } + ], + "seat": "seat" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "id", + "impid": "id", + "price": 0.1, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "", + "adomain": [ + "test.com" + ], + "cat": [ + "IAB1" + ], + "cid": "cid", + "crid": "crid", + "ext": { + "prebid": { + "type": "video" + } + } + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/iqx/iqzonextest/supplemental/bad-response.json b/adapters/iqx/iqzonextest/supplemental/bad-response.json new file mode 100644 index 00000000000..3d9ff9ffcd3 --- /dev/null +++ b/adapters/iqx/iqzonextest/supplemental/bad-response.json @@ -0,0 +1,106 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://rtb.iqzone.com/?pid=3163e2c9e034770c0daaa98c7613b573&host=iqzonex-stage&pbs=1", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": "" + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "comparison": "literal" + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/iqx/iqzonextest/supplemental/empty-mediatype.json b/adapters/iqx/iqzonextest/supplemental/empty-mediatype.json new file mode 100644 index 00000000000..2c891344b93 --- /dev/null +++ b/adapters/iqx/iqzonextest/supplemental/empty-mediatype.json @@ -0,0 +1,188 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://rtb.iqzone.com/?pid=3163e2c9e034770c0daaa98c7613b573&host=iqzonex-stage&pbs=1", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "id", + "bidid": "id", + "seatbid": [ + { + "bid": [ + { + "id": "id", + "impid": "1", + "price": 0.1, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "Test1", + "adomain": [ + "test.com" + ], + "cat": [ + "IAB1" + ], + "cid": "cid", + "crid": "crid", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, { + "id": "id", + "impid": "2", + "price": 1.2, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "Test2", + "adomain": [ + "test.com" + ], + "cat": [ + "IAB1" + ], + "cid": "cid", + "crid": "crid", + "w": 300, + "h": 250, + "ext": { + "some": "value" + } + } + ], + "seat": "seat" + } + ], + "cur": "USD" + } + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Bid[1].Ext.Prebid.Type expects one of the following values: 'banner', 'native', 'video', 'audio', got ''", + "comparison": "literal" + } + ], + "expectedBidResponses": [ + { + "currency":"USD", + "bids":[ + { + "bid": { + "id": "id", + "impid": "1", + "price": 0.1, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "Test1", + "adomain": ["test.com"], + "cat": ["IAB1"], + "cid": "cid", + "crid": "crid", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/iqx/iqzonextest/supplemental/empty-seatbid-0-bid.json b/adapters/iqx/iqzonextest/supplemental/empty-seatbid-0-bid.json new file mode 100644 index 00000000000..66b78f4bfbd --- /dev/null +++ b/adapters/iqx/iqzonextest/supplemental/empty-seatbid-0-bid.json @@ -0,0 +1,111 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://rtb.iqzone.com/?pid=3163e2c9e034770c0daaa98c7613b573&host=iqzonex-stage&pbs=1", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "id", + "bidid": "id", + "seatbid": [ + { + "bid": [], + "seat": "seat" + } + ], + "cur": "USD" + } + } + } + ], + "expectedMakeBidsErrors": [], + "expectedBidResponses": [{"currency":"USD","bids":[]}] +} diff --git a/adapters/iqx/iqzonextest/supplemental/empty-seatbid.json b/adapters/iqx/iqzonextest/supplemental/empty-seatbid.json new file mode 100644 index 00000000000..4df7e16f767 --- /dev/null +++ b/adapters/iqx/iqzonextest/supplemental/empty-seatbid.json @@ -0,0 +1,111 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://rtb.iqzone.com/?pid=3163e2c9e034770c0daaa98c7613b573&host=iqzonex-stage&pbs=1", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "a1580f2f-be6d-11eb-a150-d094662c1c35", + "bidid": "359da97d0384d8a14767029c18fd840d", + "seatbid": [], + "cur": "USD" + } + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Array SeatBid cannot be empty", + "comparison": "literal" + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/iqx/iqzonextest/supplemental/invalid-ext-bidder-object.json b/adapters/iqx/iqzonextest/supplemental/invalid-ext-bidder-object.json new file mode 100644 index 00000000000..2f124a8cf3b --- /dev/null +++ b/adapters/iqx/iqzonextest/supplemental/invalid-ext-bidder-object.json @@ -0,0 +1,49 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": [] + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [], + "expectedMakeRequestsErrors": [ + { + "value": "Failed to deserialize IQZonex extension: json: cannot unmarshal array into Go value of type openrtb_ext.ExtIQX", + "comparison": "literal" + } + ] +} diff --git a/adapters/iqx/iqzonextest/supplemental/invalid-ext-object.json b/adapters/iqx/iqzonextest/supplemental/invalid-ext-object.json new file mode 100644 index 00000000000..aa215eb3e34 --- /dev/null +++ b/adapters/iqx/iqzonextest/supplemental/invalid-ext-object.json @@ -0,0 +1,47 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": "" + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [], + "expectedMakeRequestsErrors": [ + { + "value": "Failed to deserialize bidder impression extension: json: cannot unmarshal string into Go value of type adapters.ExtImpBidder", + "comparison": "literal" + } + ] +} diff --git a/adapters/iqx/iqzonextest/supplemental/invalid-mediatype.json b/adapters/iqx/iqzonextest/supplemental/invalid-mediatype.json new file mode 100644 index 00000000000..fb001d58f9e --- /dev/null +++ b/adapters/iqx/iqzonextest/supplemental/invalid-mediatype.json @@ -0,0 +1,190 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://rtb.iqzone.com/?pid=3163e2c9e034770c0daaa98c7613b573&host=iqzonex-stage&pbs=1", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "id", + "bidid": "id", + "seatbid": [ + { + "bid": [ + { + "id": "id", + "impid": "1", + "price": 0.1, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "Test1", + "adomain": [ + "test.com" + ], + "cat": [ + "IAB1" + ], + "cid": "cid", + "crid": "crid", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, { + "id": "id", + "impid": "2", + "price": 1.2, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "Test2", + "adomain": [ + "test.com" + ], + "cat": [ + "IAB1" + ], + "cid": "cid", + "crid": "crid", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "wrong" + } + } + } + ], + "seat": "seat" + } + ], + "cur": "USD" + } + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Bid[1].Ext.Prebid.Type expects one of the following values: 'banner', 'native', 'video', 'audio', got 'wrong'", + "comparison": "literal" + } + ], + "expectedBidResponses": [ + { + "currency":"USD", + "bids":[ + { + "bid": { + "id": "id", + "impid": "1", + "price": 0.1, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "Test1", + "adomain": ["test.com"], + "cat": ["IAB1"], + "cid": "cid", + "crid": "crid", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/iqx/iqzonextest/supplemental/status-204.json b/adapters/iqx/iqzonextest/supplemental/status-204.json new file mode 100644 index 00000000000..c850d34b527 --- /dev/null +++ b/adapters/iqx/iqzonextest/supplemental/status-204.json @@ -0,0 +1,100 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://rtb.iqzone.com/?pid=3163e2c9e034770c0daaa98c7613b573&host=iqzonex-stage&pbs=1", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 204, + "body": {} + } + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/iqx/iqzonextest/supplemental/status-400.json b/adapters/iqx/iqzonextest/supplemental/status-400.json new file mode 100644 index 00000000000..7e3d17d3baf --- /dev/null +++ b/adapters/iqx/iqzonextest/supplemental/status-400.json @@ -0,0 +1,106 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://rtb.iqzone.com/?pid=3163e2c9e034770c0daaa98c7613b573&host=iqzonex-stage&pbs=1", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 400, + "body": "The Key has a different ad format" + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/iqx/iqzonextest/supplemental/status-503.json b/adapters/iqx/iqzonextest/supplemental/status-503.json new file mode 100644 index 00000000000..1b6dd02af8c --- /dev/null +++ b/adapters/iqx/iqzonextest/supplemental/status-503.json @@ -0,0 +1,105 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://rtb.iqzone.com/?pid=3163e2c9e034770c0daaa98c7613b573&host=iqzonex-stage&pbs=1", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 503 + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Bidder IQZonex is unavailable. Please contact the bidder support.", + "comparison": "literal" + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/iqx/iqzonextest/supplemental/unexpected-status.json b/adapters/iqx/iqzonextest/supplemental/unexpected-status.json new file mode 100644 index 00000000000..edfdf5fdd80 --- /dev/null +++ b/adapters/iqx/iqzonextest/supplemental/unexpected-status.json @@ -0,0 +1,106 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://rtb.iqzone.com/?pid=3163e2c9e034770c0daaa98c7613b573&host=iqzonex-stage&pbs=1", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "env": "iqzonex-stage", + "pid": "3163e2c9e034770c0daaa98c7613b573" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 403, + "body": "Access is denied" + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 403. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/iqx/params_test.go b/adapters/iqx/params_test.go new file mode 100644 index 00000000000..94bfb1d0926 --- /dev/null +++ b/adapters/iqx/params_test.go @@ -0,0 +1,53 @@ +package iqx + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/openrtb_ext" +) + +var validParams = []string{ + `{"env":"iqzonex-stage", "pid":"123456"}`, +} + +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.BidderIQX, json.RawMessage(validParam)); err != nil { + t.Errorf("Schema rejected iqzonex params: %s", validParam) + } + } +} + +var invalidParams = []string{ + ``, + `null`, + `true`, + `5`, + `[]`, + `{}`, + `{"some": "param"}`, + `{"env":"iqzonex-stage"}`, + `{"pid":"1234"}`, + `{"othervalue":"Lorem ipsum"}`, + `{"env":"iqzonex-stage", pid:""}`, + `{"env":"", pid:"1234"}`, +} + +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.BidderIQX, json.RawMessage(invalidParam)); err == nil { + t.Errorf("Schema allowed unexpected params: %s", invalidParam) + } + } +} diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index c5b4b1134cc..7d29aae6464 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -94,6 +94,7 @@ import ( "github.com/prebid/prebid-server/adapters/inmobi" "github.com/prebid/prebid-server/adapters/interactiveoffers" "github.com/prebid/prebid-server/adapters/invibes" + "github.com/prebid/prebid-server/adapters/iqx" "github.com/prebid/prebid-server/adapters/iqzone" "github.com/prebid/prebid-server/adapters/ix" "github.com/prebid/prebid-server/adapters/jixie" @@ -291,6 +292,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderInteractiveoffers: interactiveoffers.Builder, openrtb_ext.BidderInvibes: invibes.Builder, openrtb_ext.BidderIQZone: iqzone.Builder, + openrtb_ext.BidderIQX: iqx.Builder, openrtb_ext.BidderIx: ix.Builder, openrtb_ext.BidderJANet: adtelligent.Builder, openrtb_ext.BidderJixie: jixie.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 67f43ec62dd..242ad83728d 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -120,6 +120,7 @@ var coreBidderNames []BidderName = []BidderName{ BidderInMobi, BidderInteractiveoffers, BidderInvibes, + BidderIQX, BidderIQZone, BidderIx, BidderJANet, @@ -408,6 +409,7 @@ const ( BidderInMobi BidderName = "inmobi" BidderInteractiveoffers BidderName = "interactiveoffers" BidderInvibes BidderName = "invibes" + BidderIQX BidderName = "iqx" BidderIQZone BidderName = "iqzone" BidderIx BidderName = "ix" BidderJANet BidderName = "janet" diff --git a/openrtb_ext/imp_iqx.go b/openrtb_ext/imp_iqx.go new file mode 100644 index 00000000000..0b0358b67e1 --- /dev/null +++ b/openrtb_ext/imp_iqx.go @@ -0,0 +1,6 @@ +package openrtb_ext + +type ExtIQX struct { + Env string `json:"env"` + Pid string `json:"pid"` +} diff --git a/static/bidder-info/iqx.yaml b/static/bidder-info/iqx.yaml new file mode 100644 index 00000000000..03d06e0d48d --- /dev/null +++ b/static/bidder-info/iqx.yaml @@ -0,0 +1,19 @@ +endpoint: "http://localhost:1337/?pid={{.SourceId}}&host={{.Host}}&pbs=1" +maintainer: + email: "it@iqzone.com" +capabilities: + app: + mediaTypes: + - banner + - video + - native + site: + mediaTypes: + - banner + - video + - native +userSync: + # IQX supports user syncing, but requires configuration by the host. contact this + # bidder directly at the email address in this file to ask about enabling user sync. + supports: + - redirect \ No newline at end of file diff --git a/static/bidder-params/iqx.json b/static/bidder-params/iqx.json new file mode 100644 index 00000000000..3e661cfc4da --- /dev/null +++ b/static/bidder-params/iqx.json @@ -0,0 +1,22 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "IQX Adapter Params", + "description": "A schema which validates params accepted by the iqzonex adapter", + "type": "object", + "properties": { + "env": { + "type": "string", + "description": "IQX environment", + "minLength": 1 + }, + "pid": { + "type": "string", + "description": "Uniq placement ID", + "minLength": 1 + } + }, + "required": [ + "env", + "pid" + ] +} From a427c321f6b34090eae205fc16ca8d76b86575b4 Mon Sep 17 00:00:00 2001 From: Dmytro Shyrokov Date: Fri, 29 Sep 2023 12:00:36 +0300 Subject: [PATCH 2/7] iqx: setup live ep --- static/bidder-info/iqx.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/bidder-info/iqx.yaml b/static/bidder-info/iqx.yaml index 03d06e0d48d..057e38628af 100644 --- a/static/bidder-info/iqx.yaml +++ b/static/bidder-info/iqx.yaml @@ -1,4 +1,4 @@ -endpoint: "http://localhost:1337/?pid={{.SourceId}}&host={{.Host}}&pbs=1" +endpoint: "http://rtb.iqzone.com/?pid={{.SourceId}}&host={{.Host}}&pbs=1" maintainer: email: "it@iqzone.com" capabilities: From d9980803ab7a6df1bbd33adf5d350fcd52fded4c Mon Sep 17 00:00:00 2001 From: Dmytro Shyrokov Date: Tue, 3 Oct 2023 11:26:44 +0300 Subject: [PATCH 3/7] onkarvhanumante code review --- adapters/iqx/iqx.go | 1 - static/bidder-info/iqx.yaml | 2 +- static/bidder-params/iqx.json | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/adapters/iqx/iqx.go b/adapters/iqx/iqx.go index 88bedb9184a..bef19fba4b9 100644 --- a/adapters/iqx/iqx.go +++ b/adapters/iqx/iqx.go @@ -141,7 +141,6 @@ func prepareBidResponse(seats []openrtb2.SeatBid) (*adapters.BidderResponse, []e }) continue } - bidType, err := openrtb_ext.ParseBidType(bidExt.Prebid.Type) if err != nil { errs = append(errs, &errortypes.BadServerResponse{ diff --git a/static/bidder-info/iqx.yaml b/static/bidder-info/iqx.yaml index 057e38628af..ab10ad96289 100644 --- a/static/bidder-info/iqx.yaml +++ b/static/bidder-info/iqx.yaml @@ -1,4 +1,4 @@ -endpoint: "http://rtb.iqzone.com/?pid={{.SourceId}}&host={{.Host}}&pbs=1" +endpoint: "http://rtb.iqzone.com?pid={{.SourceId}}&host={{.Host}}&pbs=1" maintainer: email: "it@iqzone.com" capabilities: diff --git a/static/bidder-params/iqx.json b/static/bidder-params/iqx.json index 3e661cfc4da..447c92beeb8 100644 --- a/static/bidder-params/iqx.json +++ b/static/bidder-params/iqx.json @@ -11,7 +11,7 @@ }, "pid": { "type": "string", - "description": "Uniq placement ID", + "description": "Unique placement ID", "minLength": 1 } }, From d947591366961035bab13ba514ce868e299357d0 Mon Sep 17 00:00:00 2001 From: IQzoneIT Date: Tue, 3 Oct 2023 15:15:25 +0300 Subject: [PATCH 4/7] Update adapter_builders.go --- exchange/adapter_builders.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 7d29aae6464..e3f7ac8466c 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -291,8 +291,8 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderInMobi: inmobi.Builder, openrtb_ext.BidderInteractiveoffers: interactiveoffers.Builder, openrtb_ext.BidderInvibes: invibes.Builder, - openrtb_ext.BidderIQZone: iqzone.Builder, openrtb_ext.BidderIQX: iqx.Builder, + openrtb_ext.BidderIQZone: iqzone.Builder, openrtb_ext.BidderIx: ix.Builder, openrtb_ext.BidderJANet: adtelligent.Builder, openrtb_ext.BidderJixie: jixie.Builder, From 8da02ed6191445c7ff95f0aea2a482a687ebb578 Mon Sep 17 00:00:00 2001 From: Dmytro Shyrokov Date: Mon, 9 Oct 2023 10:33:59 +0300 Subject: [PATCH 5/7] remove audio from mediatype err --- adapters/iqx/iqx.go | 3 ++- adapters/iqx/iqzonextest/supplemental/empty-mediatype.json | 2 +- adapters/iqx/iqzonextest/supplemental/invalid-mediatype.json | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/adapters/iqx/iqx.go b/adapters/iqx/iqx.go index bef19fba4b9..157f517fdff 100644 --- a/adapters/iqx/iqx.go +++ b/adapters/iqx/iqx.go @@ -141,10 +141,11 @@ func prepareBidResponse(seats []openrtb2.SeatBid) (*adapters.BidderResponse, []e }) continue } + bidType, err := openrtb_ext.ParseBidType(bidExt.Prebid.Type) if err != nil { errs = append(errs, &errortypes.BadServerResponse{ - Message: fmt.Sprintf("Bid[%d].Ext.Prebid.Type expects one of the following values: 'banner', 'native', 'video', 'audio', got '%s'", bidId, bidExt.Prebid.Type), + Message: fmt.Sprintf("Bid[%d].Ext.Prebid.Type expects one of the following values: 'banner', 'native', 'video', got '%s'", bidId, bidExt.Prebid.Type), }) continue } diff --git a/adapters/iqx/iqzonextest/supplemental/empty-mediatype.json b/adapters/iqx/iqzonextest/supplemental/empty-mediatype.json index 2c891344b93..f727e9f52d7 100644 --- a/adapters/iqx/iqzonextest/supplemental/empty-mediatype.json +++ b/adapters/iqx/iqzonextest/supplemental/empty-mediatype.json @@ -152,7 +152,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "Bid[1].Ext.Prebid.Type expects one of the following values: 'banner', 'native', 'video', 'audio', got ''", + "value": "Bid[1].Ext.Prebid.Type expects one of the following values: 'banner', 'native', 'video', got ''", "comparison": "literal" } ], diff --git a/adapters/iqx/iqzonextest/supplemental/invalid-mediatype.json b/adapters/iqx/iqzonextest/supplemental/invalid-mediatype.json index fb001d58f9e..a9f120a2d79 100644 --- a/adapters/iqx/iqzonextest/supplemental/invalid-mediatype.json +++ b/adapters/iqx/iqzonextest/supplemental/invalid-mediatype.json @@ -154,7 +154,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "Bid[1].Ext.Prebid.Type expects one of the following values: 'banner', 'native', 'video', 'audio', got 'wrong'", + "value": "Bid[1].Ext.Prebid.Type expects one of the following values: 'banner', 'native', 'video', got 'wrong'", "comparison": "literal" } ], From ccf5358138af880ee0ecf124601d0d21ba70d1d5 Mon Sep 17 00:00:00 2001 From: Dmytro Shyrokov Date: Mon, 9 Oct 2023 11:19:52 +0300 Subject: [PATCH 6/7] bid MType support, getMediaTypeForBid --- adapters/iqx/iqx.go | 27 ++++++++++--------- .../iqx/iqzonextest/exemplary/banner.json | 4 +++ .../iqx/iqzonextest/exemplary/native.json | 2 ++ adapters/iqx/iqzonextest/exemplary/video.json | 2 ++ .../supplemental/empty-mediatype.json | 4 ++- .../supplemental/invalid-mediatype.json | 11 +++----- 6 files changed, 30 insertions(+), 20 deletions(-) diff --git a/adapters/iqx/iqx.go b/adapters/iqx/iqx.go index 157f517fdff..2512b951f43 100644 --- a/adapters/iqx/iqx.go +++ b/adapters/iqx/iqx.go @@ -134,19 +134,9 @@ func prepareBidResponse(seats []openrtb2.SeatBid) (*adapters.BidderResponse, []e for _, seatBid := range seats { for bidId, bid := range seatBid.Bid { - var bidExt bidExt - if err := json.Unmarshal(bid.Ext, &bidExt); err != nil { - errs = append(errs, &errortypes.BadServerResponse{ - Message: fmt.Sprintf("Failed to parse Bid[%d].Ext: %s", bidId, err.Error()), - }) - continue - } - - bidType, err := openrtb_ext.ParseBidType(bidExt.Prebid.Type) + bidType, err := getMediaTypeForBid(bid) if err != nil { - errs = append(errs, &errortypes.BadServerResponse{ - Message: fmt.Sprintf("Bid[%d].Ext.Prebid.Type expects one of the following values: 'banner', 'native', 'video', got '%s'", bidId, bidExt.Prebid.Type), - }) + errs = append(errs, err) continue } @@ -159,3 +149,16 @@ func prepareBidResponse(seats []openrtb2.SeatBid) (*adapters.BidderResponse, []e return bidResponse, errs } + +func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) { + switch bid.MType { + case openrtb2.MarkupBanner: + return openrtb_ext.BidTypeBanner, nil + case openrtb2.MarkupVideo: + return openrtb_ext.BidTypeVideo, nil + case openrtb2.MarkupNative: + return openrtb_ext.BidTypeNative, nil + default: + return "", fmt.Errorf("failed to parse bid mType for impression \"%s\"", bid.ImpID) + } +} diff --git a/adapters/iqx/iqzonextest/exemplary/banner.json b/adapters/iqx/iqzonextest/exemplary/banner.json index 88c4fce3457..303de661a2d 100644 --- a/adapters/iqx/iqzonextest/exemplary/banner.json +++ b/adapters/iqx/iqzonextest/exemplary/banner.json @@ -125,6 +125,7 @@ "crid": "crid1", "w": 300, "h": 250, + "mtype": 1, "ext": { "prebid": { "type": "banner" @@ -205,6 +206,7 @@ "crid": "crid", "w": 300, "h": 250, + "mtype": 1, "ext": { "prebid": { "type": "banner" @@ -238,6 +240,7 @@ "crid": "crid1", "w": 300, "h": 250, + "mtype": 1, "ext": { "prebid": { "type": "banner" @@ -265,6 +268,7 @@ "crid": "crid", "w": 300, "h": 250, + "mtype": 1, "ext": { "prebid": { "type": "banner" diff --git a/adapters/iqx/iqzonextest/exemplary/native.json b/adapters/iqx/iqzonextest/exemplary/native.json index 19f85cfd06e..f458d70e127 100644 --- a/adapters/iqx/iqzonextest/exemplary/native.json +++ b/adapters/iqx/iqzonextest/exemplary/native.json @@ -113,6 +113,7 @@ ], "cid": "cid", "crid": "crid", + "mtype": 4, "ext": { "prebid": { "type": "native" @@ -148,6 +149,7 @@ ], "cid": "cid", "crid": "crid", + "mtype": 4, "ext": { "prebid": { "type": "native" diff --git a/adapters/iqx/iqzonextest/exemplary/video.json b/adapters/iqx/iqzonextest/exemplary/video.json index 3364b09f66f..21826ac0440 100644 --- a/adapters/iqx/iqzonextest/exemplary/video.json +++ b/adapters/iqx/iqzonextest/exemplary/video.json @@ -153,6 +153,7 @@ ], "cid": "cid", "crid": "crid", + "mtype": 2, "ext": { "prebid": { "type": "video" @@ -188,6 +189,7 @@ ], "cid": "cid", "crid": "crid", + "mtype": 2, "ext": { "prebid": { "type": "video" diff --git a/adapters/iqx/iqzonextest/supplemental/empty-mediatype.json b/adapters/iqx/iqzonextest/supplemental/empty-mediatype.json index f727e9f52d7..2ef8b357713 100644 --- a/adapters/iqx/iqzonextest/supplemental/empty-mediatype.json +++ b/adapters/iqx/iqzonextest/supplemental/empty-mediatype.json @@ -113,6 +113,7 @@ ], "cid": "cid", "crid": "crid", + "mtype": 1, "w": 300, "h": 250, "ext": { @@ -152,7 +153,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "Bid[1].Ext.Prebid.Type expects one of the following values: 'banner', 'native', 'video', got ''", + "value": "failed to parse bid mType for impression \"2\"", "comparison": "literal" } ], @@ -174,6 +175,7 @@ "crid": "crid", "w": 300, "h": 250, + "mtype": 1, "ext": { "prebid": { "type": "banner" diff --git a/adapters/iqx/iqzonextest/supplemental/invalid-mediatype.json b/adapters/iqx/iqzonextest/supplemental/invalid-mediatype.json index a9f120a2d79..5affa99ae0a 100644 --- a/adapters/iqx/iqzonextest/supplemental/invalid-mediatype.json +++ b/adapters/iqx/iqzonextest/supplemental/invalid-mediatype.json @@ -115,6 +115,7 @@ "crid": "crid", "w": 300, "h": 250, + "mtype": 1, "ext": { "prebid": { "type": "banner" @@ -136,12 +137,7 @@ "cid": "cid", "crid": "crid", "w": 300, - "h": 250, - "ext": { - "prebid": { - "type": "wrong" - } - } + "h": 250 } ], "seat": "seat" @@ -154,7 +150,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "Bid[1].Ext.Prebid.Type expects one of the following values: 'banner', 'native', 'video', got 'wrong'", + "value": "failed to parse bid mType for impression \"2\"", "comparison": "literal" } ], @@ -176,6 +172,7 @@ "crid": "crid", "w": 300, "h": 250, + "mtype": 1, "ext": { "prebid": { "type": "banner" From 7ed229ab51e27add0cf2f905397d131e9f36f8bd Mon Sep 17 00:00:00 2001 From: Dmytro Shyrokov Date: Tue, 10 Oct 2023 12:00:14 +0300 Subject: [PATCH 7/7] fix err wording --- adapters/iqx/iqx.go | 2 +- adapters/iqx/iqzonextest/supplemental/empty-mediatype.json | 2 +- adapters/iqx/iqzonextest/supplemental/invalid-mediatype.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/adapters/iqx/iqx.go b/adapters/iqx/iqx.go index 2512b951f43..543d988bce5 100644 --- a/adapters/iqx/iqx.go +++ b/adapters/iqx/iqx.go @@ -159,6 +159,6 @@ func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) { case openrtb2.MarkupNative: return openrtb_ext.BidTypeNative, nil default: - return "", fmt.Errorf("failed to parse bid mType for impression \"%s\"", bid.ImpID) + return "", fmt.Errorf("failed to parse bid mtype for impression id \"%s\"", bid.ImpID) } } diff --git a/adapters/iqx/iqzonextest/supplemental/empty-mediatype.json b/adapters/iqx/iqzonextest/supplemental/empty-mediatype.json index 2ef8b357713..3f471c9c06e 100644 --- a/adapters/iqx/iqzonextest/supplemental/empty-mediatype.json +++ b/adapters/iqx/iqzonextest/supplemental/empty-mediatype.json @@ -153,7 +153,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "failed to parse bid mType for impression \"2\"", + "value": "failed to parse bid mtype for impression id \"2\"", "comparison": "literal" } ], diff --git a/adapters/iqx/iqzonextest/supplemental/invalid-mediatype.json b/adapters/iqx/iqzonextest/supplemental/invalid-mediatype.json index 5affa99ae0a..f2ded0f0cb4 100644 --- a/adapters/iqx/iqzonextest/supplemental/invalid-mediatype.json +++ b/adapters/iqx/iqzonextest/supplemental/invalid-mediatype.json @@ -150,7 +150,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "failed to parse bid mType for impression \"2\"", + "value": "failed to parse bid mtype for impression id \"2\"", "comparison": "literal" } ],