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

Updating pulsepoint adapter #1663

Merged
merged 9 commits into from
Jan 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions adapters/pulsepoint/params_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package pulsepoint

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-schemas. %v", err)
}

for _, validParam := range validParams {
if err := validator.Validate(openrtb_ext.BidderPulsepoint, json.RawMessage(validParam)); err != nil {
t.Errorf("Schema rejected pulsepoint params: %s \n Error: %s", validParam, err)
}
}
}

// TestInvalidParams makes sure that the pubmatic schema rejects all the imp.ext fields we don't support.
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.BidderPulsepoint, json.RawMessage(invalidParam)); err == nil {
t.Errorf("Schema allowed unexpected pulsepoint params: %s", invalidParam)
}
}
}

var validParams = []string{
`{"cp":1000, "ct": 2000}`,
`{"cp":1001, "ct": 2001}`,
`{"cp":1001, "ct": 2001, "cf": "1x1"}`,
}
anand-venkatraman marked this conversation as resolved.
Show resolved Hide resolved

var invalidParams = []string{
``,
`null`,
`true`,
`5`,
`4.2`,
`[]`,
`{}`,
`{"cp":"1000"}`,
`{"ct":"1000"}`,
`{"cp":1000}`,
`{"ct":1000}`,
`{"cp":1000, "ct":"1000"}`,
`{"cp":1000, "ct": "abcd"}`,
`{"cp":"abcd", "ct": 1000}`,
`{"cp":"1000.2", "ct": "1000.1"}`,
}
185 changes: 170 additions & 15 deletions adapters/pulsepoint/pulsepoint.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
package pulsepoint

import (
"bytes"
"context"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"strconv"

"bytes"
"context"
"io/ioutil"
"strings"

"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"
"github.com/prebid/prebid-server/pbs"
Expand All @@ -23,22 +25,180 @@ type PulsePointAdapter struct {
URI string
}

// Builds an instance of PulsePointAdapter
func Builder(bidderName openrtb_ext.BidderName, config config.Adapter) (adapters.Bidder, error) {
bidder := &PulsePointAdapter{
URI: config.Endpoint,
}
return bidder, nil
}
anand-venkatraman marked this conversation as resolved.
Show resolved Hide resolved

func (a *PulsePointAdapter) MakeRequests(request *openrtb.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
errs := make([]error, 0, len(request.Imp))

var err error
pubID := ""
imps := make([]openrtb.Imp, 0, len(request.Imp))
for i := 0; i < len(request.Imp); i++ {
imp := request.Imp[i]
anand-venkatraman marked this conversation as resolved.
Show resolved Hide resolved
var bidderExt adapters.ExtImpBidder
if err = json.Unmarshal(imp.Ext, &bidderExt); err != nil {
errs = append(errs, &errortypes.BadInput{
anand-venkatraman marked this conversation as resolved.
Show resolved Hide resolved
Message: err.Error(),
})
continue
}
var pulsepointExt openrtb_ext.ExtImpPulsePoint
if err = json.Unmarshal(bidderExt.Bidder, &pulsepointExt); err != nil {
errs = append(errs, &errortypes.BadInput{
anand-venkatraman marked this conversation as resolved.
Show resolved Hide resolved
Message: err.Error(),
})
continue
}
// parse pubid and keep it for reference
if pubID == "" && pulsepointExt.PubID > 0 {
pubID = strconv.Itoa(pulsepointExt.PubID)
}
// tag id to be sent
imp.TagID = strconv.Itoa(pulsepointExt.TagID)
imps = append(imps, imp)
}

// verify there are valid impressions
if len(imps) == 0 {
return nil, errs
}

// add the publisher id from ext to the site.pub.id or app.pub.id
if request.Site != nil {
site := *request.Site
if site.Publisher != nil {
publisher := *site.Publisher
publisher.ID = pubID
site.Publisher = &publisher
} else {
site.Publisher = &openrtb.Publisher{ID: pubID}
anand-venkatraman marked this conversation as resolved.
Show resolved Hide resolved
}
request.Site = &site
} else if request.App != nil {
app := *request.App
anand-venkatraman marked this conversation as resolved.
Show resolved Hide resolved
if app.Publisher != nil {
publisher := *app.Publisher
publisher.ID = pubID
app.Publisher = &publisher
} else {
app.Publisher = &openrtb.Publisher{ID: pubID}
}
request.App = &app
}

request.Imp = imps
reqJSON, err := json.Marshal(request)
if err != nil {
errs = append(errs, err)
return nil, errs
}
headers := http.Header{}
headers.Add("Content-Type", "application/json;charset=utf-8")
headers.Add("Accept", "application/json")
return []*adapters.RequestData{{
Method: "POST",
Uri: a.URI,
Body: reqJSON,
Headers: headers,
}}, errs
}

func (a *PulsePointAdapter) MakeBids(internalRequest *openrtb.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) {
// passback
if response.StatusCode == http.StatusNoContent {
return nil, nil
}
anand-venkatraman marked this conversation as resolved.
Show resolved Hide resolved
// bad requests
if response.StatusCode == http.StatusBadRequest {
return nil, []error{&errortypes.BadInput{
Message: fmt.Sprintf("Bad user input: HTTP status %d", response.StatusCode),
}}
}
// error
if response.StatusCode != http.StatusOK {
return nil, []error{&errortypes.BadServerResponse{
Message: fmt.Sprintf("Bad server response: HTTP status %d", response.StatusCode),
}}
}
// parse response
var bidResp openrtb.BidResponse
if err := json.Unmarshal(response.Body, &bidResp); err != nil {
return nil, []error{err}
anand-venkatraman marked this conversation as resolved.
Show resolved Hide resolved
}

bidResponse := adapters.NewBidderResponseWithBidsCapacity(5)
// map imps by id
impsByID := make(map[string]openrtb.Imp)
for i := 0; i < len(internalRequest.Imp); i++ {
impsByID[internalRequest.Imp[i].ID] = internalRequest.Imp[i]
}

var errs []error
for _, sb := range bidResp.SeatBid {
for i := 0; i < len(sb.Bid); i++ {
bid := sb.Bid[i]
imp := impsByID[bid.ImpID]
bidType := getBidType(imp)
if &imp != nil && bidType != "" {
bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{
Bid: &bid,
BidType: bidType,
})
}
}
}
return bidResponse, errs
}

