Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Adapter: Mediasquare #3994

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open
124 changes: 124 additions & 0 deletions adapters/mediasquare/mediasquare.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package mediasquare

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"
)

type adapter struct {
endpoint string
}

func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) {
return &adapter{
endpoint: config.Endpoint,
}, nil
}

func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
var (
requestData []*adapters.RequestData
errs []error
)
if request == nil || request.Imp == nil {
errs = append(errs, errorWritter("<MakeRequests> request", nil, true))
return nil, errs
}

msqParams := initMsqParams(request)
msqParams.Test = (request.Test == int8(1))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't seen this behavior before. Is this added because the msqParams.Test field is required by the MediaSquare backend to recognize the request as a test?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it is.

for _, imp := range request.Imp {
var (
bidderExt adapters.ExtImpBidder
msqExt openrtb_ext.ImpExtMediasquare
currentCode = msqParametersCodes{
AdUnit: imp.TagID,
AuctionId: request.ID,
BidId: imp.ID,
}
)

if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil {
errs = append(errs, errorWritter("<MakeRequests> imp[ext]", err, len(imp.Ext) == 0))
continue
}
if err := jsonutil.Unmarshal(bidderExt.Bidder, &msqExt); err != nil {
errs = append(errs, errorWritter("<MakeRequests> imp-bidder[ext]", err, len(bidderExt.Bidder) == 0))
continue
}
currentCode.Owner = msqExt.Owner
currentCode.Code = msqExt.Code

if ok := currentCode.setContent(imp); ok {
msqParams.Codes = append(msqParams.Codes, currentCode)
}
}

req, err := a.makeRequest(request, &msqParams)
if err != nil {
errs = append(errs, err)
} else if req != nil {
requestData = append(requestData, req)
}
return requestData, errs
}

func (a *adapter) makeRequest(request *openrtb2.BidRequest, msqParams *msqParameters) (requestData *adapters.RequestData, err error) {
var requestJsonBytes []byte
if msqParams == nil {
err = errorWritter("<makeRequest> msqParams", nil, true)
return
}
if requestJsonBytes, err = jsonutil.Marshal(msqParams); err == nil {
var headers http.Header = headerList
requestData = &adapters.RequestData{
Method: "POST",
Uri: a.endpoint,
Body: requestJsonBytes,
Headers: headers,
ImpIDs: openrtb_ext.GetImpIDs(request.Imp),
}
} else {
err = errorWritter("<makeRequest> jsonutil.Marshal", err, false)
}

return
}

func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) {
var (
bidderResponse *adapters.BidderResponse
errs []error
)
if response.StatusCode != http.StatusOK {
switch response.StatusCode {
case http.StatusBadRequest:
errs = []error{&errortypes.BadInput{Message: fmt.Sprintf("<MakeBids> Unexpected status code: %d.", response.StatusCode)}}
default:
errs = []error{&errortypes.BadServerResponse{
Message: fmt.Sprintf("<MakeBids> Unexpected status code: %d. Run with request.debug = 1 for more info.", response.StatusCode),
}}
}
return bidderResponse, errs
}

var msqResp msqResponse
if err := jsonutil.Unmarshal(response.Body, &msqResp); err != nil {
errs = []error{&errortypes.BadServerResponse{
Message: fmt.Sprintf("<MakeBids> Unexprected status code: %d. Bad server response: %s.",
http.StatusNotAcceptable, err.Error())},
}
return bidderResponse, errs
}
bidderResponse = adapters.NewBidderResponseWithBidsCapacity(len(request.Imp))
msqResp.getContent(bidderResponse)

return bidderResponse, errs
}
44 changes: 44 additions & 0 deletions adapters/mediasquare/mediasquare_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package mediasquare

import (
"testing"

"github.com/prebid/openrtb/v20/openrtb2"
"github.com/prebid/prebid-server/v3/adapters"
"github.com/prebid/prebid-server/v3/adapters/adapterstest"
"github.com/prebid/prebid-server/v3/config"
"github.com/prebid/prebid-server/v3/openrtb_ext"
"github.com/stretchr/testify/assert"
)

func TestBidderMediasquare(t *testing.T) {
bidder, buildErr := Builder(openrtb_ext.BidderMediasquare, config.Adapter{
Endpoint: "https://pbs-front.mediasquare.fr/msq_prebid"},
config.Server{ExternalUrl: "https://pbs-front.mediasquare.fr/msq_prebid", GvlID: 1, DataCenter: "2"})
if buildErr != nil {
t.Fatalf("Builder returned unexpected error %v", buildErr)
}
adapterstest.RunJSONBidderTest(t, "mediasquaretest", bidder)
}

func TestMakeRequests(t *testing.T) {
bidder, buildErr := Builder(openrtb_ext.BidderMediasquare, config.Adapter{
Endpoint: "https://pbs-front.mediasquare.fr/msq_prebid"},
config.Server{ExternalUrl: "https://pbs-front.mediasquare.fr/msq_prebid", GvlID: 1, DataCenter: "2"})
if buildErr != nil {
t.Fatalf("Builder returned unexpected error %v", buildErr)
}

// MakeRequests : case request is empty.
resp, errs := bidder.MakeRequests(nil, nil)
expectingErrors := []error{errorWritter("<MakeRequests> request", nil, true)}
assert.Equal(t, []*adapters.RequestData(nil), resp, "resp, was supposed to be empty result.")
assert.Equal(t, expectingErrors, errs, "errs, was supposed to be :", expectingErrors)

Comment on lines +32 to +37
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be tested in JSON files.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I initially would have if it was possible,

// MakeRequests : case request is empty.
resp, errs := bidder.MakeRequests(nil, nil)

Here is a screen-shot of the following test :
nil-imp

Cordially

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have had, let this test be :
image
Tell me if you want me to take it back, it will reduce the coverage by 2% or so... But it is not critical.

// MakeRequests : case request.Imp is empty.
bidResquest := openrtb2.BidRequest{ID: "id-test", Imp: nil}
resp, errs = bidder.MakeRequests(&bidResquest, nil)
expectingErrors = []error{errorWritter("<MakeRequests> request", nil, true)}
assert.Equal(t, []*adapters.RequestData(nil), resp, "resp, was supposed to be empty result.")
assert.Equal(t, expectingErrors, errs, "errs, was supposed to be :", expectingErrors)
}
Loading
Loading