diff --git a/adapters/revx/revx.go b/adapters/revx/revx.go new file mode 100644 index 00000000000..e18c23b5602 --- /dev/null +++ b/adapters/revx/revx.go @@ -0,0 +1,115 @@ +package revx + +import ( + "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" +) + +// RevXAdapter struct +type adapter struct { + endPoint string +} + +// Builder builds a new instance of the RevX adapter. +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + return &adapter{ + endPoint: config.Endpoint, // Default endpoint + }, nil +} + +// MakeRequests handles the OpenRTB bid request and returns адаптер.RequestData +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + var errors []error + + // Build headers + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + headers.Add("Accept", "application/json") + + // Marshal request + reqJson, err := jsonutil.Marshal(request) + if err != nil { + return nil, []error{&errortypes.BadInput{Message: fmt.Sprintf("Failed to marshal request: %s", err)}} // skip append + } + + requestData := &adapters.RequestData{ + Method: http.MethodPost, + Uri: a.endPoint, + Body: reqJson, + Headers: headers, + ImpIDs: openrtb_ext.GetImpIDs(request.Imp), + } + + return []*adapters.RequestData{requestData}, errors +} + +// MakeBids handles the OpenRTB bid response. +func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if externalRequest == nil { + return nil, nil + } + + // Handle specific status codes first + if adapters.IsResponseStatusCodeNoContent(response) { + return nil, nil + } + + // For all other status codes + if err := adapters.CheckResponseStatusCodeForErrors(response); err != nil { + return nil, []error{err} + } + + // Proceed with normal parsing + var serverBidResponse openrtb2.BidResponse + if err := jsonutil.Unmarshal(response.Body, &serverBidResponse); err != nil { + return nil, []error{err} + } + + var typedBids []*adapters.TypedBid + var errs []error + for _, sb := range serverBidResponse.SeatBid { + for i := range sb.Bid { + mediaType, err := getMediaTypeForImp(sb.Bid[i]) + if err != nil { + errs = append(errs, err) + continue + } + typedBids = append(typedBids, &adapters.TypedBid{ + Bid: &sb.Bid[i], + BidType: mediaType, + }) + } + } + + if len(typedBids) == 0 { + return nil, errs + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(typedBids)) + bidResponse.Bids = typedBids + bidResponse.Currency = serverBidResponse.Cur + + return bidResponse, errs +} + +func getMediaTypeForImp(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 "", &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Unsupported mtype %d for bid %s", bid.MType, bid.ID), + } + } +} diff --git a/adapters/revx/revx_external_null_test.go b/adapters/revx/revx_external_null_test.go new file mode 100644 index 00000000000..0b3f5ed32f3 --- /dev/null +++ b/adapters/revx/revx_external_null_test.go @@ -0,0 +1,35 @@ +package revx_test + +import ( + "testing" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/adapters/revx" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/stretchr/testify/assert" +) + +func TestMakeBids_NilExternalRequest(t *testing.T) { + // Arrange + bidder, buildErr := revx.Builder(openrtb_ext.BidderRevX, config.Adapter{ + Endpoint: "prebid-use.atomex.net/ag=PUB123", + }, config.Server{ + ExternalUrl: "http://hosturl.com", + GvlID: 375, + DataCenter: "2", + }) + + var internalReq *openrtb2.BidRequest + var response *adapters.ResponseData + if buildErr != nil { + t.Logf("RevX Builder created successfully: %+v", bidder) + } + // Act + bidderResponse, errs := bidder.MakeBids(internalReq, nil, response) + + // Assert + assert.Nil(t, bidderResponse, "Expected bidderResponse to be nil when externalRequest is nil") + assert.Nil(t, errs, "Expected errors to be nil when externalRequest is nil") +} diff --git a/adapters/revx/revx_test.go b/adapters/revx/revx_test.go new file mode 100644 index 00000000000..68275877cea --- /dev/null +++ b/adapters/revx/revx_test.go @@ -0,0 +1,27 @@ +package revx_test + +import ( + "testing" + + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/adapters/revx" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := revx.Builder(openrtb_ext.BidderRevX, config.Adapter{ + Endpoint: "prebid-use.atomex.net/ag=PUB123", + }, config.Server{ + ExternalUrl: "http://hosturl.com", + GvlID: 375, + DataCenter: "2", + }) + + if buildErr != nil { + + t.Logf("RevX Builder created successfully: %+v", bidder) + } + + adapterstest.RunJSONBidderTest(t, "revxtest", bidder) +} diff --git a/adapters/revx/revxtest/exemplary/simple-app-banner.json b/adapters/revx/revxtest/exemplary/simple-app-banner.json new file mode 100644 index 00000000000..f36257ec3ac --- /dev/null +++ b/adapters/revx/revxtest/exemplary/simple-app-banner.json @@ -0,0 +1,109 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "https://good.site/url" + }, + "imp": [ + { + "id": "imp-id", + "banner": { + "format": [ + { + "w": 111, + "h": 111 + } + ] + }, + "ext": { + "bidder": { + "pubname": "PUB123" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "prebid-use.atomex.net/ag=PUB123", + + "body": { + "id": "test-request-id", + "site": { + "page": "https://good.site/url" + }, + "imp": [ + { + "id": "imp-id", + "banner": { + "format": [ + { + "w": 111, + "h": 111 + } + ] + }, + "ext": { + "bidder": { + "pubname": "PUB123" + } + } + } + ] + }, + "impIDs": [ + "imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "interactiveoffers", + "bid": [ + { + "id": "randomid", + "impid": "imp-id", + "price": 0.5, + "adid": "12345678", + "adm": "some-test-ad", + "cid": "987", + "crid": "12345678", + "h": 111, + "w": 111, + "mtype": 1 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "randomid", + "impid": "imp-id", + "price": 0.5, + "adm": "some-test-ad", + "adid": "12345678", + "cid": "987", + "crid": "12345678", + "w": 111, + "h": 111, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/revx/revxtest/exemplary/simple-app-native.json b/adapters/revx/revxtest/exemplary/simple-app-native.json new file mode 100644 index 00000000000..81c77915a25 --- /dev/null +++ b/adapters/revx/revxtest/exemplary/simple-app-native.json @@ -0,0 +1,99 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "publisher": { + "name": "PUB123" + } + }, + "imp": [ + { + "id": "imp-id", + "native": { + "request": "{\"native\":{\"ver\":\"1.2\",\"api\":[1],\"battr\":[1,3,9],\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":25}},{\"id\":1,\"required\":1,\"img\":{\"type\":3,\"wmin\":100,\"hmin\":50}},{\"id\":2,\"required\":0,\"data\":{\"type\":2,\"len\":200}},{\"id\":3,\"required\":0,\"data\":{\"type\":12}},{\"id\":4,\"required\":0,\"data\":{\"type\":1}}]}}" + }, + "ext": { + "bidder": { + "pubname": "PUB123" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "prebid-use.atomex.net/ag=PUB123", + "body": { + "id": "test-request-id", + "app": { + "publisher": { + "name": "PUB123" + } + }, + "imp": [ + { + "id": "imp-id", + "native": { + "request": "{\"native\":{\"ver\":\"1.2\",\"api\":[1],\"battr\":[1,3,9],\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":25}},{\"id\":1,\"required\":1,\"img\":{\"type\":3,\"wmin\":100,\"hmin\":50}},{\"id\":2,\"required\":0,\"data\":{\"type\":2,\"len\":200}},{\"id\":3,\"required\":0,\"data\":{\"type\":12}},{\"id\":4,\"required\":0,\"data\":{\"type\":1}}]}}" + }, + "ext": { + "bidder": { + "pubname": "PUB123" + } + } + } + ] + }, + "impIDs": [ + "imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "interactiveoffers", + "bid": [ + { + "id": "randomid", + "impid": "imp-id", + "price": 0.5, + "adid": "12345678", + "adm": "{\"native\":{\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"title\":{\"text\":\"Test Title\"}},{\"id\":1,\"img\":{\"url\":\"http://some.image.url\",\"w\":100,\"h\":50}},{\"id\":2,\"data\":{\"type\":2,\"value\":\"Test Body\"}},{\"id\":3,\"data\":{\"type\":12,\"value\":\"Test Sponsored\"}},{\"id\":4,\"data\":{\"type\":1,\"value\":\"Test Display URL\"}}],\"link\":{\"url\":\"http://click.url\"},\"imptrackers\":[\"http://impression.url\"]}}", + "cid": "987", + "crid": "12345678", + "mtype": 4 + + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "randomid", + "impid": "imp-id", + "price": 0.5, + "adm": "{\"native\":{\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"title\":{\"text\":\"Test Title\"}},{\"id\":1,\"img\":{\"url\":\"http://some.image.url\",\"w\":100,\"h\":50}},{\"id\":2,\"data\":{\"type\":2,\"value\":\"Test Body\"}},{\"id\":3,\"data\":{\"type\":12,\"value\":\"Test Sponsored\"}},{\"id\":4,\"data\":{\"type\":1,\"value\":\"Test Display URL\"}}],\"link\":{\"url\":\"http://click.url\"},\"imptrackers\":[\"http://impression.url\"]}}", + "adid": "12345678", + "cid": "987", + "crid": "12345678", + "mtype": 4 + }, + "type": "native" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/revx/revxtest/exemplary/simple-app-video.json b/adapters/revx/revxtest/exemplary/simple-app-video.json new file mode 100644 index 00000000000..6db4f7abcf9 --- /dev/null +++ b/adapters/revx/revxtest/exemplary/simple-app-video.json @@ -0,0 +1,122 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "publisher": { + "name": "PUB123" + } + }, + "imp": [ + { + "id": "imp-id", + "video": { + "mimes": [ + "application/x-mpegURL", + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 640, + "h": 480, + "placement": 1 + }, + "ext": { + "bidder": { + "pubname": "PUB123" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "prebid-use.atomex.net/ag=PUB123", + "body": { + "id": "test-request-id", + "app": { + "publisher": { + "name": "PUB123" + } + }, + "imp": [ + { + "id": "imp-id", + "video": { + "mimes": [ + "application/x-mpegURL", + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 640, + "h": 480, + "placement": 1 + }, + "ext": { + "bidder": { + "pubname": "PUB123" + } + } + } + ] + }, + "impIDs": [ + "imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "interactiveoffers", + "bid": [ + { + "id": "randomid", + "impid": "imp-id", + "price": 0.5, + "adid": "12345678", + "adm": "", + "cid": "987", + "crid": "12345678", + "w": 640, + "h": 480, + "mtype": 2 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "randomid", + "impid": "imp-id", + "price": 0.5, + "adm": "", + "adid": "12345678", + "cid": "987", + "crid": "12345678", + "w": 640, + "h": 480, + "mtype": 2 + }, + "type": "video" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/revx/revxtest/exemplary/simple-web-banner.json b/adapters/revx/revxtest/exemplary/simple-web-banner.json new file mode 100644 index 00000000000..58ea9fb30ba --- /dev/null +++ b/adapters/revx/revxtest/exemplary/simple-web-banner.json @@ -0,0 +1,108 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "https://good.site/url" + }, + "imp": [ + { + "id": "imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "pubname": "PUB123" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "prebid-use.atomex.net/ag=PUB123", + "body": { + "id": "test-request-id", + "site": { + "page": "https://good.site/url" + }, + "imp": [ + { + "id": "imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "pubname": "PUB123" + } + } + } + ] + }, + "impIDs": [ + "imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "interactiveoffers", + "bid": [ + { + "id": "randomid", + "impid": "imp-id", + "price": 0.5, + "adid": "12345678", + "adm": "
", + "cid": "987", + "crid": "12345678", + "h": 250, + "w": 300, + "mtype": 1 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "randomid", + "impid": "imp-id", + "price": 0.5, + "adm": "
", + "adid": "12345678", + "cid": "987", + "crid": "12345678", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/revx/revxtest/exemplary/simple-web-native.json b/adapters/revx/revxtest/exemplary/simple-web-native.json new file mode 100644 index 00000000000..7fce0930585 --- /dev/null +++ b/adapters/revx/revxtest/exemplary/simple-web-native.json @@ -0,0 +1,94 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "https://good.site/url" + }, + "imp": [ + { + "id": "imp-id", + "native": { + "request": "{\"native\":{\"ver\":\"1.2\",\"api\":[1],\"battr\":[1,3,9],\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":25}},{\"id\":1,\"required\":1,\"img\":{\"type\":3,\"wmin\":100,\"hmin\":50}},{\"id\":2,\"required\":0,\"data\":{\"type\":2,\"len\":200}},{\"id\":3,\"required\":0,\"data\":{\"type\":12}},{\"id\":4,\"required\":0,\"data\":{\"type\":1}}]}}" + }, + "ext": { + "bidder": { + "pubname": "PUB123" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "prebid-use.atomex.net/ag=PUB123", + "body": { + "id": "test-request-id", + "site": { + "page": "https://good.site/url" + }, + "imp": [ + { + "id": "imp-id", + "native": { + "request": "{\"native\":{\"ver\":\"1.2\",\"api\":[1],\"battr\":[1,3,9],\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":25}},{\"id\":1,\"required\":1,\"img\":{\"type\":3,\"wmin\":100,\"hmin\":50}},{\"id\":2,\"required\":0,\"data\":{\"type\":2,\"len\":200}},{\"id\":3,\"required\":0,\"data\":{\"type\":12}},{\"id\":4,\"required\":0,\"data\":{\"type\":1}}]}}" + }, + "ext": { + "bidder": { + "pubname": "PUB123" + } + } + } + ] + }, + "impIDs": [ + "imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "interactiveoffers", + "bid": [ + { + "id": "randomid", + "impid": "imp-id", + "price": 0.5, + "adid": "12345678", + "adm": "{\"native\":{\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"title\":{\"text\":\"Test Title\"}},{\"id\":1,\"img\":{\"url\":\"http://some.image.url\",\"w\":100,\"h\":50}},{\"id\":2,\"data\":{\"type\":2,\"value\":\"Test Body\"}},{\"id\":3,\"data\":{\"type\":12,\"value\":\"Test Sponsored\"}},{\"id\":4,\"data\":{\"type\":1,\"value\":\"Test Display URL\"}}],\"link\":{\"url\":\"http://click.url\"},\"imptrackers\":[\"http://impression.url\"]}}", + "cid": "987", + "crid": "12345678", + "mtype": 4 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "randomid", + "impid": "imp-id", + "price": 0.5, + "adm": "{\"native\":{\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"title\":{\"text\":\"Test Title\"}},{\"id\":1,\"img\":{\"url\":\"http://some.image.url\",\"w\":100,\"h\":50}},{\"id\":2,\"data\":{\"type\":2,\"value\":\"Test Body\"}},{\"id\":3,\"data\":{\"type\":12,\"value\":\"Test Sponsored\"}},{\"id\":4,\"data\":{\"type\":1,\"value\":\"Test Display URL\"}}],\"link\":{\"url\":\"http://click.url\"},\"imptrackers\":[\"http://impression.url\"]}}", + "adid": "12345678", + "cid": "987", + "crid": "12345678", + "mtype": 4 + }, + "type": "native" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/revx/revxtest/exemplary/simple-web-video.json b/adapters/revx/revxtest/exemplary/simple-web-video.json new file mode 100644 index 00000000000..0b397138693 --- /dev/null +++ b/adapters/revx/revxtest/exemplary/simple-web-video.json @@ -0,0 +1,118 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "https://good.site/url" + }, + "imp": [ + { + "id": "imp-id", + "video": { + "mimes": [ + "application/x-mpegURL", + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 800, + "h": 600, + "placement": 1 + }, + "ext": { + "bidder": { + "pubname": "PUB123" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "prebid-use.atomex.net/ag=PUB123", + "body": { + "id": "test-request-id", + "site": { + "page": "https://good.site/url" + }, + "imp": [ + { + "id": "imp-id", + "video": { + "mimes": [ + "application/x-mpegURL", + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 800, + "h": 600, + "placement": 1 + }, + "ext": { + "bidder": { + "pubname": "PUB123" + } + } + } + ] + }, + "impIDs": [ + "imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "interactiveoffers", + "bid": [ + { + "id": "randomid", + "impid": "imp-id", + "price": 0.5, + "adid": "12345678", + "adm": "", + "cid": "987", + "crid": "12345678", + "w": 800, + "h": 600, + "mtype": 2 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "randomid", + "impid": "imp-id", + "price": 0.5, + "adm": "", + "adid": "12345678", + "cid": "987", + "crid": "12345678", + "w": 800, + "h": 600, + "mtype": 2 + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/revx/revxtest/supplemental/204Response.json b/adapters/revx/revxtest/supplemental/204Response.json new file mode 100644 index 00000000000..bbfab997069 --- /dev/null +++ b/adapters/revx/revxtest/supplemental/204Response.json @@ -0,0 +1,65 @@ +{ + "mockBidRequest": { + "app": { + "bundle": "com.example.app" + }, + "id": "req-id", + "device": { + "ifa": "9d8fe0a9-c0dd-4482-b16b-5709b00c608d", + "ip": "1.1.1.1", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G960F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36" + }, + "imp": [ + { + "ext": { + "bidder": { + "pubname": "PUB123" + } + }, + "banner": { + "w": 111, + "h": 111 + }, + "id": "imp-id" + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "prebid-use.atomex.net/ag=PUB123", + "body": { + "app": { + "bundle": "com.example.app" + }, + "id": "req-id", + "device": { + "ifa": "9d8fe0a9-c0dd-4482-b16b-5709b00c608d", + "ip": "1.1.1.1", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G960F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36" + }, + "imp": [ + { + "ext": { + "bidder": { + "pubname": "PUB123" + } + }, + "banner": { + "w": 111, + "h": 111 + }, + "id": "imp-id" + } + ] + }, + "impIDs": ["imp-id"] + }, + "mockResponse": { + "status": 204, + "body": {} + } + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/revx/revxtest/supplemental/400Response.json b/adapters/revx/revxtest/supplemental/400Response.json new file mode 100644 index 00000000000..2d3785503e7 --- /dev/null +++ b/adapters/revx/revxtest/supplemental/400Response.json @@ -0,0 +1,71 @@ +{ + "mockBidRequest": { + "app": { + "bundle": "com.example.app" + }, + "id": "req-id", + "device": { + "ifa": "9d8fe0a9-c0dd-4482-b16b-5709b00c608d", + "ip": "1.1.1.1", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G960F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36" + }, + "imp": [ + { + "ext": { + "bidder": { + "pubname": "PUB123" + } + }, + "banner": { + "w": 111, + "h": 111 + }, + "id": "imp-id" + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "prebid-use.atomex.net/ag=PUB123", + "body": { + "app": { + "bundle": "com.example.app" + }, + "id": "req-id", + "device": { + "ifa": "9d8fe0a9-c0dd-4482-b16b-5709b00c608d", + "ip": "1.1.1.1", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G960F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36" + }, + "imp": [ + { + "ext": { + "bidder": { + "pubname": "PUB123" + } + }, + "banner": { + "w": 111, + "h": 111 + }, + "id": "imp-id" + } + ] + }, + "impIDs": ["imp-id"] + }, + "mockResponse": { + "status": 400, + "body": "Invalid Request" + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} diff --git a/adapters/revx/revxtest/supplemental/500Response.json b/adapters/revx/revxtest/supplemental/500Response.json new file mode 100644 index 00000000000..64ed16db8df --- /dev/null +++ b/adapters/revx/revxtest/supplemental/500Response.json @@ -0,0 +1,71 @@ +{ + "mockBidRequest": { + "app": { + "bundle": "com.example.app" + }, + "id": "req-id", + "device": { + "ifa": "9d8fe0a9-c0dd-4482-b16b-5709b00c608d", + "ip": "1.1.1.1", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G960F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36" + }, + "imp": [ + { + "ext": { + "bidder": { + "pubname": "PUB123" + } + }, + "banner": { + "w": 111, + "h": 111 + }, + "id": "imp-id" + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "prebid-use.atomex.net/ag=PUB123", + "body": { + "app": { + "bundle": "com.example.app" + }, + "id": "req-id", + "device": { + "ifa": "9d8fe0a9-c0dd-4482-b16b-5709b00c608d", + "ip": "1.1.1.1", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G960F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36" + }, + "imp": [ + { + "ext": { + "bidder": { + "pubname": "PUB123" + } + }, + "banner": { + "w": 111, + "h": 111 + }, + "id": "imp-id" + } + ] + }, + "impIDs": ["imp-id"] + }, + "mockResponse": { + "status": 500, + "body": "Invalid Request" + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 500. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} diff --git a/adapters/revx/revxtest/supplemental/invalid-mtype.json b/adapters/revx/revxtest/supplemental/invalid-mtype.json new file mode 100644 index 00000000000..cfad8d4914c --- /dev/null +++ b/adapters/revx/revxtest/supplemental/invalid-mtype.json @@ -0,0 +1,94 @@ +{ + "mockBidRequest": { + "site": { + "page": "https://www.revx.io" + }, + "id": "req-id", + "device": { + "ip": "1.1.1.1", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G960F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36" + }, + "imp": [ + { + "ext": { + "bidder": { + "pubname": "PUB123" + } + }, + "video": { + "w": 640, + "h": 360, + "mimes": ["video/mp4"] + }, + "id": "imp-id" + } + ] + }, + "httpCalls": [{ + "expectedRequest": { + "uri":"prebid-use.atomex.net/ag=PUB123", + "body": { + "site": { + "page": "https://www.revx.io" + }, + "id": "req-id", + "device": { + "ip": "1.1.1.1", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G960F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36" + }, + "imp": [ + { + "ext": { + "bidder": { + "pubname": "PUB123" + } + }, + "video": { + "w": 640, + "h": 360, + "mimes": ["video/mp4"] + }, + "id": "imp-id" + } + ] + }, + "impIDs": ["imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "req-id", + "seatbid": [ + { + "bid": [ + { + "id": "1234", + "impid": "imp-id", + "price": 2.0, + "adm": "", + "crid": "123456789", + "adomain": ["example.com"], + "nurl": "https://tracking.url.com/event", + "mtype": 0, + "ext": { + "prebid": { + "meta": { + "networkName": "revx" + } + } + } + } + ] + } + ] + } + } + }], + "expectedBidResponses":[], + "expectedMakeBidsErrors":[ + { + "value":"Unsupported mtype 0 for bid 1234", + "comparison":"literal" + } + ] +} \ No newline at end of file diff --git a/adapters/revx/revxtest/supplemental/response_unmarshal_error.json b/adapters/revx/revxtest/supplemental/response_unmarshal_error.json new file mode 100644 index 00000000000..9cf5b5322ca --- /dev/null +++ b/adapters/revx/revxtest/supplemental/response_unmarshal_error.json @@ -0,0 +1,72 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "https://good.site/url" + }, + "imp": [ + { + "id": "imp-id", + "banner": { + "format": [ + { + "w": 111, + "h": 111 + } + ] + }, + "ext": { + "bidder": { + "pubname": "PUB123" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "prebid-use.atomex.net/ag=PUB123", + + "body": { + "id": "test-request-id", + "site": { + "page": "https://good.site/url" + }, + "imp": [ + { + "id": "imp-id", + "banner": { + "format": [ + { + "w": 111, + "h": 111 + } + ] + }, + "ext": { + "bidder": { + "pubname": "PUB123" + } + } + } + ] + }, + "impIDs": [ + "imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": "incorrect response body" + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "expect { or n, but found \"", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 87821fd0c75..3993515df59 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -182,6 +182,7 @@ import ( "github.com/prebid/prebid-server/v3/adapters/relevantdigital" "github.com/prebid/prebid-server/v3/adapters/resetdigital" "github.com/prebid/prebid-server/v3/adapters/revcontent" + "github.com/prebid/prebid-server/v3/adapters/revx" "github.com/prebid/prebid-server/v3/adapters/richaudience" "github.com/prebid/prebid-server/v3/adapters/rise" "github.com/prebid/prebid-server/v3/adapters/roulax" @@ -434,6 +435,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderRelevantDigital: relevantdigital.Builder, openrtb_ext.BidderResetDigital: resetdigital.Builder, openrtb_ext.BidderRevcontent: revcontent.Builder, + openrtb_ext.BidderRevX: revx.Builder, openrtb_ext.BidderRichaudience: richaudience.Builder, openrtb_ext.BidderRise: rise.Builder, openrtb_ext.BidderRoulax: roulax.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 67cf8e7c15e..efc734ea29c 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -200,6 +200,7 @@ var coreBidderNames []BidderName = []BidderName{ BidderRelevantDigital, BidderResetDigital, BidderRevcontent, + BidderRevX, BidderRichaudience, BidderRise, BidderRoulax, @@ -556,6 +557,7 @@ const ( BidderRelevantDigital BidderName = "relevantdigital" BidderResetDigital BidderName = "resetdigital" BidderRevcontent BidderName = "revcontent" + BidderRevX BidderName = "revx" BidderRichaudience BidderName = "richaudience" BidderRise BidderName = "rise" BidderRoulax BidderName = "roulax" diff --git a/static/bidder-info/revx.yaml b/static/bidder-info/revx.yaml new file mode 100644 index 00000000000..cf745dd1b9f --- /dev/null +++ b/static/bidder-info/revx.yaml @@ -0,0 +1,15 @@ +endpoint: "https://prebid-use.atomex.net?ag=PREBID" +maintainer: + email: prebidsupport@revx.io +gvlVendorID: 375 +capabilities: + app: + mediaTypes: + - banner + - video + - native + site: + mediaTypes: + - banner + - video + - native \ No newline at end of file diff --git a/static/bidder-params/revx.json b/static/bidder-params/revx.json new file mode 100644 index 00000000000..7ed0ec5ea3f --- /dev/null +++ b/static/bidder-params/revx.json @@ -0,0 +1,7 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "RevX Adapter Params", + "description": "A schema which validates params accepted by the RevX adapter", + "type": "object", + "properties": {} +}