Skip to content

Commit

Permalink
Update adot adapter
Browse files Browse the repository at this point in the history
  • Loading branch information
Giudici-a committed Dec 16, 2020
1 parent 1921164 commit 2344c6c
Show file tree
Hide file tree
Showing 20 changed files with 610 additions and 868 deletions.
151 changes: 39 additions & 112 deletions adapters/adot/adot.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,45 +3,42 @@ package adot
import (
"encoding/json"
"fmt"
"github.com/buger/jsonparser"
"github.com/prebid/prebid-server/config"
"net/http"
"net/url"
"strconv"

"github.com/mxmCherry/openrtb"
"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"
"net/http"
)

type AdotAdapter struct {
type adapter struct {
endpoint string
}

// NewGridBidder configure bidder endpoint
func Builder(bidderName openrtb_ext.BidderName, config config.Adapter) (adapters.Bidder, error) {
_, err := url.ParseRequestURI(config.Endpoint)
if len(config.Endpoint) > 0 && err != nil {
return nil, fmt.Errorf("unable to parse endpoint url: %v", err)
}
type adotBidExt struct {
Adot bidExt `json:"adot"`
}

bidder := &AdotAdapter{
type bidExt struct {
MediaType string `json:"media_type"`
}

// Builder builds a new instance of the Adot adapter for the given bidder with the given config.
func Builder(bidderName openrtb_ext.BidderName, config config.Adapter) (adapters.Bidder, error) {
bidder := &adapter{
endpoint: config.Endpoint,
}
return bidder, nil
}

// MakeRequests makes the HTTP requests which should be made to fetch bids.
func (a *AdotAdapter) MakeRequests(request *openrtb.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
var errors = make([]error, 0)
func (a *adapter) MakeRequests(request *openrtb.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
var reqJSON []byte
var err error

reqJSON, err := json.Marshal(request)
if err != nil {
errors = append(errors, err)
return nil, errors
if reqJSON, err = json.Marshal(request); err != nil {
return nil, []error{fmt.Errorf("unable to marshal openrtb request (%v)", err)}
}
reqJSON = addParallaxIfNecessary(reqJSON)

headers := http.Header{}
headers.Add("Content-Type", "application/json;charset=utf-8")
Expand All @@ -51,11 +48,12 @@ func (a *AdotAdapter) MakeRequests(request *openrtb.BidRequest, reqInfo *adapter
Uri: a.endpoint,
Body: reqJSON,
Headers: headers,
}}, errors
}}, nil
}

// MakeBids unpacks the server's response into Bids.
func (a *AdotAdapter) MakeBids(internalRequest *openrtb.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) {
// The bidder return a status code 204 when it cannot delivery an ad.
func (a *adapter) MakeBids(internalRequest *openrtb.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) {
if response.StatusCode == http.StatusNoContent {
return nil, nil
}
Expand All @@ -77,114 +75,43 @@ func (a *AdotAdapter) MakeBids(internalRequest *openrtb.BidRequest, externalRequ
return nil, []error{err}
}

bidResponse := adapters.NewBidderResponseWithBidsCapacity(1)
bidsCapacity := 1
if len(bidResp.SeatBid) > 0 {
bidsCapacity = len(bidResp.SeatBid[0].Bid)
}
bidResponse := adapters.NewBidderResponseWithBidsCapacity(bidsCapacity)

for _, sb := range bidResp.SeatBid {
for i := range sb.Bid {
if bidType, err := getMediaTypeForBid(&sb.Bid[i], internalRequest); err == nil {
if bidType, err := getMediaTypeForBid(&sb.Bid[i]); err == nil {
bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{
Bid: &sb.Bid[i],
BidType: bidType,
})
}
}
}
return bidResponse, nil

return bidResponse, nil
}

// getMediaTypeForBid determines which type of bid.
func getMediaTypeForBid(bid *openrtb.Bid, internalRequest *openrtb.BidRequest) (openrtb_ext.BidType, error) {
if bid == nil || internalRequest == nil {
func getMediaTypeForBid(bid *openrtb.Bid) (openrtb_ext.BidType, error) {
if bid == nil {
return "", fmt.Errorf("the bid request object is nil")
}

impID := bid.ImpID

for _, imp := range internalRequest.Imp {
if imp.ID == impID {
if imp.Banner != nil {
return openrtb_ext.BidTypeBanner, nil
} else if imp.Video != nil {
return openrtb_ext.BidTypeVideo, nil
} else if imp.Audio != nil {
return openrtb_ext.BidTypeAudio, nil
} else if imp.Native != nil {
return openrtb_ext.BidTypeNative, nil
}
var impExt adotBidExt
if err := json.Unmarshal(bid.Ext, &impExt); err == nil {
switch impExt.Adot.MediaType {
case string(openrtb_ext.BidTypeBanner):
return openrtb_ext.BidTypeBanner, nil
case string(openrtb_ext.BidTypeVideo):
return openrtb_ext.BidTypeVideo, nil
case string(openrtb_ext.BidTypeNative):
return openrtb_ext.BidTypeNative, nil
}
}

return "", fmt.Errorf("unrecognized bid type in response from adot")
}

func addParallaxIfNecessary(reqJSON []byte) []byte {
var adotJSON []byte
var err error

adotRequest, parallaxError := addParallaxInRequest(reqJSON)
if parallaxError == nil {
adotJSON, err = json.Marshal(adotRequest)
if err != nil {
adotJSON = reqJSON
}
} else {
adotJSON = reqJSON
}

return adotJSON
}

func addParallaxInRequest(data []byte) (map[string]interface{}, error) {
var adotRequest map[string]interface{}

if err := json.Unmarshal(data, &adotRequest); err != nil {
return adotRequest, err
}

imps := adotRequest["imp"].([]interface{})
for i, impObj := range imps {
castedImps := impObj.(map[string]interface{})
if isParallaxInExt(castedImps) {
if impByte, err := json.Marshal(impObj); err == nil {
if val, err := jsonparser.Set(impByte, jsonparser.StringToBytes(strconv.FormatBool(true)), "banner", "parallax"); err == nil {
_ = json.Unmarshal(val, &imps[i])
}
}
}
}
return adotRequest, nil
}

func isParallaxInExt(impObj map[string]interface{}) bool {
isParallaxInExt := false

isParallaxByte, err := getParallaxByte(impObj)
if err == nil {
isParallaxInt, err := jsonparser.GetInt(isParallaxByte)
if err != nil {
isParallaxBool, err := jsonparser.GetBoolean(isParallaxByte)
if err == nil {
return isParallaxBool
}
}
isParallaxInExt = isParallaxInt == 1
}

return isParallaxInExt
}

func getParallaxByte(impObj map[string]interface{}) ([]byte, error) {
impByte, err := json.Marshal(impObj)
if err != nil {
return nil, err
}

isExtByte, _, _, err := jsonparser.Get(impByte, "ext")
if err != nil {
return nil, err
}

isParallaxByte, _, _, err := jsonparser.Get(isExtByte, "bidder", "parallax")
return isParallaxByte, err
}
117 changes: 34 additions & 83 deletions adapters/adot/adot_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,20 @@ package adot

import (
"encoding/json"
"fmt"
"github.com/mxmCherry/openrtb"
"github.com/prebid/prebid-server/adapters"
"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"
"io/ioutil"
"strings"
"testing"
)

var jsonBidReq = getJsonByteForTesting("./static/adapter/adot/parallax_request_test.json")

func getJsonByteForTesting(path string) []byte {
jsonBidReq, err := ioutil.ReadFile(path)
if err != nil {
fmt.Println("File reading error", err)
return nil
}

return jsonBidReq
}
const testsBidderEndpoint = "https://dsp.adotmob.com/headerbidding/bidrequest"

func TestJsonSamples(t *testing.T) {
bidder, buildErr := Builder(openrtb_ext.BidderAdot, config.Adapter{
Endpoint: "https://dsp.adotmob.com/headerbidding/bidrequest"})
Endpoint: testsBidderEndpoint})

if buildErr != nil {
t.Fatalf("Builder returned unexpected error %v", buildErr)
Expand All @@ -36,90 +24,53 @@ func TestJsonSamples(t *testing.T) {
adapterstest.RunJSONBidderTest(t, "adottest", bidder)
}

func TestEndpoint(t *testing.T) {
_, buildErr := Builder(openrtb_ext.BidderAdot, config.Adapter{
Endpoint: "wrongurl."})

assert.Error(t, buildErr)
}

// Test the request with the parallax parameter
func TestRequestWithParallax(t *testing.T) {
var bidReq *openrtb.BidRequest
if err := json.Unmarshal(jsonBidReq, &bidReq); err != nil {
fmt.Println("error: ", err.Error())
}

reqJSON, err := json.Marshal(bidReq)
if err != nil {
t.Errorf("The request should not be the same, because their is a parallax param in ext.")
}
//Test the media type error
func TestMediaTypeError(t *testing.T) {
_, err := getMediaTypeForBid(nil)

adotJson := addParallaxIfNecessary(reqJSON)
stringReqJSON := string(adotJson)
assert.Error(t, err)

if stringReqJSON == string(reqJSON) {
t.Errorf("The request should not be the same, because their is a parallax param in ext.")
}
byteInvalid, _ := json.Marshal(&adotBidExt{Adot: bidExt{"invalid"}})
_, err = getMediaTypeForBid(&openrtb.Bid{Ext: json.RawMessage(byteInvalid)})

if strings.Count(stringReqJSON, "parallax: true") == 2 {
t.Errorf("The parallax was not well add in the request")
}
assert.Error(t, err)
}

// Test the request without the parallax parameter
func TestRequestWithoutParallax(t *testing.T) {
stringBidReq := strings.Replace(string(jsonBidReq), "\"parallax\": true", "", -1)
jsonReq := []byte(stringBidReq)

reqJSON := addParallaxIfNecessary(jsonReq)
//Test the bid response when the bidder return a status code 204
func TestBidResponseNoContent(t *testing.T) {
bidder, buildErr := Builder(openrtb_ext.BidderAdot, config.Adapter{
Endpoint: "https://dsp.adotmob.com/headerbidding/bidrequest"})

if strings.Contains(string(reqJSON), "parallax") {
t.Errorf("The request should not contains parallax param " + string(reqJSON))
if buildErr != nil {
t.Fatalf("Builder returned unexpected error %v", buildErr)
}
}

// Test the parallax with an invalid request
func TestParallaxWithInvalidRequest(t *testing.T) {
test := map[string]interface{}(nil)

_, err := getParallaxByte(test)

assert.Error(t, err)
}

//Test the media type error
func TestMediaTypeError(t *testing.T) {
_, err := getMediaTypeForBid(nil, nil)

assert.Error(t, err)
bidResponse, err := bidder.MakeBids(nil, nil, &adapters.ResponseData{StatusCode: 204})
if bidResponse != nil {
t.Fatalf("the bid response should be nil since the bidder status is No Content")
} else if err != nil {
t.Fatalf("the error should be nil since the bidder status is 204 : No Content")
}
}

//Test the media type for a bid response
func TestMediaTypeForBid(t *testing.T) {
_, err := getMediaTypeForBid(nil, nil)

assert.Error(t, err)

var reqBanner, reqVideo *openrtb.BidRequest
var bidBanner, bidVideo *openrtb.Bid

err1 := json.Unmarshal(getJsonByteForTesting("./static/adapter/adot/parallax_request_test.json"), &reqBanner)
err2 := json.Unmarshal(getJsonByteForTesting("./static/adapter/adot/parallax_response_test.json"), &bidBanner)
err3 := json.Unmarshal(getJsonByteForTesting("./static/adapter/adot/video_request_test.json"), &reqVideo)
err4 := json.Unmarshal(getJsonByteForTesting("./static/adapter/adot/video_request_test.json"), &bidVideo)
byteBanner, _ := json.Marshal(&adotBidExt{Adot: bidExt{"banner"}})
byteVideo, _ := json.Marshal(&adotBidExt{Adot: bidExt{"video"}})
byteNative, _ := json.Marshal(&adotBidExt{Adot: bidExt{"native"}})

if err1 != nil || err2 != nil || err3 != nil || err4 != nil {
fmt.Println("error: ", "cannot unmarshal well")
bidTypeBanner, _ := getMediaTypeForBid(&openrtb.Bid{Ext: json.RawMessage(byteBanner)})
if bidTypeBanner != openrtb_ext.BidTypeBanner {
t.Errorf("the type is not the valid one. actual: %v, expected: %v", bidTypeBanner, openrtb_ext.BidTypeBanner)
}

bidType, err := getMediaTypeForBid(bidBanner, reqBanner)
if bidType == openrtb_ext.BidTypeBanner {
t.Errorf("the type is not the valid one. actual: %v, expected: %v", bidType, openrtb_ext.BidTypeBanner)
bidTypeVideo, _ := getMediaTypeForBid(&openrtb.Bid{Ext: json.RawMessage(byteVideo)})
if bidTypeVideo != openrtb_ext.BidTypeVideo {
t.Errorf("the type is not the valid one. actual: %v, expected: %v", bidTypeVideo, openrtb_ext.BidTypeVideo)
}

bidType2, _ := getMediaTypeForBid(bidVideo, reqVideo)
if bidType2 == openrtb_ext.BidTypeVideo {
t.Errorf("the type is not the valid one. actual: %v, expected: %v", bidType2, openrtb_ext.BidTypeVideo)
bidTypeNative, _ := getMediaTypeForBid(&openrtb.Bid{Ext: json.RawMessage(byteNative)})
if bidTypeNative != openrtb_ext.BidTypeNative {
t.Errorf("the type is not the valid one. actual: %v, expected: %v", bidTypeNative, openrtb_ext.BidTypeVideo)
}
}
Loading

0 comments on commit 2344c6c

Please sign in to comment.