func getBidType(imp openrtb.Imp) openrtb_ext.BidType {
// derive the bidtype purely from the impression itself
anand-venkatraman marked this conversation as resolved.
Show resolved Hide resolved
if imp.Banner != nil {
return openrtb_ext.BidTypeBanner
} else if imp.Video != nil {
return openrtb_ext.BidTypeVideo
} else if imp.Audio != nil {
return openrtb_ext.BidTypeAudio
} else if imp.Native != nil {
return openrtb_ext.BidTypeNative
}
return ""
}

/////////////////////////////////
// Legacy implementation: Start
/////////////////////////////////

func NewPulsePointLegacyAdapter(config *adapters.HTTPAdapterConfig, uri string) *PulsePointAdapter {
a := adapters.NewHTTPAdapter(config)

return &PulsePointAdapter{
http: a,
URI: uri,
}
}

// used for cookies and such
func (a *PulsePointAdapter) Name() string {
return "pulsepoint"
}

func (a *PulsePointAdapter) SkipNoCookies() bool {
return false
}

// parameters for pulsepoint adapter.
type PulsepointParams struct {
PublisherId int `json:"cp"`
TagId int `json:"ct"`
AdSize string `json:"cf"`
}

func (a *PulsePointAdapter) SkipNoCookies() bool {
return false
}

func (a *PulsePointAdapter) Call(ctx context.Context, req *pbs.PBSRequest, bidder *pbs.PBSBidder) (pbs.PBSBidSlice, error) {
mediaTypes := []pbs.MediaType{pbs.MEDIA_TYPE_BANNER}
ppReq, err := adapters.MakeOpenRTBGeneric(req, bidder, a.Name(), mediaTypes)
Expand Down Expand Up @@ -195,11 +355,6 @@ func (a *PulsePointAdapter) Call(ctx context.Context, req *pbs.PBSRequest, bidde
return bids, nil
}

func NewPulsePointLegacyAdapter(config *adapters.HTTPAdapterConfig, uri string) *PulsePointAdapter {
a := adapters.NewHTTPAdapter(config)

return &PulsePointAdapter{
http: a,
URI: uri,
}
}
/////////////////////////////////
// Legacy implementation: End
/////////////////////////////////
34 changes: 27 additions & 7 deletions adapters/pulsepoint/pulsepoint_test.go
Original file line number Diff line number Diff line change
@@ -1,26 +1,43 @@
package pulsepoint

import (
"encoding/json"
"net/http"
"testing"

"github.com/mxmCherry/openrtb"
"github.com/prebid/prebid-server/adapters"
"github.com/prebid/prebid-server/openrtb_ext"

"bytes"
"context"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/http/httptest"
"testing"
"time"

"github.com/mxmCherry/openrtb"
"github.com/prebid/prebid-server/adapters"
"github.com/prebid/prebid-server/adapters/adapterstest"
"github.com/prebid/prebid-server/cache/dummycache"
"github.com/prebid/prebid-server/config"
"github.com/prebid/prebid-server/openrtb_ext"
"github.com/prebid/prebid-server/pbs"
"github.com/prebid/prebid-server/usersync"
)

func TestJsonSamples(t *testing.T) {
bidder, buildErr := Builder(openrtb_ext.BidderPulsepoint, config.Adapter{
Endpoint: "http://bidder.pulsepoint.com"})

if buildErr != nil {
t.Fatalf("Builder returned unexpected error %v", buildErr)
}

adapterstest.RunJSONBidderTest(t, "pulsepointtest", bidder)
}

/////////////////////////////////
// Legacy implementation: Start
/////////////////////////////////

/**
* Verify adapter names are setup correctly.
*/
Expand Down Expand Up @@ -75,7 +92,6 @@ func TestPulsePointOpenRTBRequest(t *testing.T) {
bidder := req.Bidders[0]
adapter := NewPulsePointLegacyAdapter(adapters.DefaultHTTPAdapterConfig, server.URL)
adapter.Call(ctx, req, bidder)
fmt.Println(service.LastBidRequest)
adapterstest.VerifyIntValue(len(service.LastBidRequest.Imp), 1, t)
adapterstest.VerifyStringValue(service.LastBidRequest.Imp[0].TagID, "1001", t)
adapterstest.VerifyStringValue(service.LastBidRequest.Site.Publisher.ID, "2001", t)
Expand Down Expand Up @@ -290,3 +306,7 @@ func CreateService(tagsToBid map[string]bool) adapterstest.OrtbMockService {
service.LastBidRequest = &lastBidRequest
return service
}

/////////////////////////////////
// Legacy implementation: End
/////////////////////////////////
Loading