From a35b0d01905f4a9c103f5425dbc7942774b6b7ce Mon Sep 17 00:00:00 2001 From: IQZoneAdx <88879712+IQZoneAdx@users.noreply.github.com> Date: Thu, 19 Aug 2021 20:33:28 +0300 Subject: [PATCH] New Adapter: IQZone (#1964) --- adapters/iqzone/iqzone.go | 99 +++++++++++++ adapters/iqzone/iqzone_test.go | 20 +++ .../iqzonetest/exemplary/simple-banner.json | 132 ++++++++++++++++++ .../iqzonetest/exemplary/simple-native.json | 116 +++++++++++++++ .../iqzonetest/exemplary/simple-video.json | 127 +++++++++++++++++ .../exemplary/simple-web-banner.json | 132 ++++++++++++++++++ .../supplemental/bad_media_type.json | 85 +++++++++++ .../iqzonetest/supplemental/bad_response.json | 83 +++++++++++ .../iqzonetest/supplemental/status-204.json | 78 +++++++++++ .../supplemental/status-not-200.json | 83 +++++++++++ adapters/iqzone/params_test.go | 45 ++++++ config/config.go | 1 + exchange/adapter_builders.go | 2 + openrtb_ext/bidders.go | 2 + openrtb_ext/imp_iqzone.go | 5 + static/bidder-info/iqzone.yaml | 15 ++ static/bidder-params/iqzone.json | 15 ++ usersync/usersyncers/syncer_test.go | 1 + 18 files changed, 1041 insertions(+) create mode 100644 adapters/iqzone/iqzone.go create mode 100644 adapters/iqzone/iqzone_test.go create mode 100644 adapters/iqzone/iqzonetest/exemplary/simple-banner.json create mode 100644 adapters/iqzone/iqzonetest/exemplary/simple-native.json create mode 100644 adapters/iqzone/iqzonetest/exemplary/simple-video.json create mode 100644 adapters/iqzone/iqzonetest/exemplary/simple-web-banner.json create mode 100644 adapters/iqzone/iqzonetest/supplemental/bad_media_type.json create mode 100644 adapters/iqzone/iqzonetest/supplemental/bad_response.json create mode 100644 adapters/iqzone/iqzonetest/supplemental/status-204.json create mode 100644 adapters/iqzone/iqzonetest/supplemental/status-not-200.json create mode 100644 adapters/iqzone/params_test.go create mode 100644 openrtb_ext/imp_iqzone.go create mode 100644 static/bidder-info/iqzone.yaml create mode 100644 static/bidder-params/iqzone.json diff --git a/adapters/iqzone/iqzone.go b/adapters/iqzone/iqzone.go new file mode 100644 index 00000000000..190466b36e0 --- /dev/null +++ b/adapters/iqzone/iqzone.go @@ -0,0 +1,99 @@ +package iqzone + +import ( + "encoding/json" + "fmt" + "net/http" + + "github.com/mxmCherry/openrtb/v15/openrtb2" + "github.com/prebid/prebid-server/adapters" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/errortypes" + "github.com/prebid/prebid-server/openrtb_ext" +) + +type adapter struct { + endpoint string +} + +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter) (adapters.Bidder, error) { + bidder := &adapter{ + endpoint: config.Endpoint, + } + return bidder, nil +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + requestJSON, err := json.Marshal(request) + if err != nil { + return nil, []error{err} + } + + requestData := &adapters.RequestData{ + Method: "POST", + Uri: a.endpoint, + Body: requestJSON, + } + + return []*adapters.RequestData{requestData}, nil +} + +func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if responseData.StatusCode == http.StatusNoContent { + return nil, nil + } + + if responseData.StatusCode != http.StatusOK { + err := &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info.", responseData.StatusCode), + } + return nil, []error{err} + } + + var response openrtb2.BidResponse + if err := json.Unmarshal(responseData.Body, &response); err != nil { + return nil, []error{err} + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) + bidResponse.Currency = response.Cur + for _, seatBid := range response.SeatBid { + for i := range seatBid.Bid { + bidType, err := getMediaTypeForImp(seatBid.Bid[i].ImpID, request.Imp) + if err != nil { + return nil, []error{err} + } + + b := &adapters.TypedBid{ + Bid: &seatBid.Bid[i], + BidType: bidType, + } + bidResponse.Bids = append(bidResponse.Bids, b) + } + } + return bidResponse, nil +} + +func getMediaTypeForImp(impID string, imps []openrtb2.Imp) (openrtb_ext.BidType, error) { + var mediaType openrtb_ext.BidType = "" + for _, imp := range imps { + if imp.ID == impID { + if imp.Banner != nil { + mediaType = openrtb_ext.BidTypeBanner + return mediaType, nil + } + if imp.Banner == nil && imp.Video != nil { + mediaType = openrtb_ext.BidTypeVideo + return mediaType, nil + } + if imp.Banner == nil && imp.Video == nil && imp.Native != nil { + mediaType = openrtb_ext.BidTypeNative + return mediaType, nil + } + } + } + + return "", &errortypes.BadInput{ + Message: fmt.Sprintf("Failed to find impression \"%s\"", impID), + } +} diff --git a/adapters/iqzone/iqzone_test.go b/adapters/iqzone/iqzone_test.go new file mode 100644 index 00000000000..69ee77e2775 --- /dev/null +++ b/adapters/iqzone/iqzone_test.go @@ -0,0 +1,20 @@ +package iqzone + +import ( + "testing" + + "github.com/prebid/prebid-server/adapters/adapterstest" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/openrtb_ext" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderIQZone, config.Adapter{ + Endpoint: "http://smartssp-us-east.iqzone.com/pserver"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "iqzonetest", bidder) +} diff --git a/adapters/iqzone/iqzonetest/exemplary/simple-banner.json b/adapters/iqzone/iqzonetest/exemplary/simple-banner.json new file mode 100644 index 00000000000..f816191ec32 --- /dev/null +++ b/adapters/iqzone/iqzonetest/exemplary/simple-banner.json @@ -0,0 +1,132 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://smartssp-us-east.iqzone.com/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ], + "seat": "iqzone" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/iqzone/iqzonetest/exemplary/simple-native.json b/adapters/iqzone/iqzonetest/exemplary/simple-native.json new file mode 100644 index 00000000000..819e14bf572 --- /dev/null +++ b/adapters/iqzone/iqzonetest/exemplary/simple-native.json @@ -0,0 +1,116 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "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": { + "placementId": "test" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://smartssp-us-east.iqzone.com/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "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": { + "placementId": "test" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "native" + } + } + } + ], + "seat": "iqzone" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "native" + } + } + }, + "type": "native" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/iqzone/iqzonetest/exemplary/simple-video.json b/adapters/iqzone/iqzonetest/exemplary/simple-video.json new file mode 100644 index 00000000000..16e6f4c7144 --- /dev/null +++ b/adapters/iqzone/iqzonetest/exemplary/simple-video.json @@ -0,0 +1,127 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://smartssp-us-east.iqzone.com/pserver", + "body": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "00:01:00", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "ext": { + "prebid": { + "type": "video" + } + } + } + ], + "seat": "iqzone" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "00:01:00", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "ext": { + "prebid": { + "type": "video" + } + } + }, + "type": "video" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/iqzone/iqzonetest/exemplary/simple-web-banner.json b/adapters/iqzone/iqzonetest/exemplary/simple-web-banner.json new file mode 100644 index 00000000000..968c030575b --- /dev/null +++ b/adapters/iqzone/iqzonetest/exemplary/simple-web-banner.json @@ -0,0 +1,132 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "site": { + "id": "1", + "domain": "test.com" + }, + "device": { + "ip": "123.123.123.123", + "ua": "Ubuntu" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://smartssp-us-east.iqzone.com/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "site": { + "id": "1", + "domain": "test.com" + }, + "device": { + "ip": "123.123.123.123", + "ua": "Ubuntu" + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "w": 468, + "h": 60, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ], + "seat": "iqzone" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "w": 468, + "h": 60, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/iqzone/iqzonetest/supplemental/bad_media_type.json b/adapters/iqzone/iqzonetest/supplemental/bad_media_type.json new file mode 100644 index 00000000000..3d1923104e7 --- /dev/null +++ b/adapters/iqzone/iqzonetest/supplemental/bad_media_type.json @@ -0,0 +1,85 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://smartssp-us-east.iqzone.com/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ], + "seat": "iqzone" + } + ], + "cur": "USD" + } + } + }], + "expectedMakeBidsErrors": [ + { + "value": "Failed to find impression \"test-imp-id\"", + "comparison": "literal" + } + ] +} diff --git a/adapters/iqzone/iqzonetest/supplemental/bad_response.json b/adapters/iqzone/iqzonetest/supplemental/bad_response.json new file mode 100644 index 00000000000..ad420705fcd --- /dev/null +++ b/adapters/iqzone/iqzonetest/supplemental/bad_response.json @@ -0,0 +1,83 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://smartssp-us-east.iqzone.com/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + } + }, + "mockResponse": { + "status": 200, + "body": "" + } + }], + "expectedMakeBidsErrors": [ + { + "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "comparison": "literal" + } + ] +} diff --git a/adapters/iqzone/iqzonetest/supplemental/status-204.json b/adapters/iqzone/iqzonetest/supplemental/status-204.json new file mode 100644 index 00000000000..7c2f21c0aa7 --- /dev/null +++ b/adapters/iqzone/iqzonetest/supplemental/status-204.json @@ -0,0 +1,78 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://smartssp-us-east.iqzone.com/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + } + }, + "mockResponse": { + "status": 204, + "body": {} + } + }], + "expectedBidResponses": [] +} diff --git a/adapters/iqzone/iqzonetest/supplemental/status-not-200.json b/adapters/iqzone/iqzonetest/supplemental/status-not-200.json new file mode 100644 index 00000000000..22160ac78d3 --- /dev/null +++ b/adapters/iqzone/iqzonetest/supplemental/status-not-200.json @@ -0,0 +1,83 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "TagID": "test" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://smartssp-us-east.iqzone.com/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "TagID": "test" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + } + }, + "mockResponse": { + "status": 404, + "body": {} + } + }], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 404. Run with request.debug = 1 for more info.", + "comparison": "literal" + } + ] +} diff --git a/adapters/iqzone/params_test.go b/adapters/iqzone/params_test.go new file mode 100644 index 00000000000..deb4af2eda6 --- /dev/null +++ b/adapters/iqzone/params_test.go @@ -0,0 +1,45 @@ +package iqzone + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/openrtb_ext" +) + +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json schema. %v", err) + } + + for _, p := range validParams { + if err := validator.Validate(openrtb_ext.BidderIQZone, json.RawMessage(p)); err != nil { + t.Errorf("Schema rejected valid params: %s", p) + } + } +} + +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json schema. %v", err) + } + + for _, p := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderIQZone, json.RawMessage(p)); err == nil { + t.Errorf("Schema allowed invalid params: %s", p) + } + } +} + +var validParams = []string{ + `{"placementId": "test"}`, + `{"placementId": "1"}`, +} + +var invalidParams = []string{ + `{"placementId": 42}`, + `{}`, + `{"someOtherParam": "value"}`, +} diff --git a/config/config.go b/config/config.go index 865c422ffb8..224cf85931b 100644 --- a/config/config.go +++ b/config/config.go @@ -917,6 +917,7 @@ func SetupViper(v *viper.Viper, filename string) { v.SetDefault("adapters.kayzen.endpoint", "https://bids-{{.ZoneID}}.bidder.kayzen.io/?exchange={{.AccountID}}") v.SetDefault("adapters.krushmedia.endpoint", "http://ads4.krushmedia.com/?c=rtb&m=req&key={{.AccountID}}") v.SetDefault("adapters.invibes.endpoint", "https://{{.Host}}/bid/ServerBidAdContent") + v.SetDefault("adapters.iqzone.endpoint", "http://smartssp-us-east.iqzone.com/pserver") v.SetDefault("adapters.kidoz.endpoint", "http://prebid-adapter.kidoz.net/openrtb2/auction?src=prebid-server") v.SetDefault("adapters.kubient.endpoint", "https://kssp.kbntx.ch/prebid") v.SetDefault("adapters.lockerdome.endpoint", "https://lockerdome.com/ladbid/prebidserver/openrtb2") diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 7a61a914357..b25cff8c40e 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -62,6 +62,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/iqzone" "github.com/prebid/prebid-server/adapters/ix" "github.com/prebid/prebid-server/adapters/jixie" "github.com/prebid/prebid-server/adapters/kayzen" @@ -189,6 +190,7 @@ 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.BidderIx: ix.Builder, openrtb_ext.BidderJixie: jixie.Builder, openrtb_ext.BidderKayzen: kayzen.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 8e74fcc6db8..79d9abda16e 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -133,6 +133,7 @@ const ( BidderInMobi BidderName = "inmobi" BidderInteractiveoffers BidderName = "interactiveoffers" BidderInvibes BidderName = "invibes" + BidderIQZone BidderName = "iqzone" BidderIx BidderName = "ix" BidderJixie BidderName = "jixie" BidderKayzen BidderName = "kayzen" @@ -260,6 +261,7 @@ func CoreBidderNames() []BidderName { BidderInMobi, BidderInteractiveoffers, BidderInvibes, + BidderIQZone, BidderIx, BidderJixie, BidderKayzen, diff --git a/openrtb_ext/imp_iqzone.go b/openrtb_ext/imp_iqzone.go new file mode 100644 index 00000000000..67a03376067 --- /dev/null +++ b/openrtb_ext/imp_iqzone.go @@ -0,0 +1,5 @@ +package openrtb_ext + +type ImpExtIQZone struct { + PlacementID string `json:"placementId"` +} diff --git a/static/bidder-info/iqzone.yaml b/static/bidder-info/iqzone.yaml new file mode 100644 index 00000000000..254caa8c6e3 --- /dev/null +++ b/static/bidder-info/iqzone.yaml @@ -0,0 +1,15 @@ +maintainer: + email: "smartssp@iqzone.com" +capabilities: + site: + mediaTypes: + - banner + - video + - native + + app: + mediaTypes: + - banner + - video + - native + diff --git a/static/bidder-params/iqzone.json b/static/bidder-params/iqzone.json new file mode 100644 index 00000000000..38e98c53346 --- /dev/null +++ b/static/bidder-params/iqzone.json @@ -0,0 +1,15 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "IQZone Adapter Params", + "description": "A schema which validates params accepted by the IQZone adapter", + "type": "object", + + "properties": { + "placementId": { + "type": "string", + "description": "Placement ID" + } + }, + + "required": ["placementId"] + } \ No newline at end of file diff --git a/usersync/usersyncers/syncer_test.go b/usersync/usersyncers/syncer_test.go index 7eacd086ac3..4a6ffb96c99 100644 --- a/usersync/usersyncers/syncer_test.go +++ b/usersync/usersyncers/syncer_test.go @@ -126,6 +126,7 @@ func TestNewSyncerMap(t *testing.T) { openrtb_ext.BidderEpom: true, openrtb_ext.BidderDecenterAds: true, openrtb_ext.BidderInteractiveoffers: true, + openrtb_ext.BidderIQZone: true, openrtb_ext.BidderKayzen: true, openrtb_ext.BidderKidoz: true, openrtb_ext.BidderKubient: true,