Skip to content
This repository has been archived by the owner on Dec 22, 2022. It is now read-only.

Commit

Permalink
[Sharethrough] Add Unified ID support (prebid#987)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mathieu Pheulpin authored and mansinahar committed Aug 19, 2019
1 parent 896099d commit 6d37151
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 91 deletions.
8 changes: 7 additions & 1 deletion adapters/sharethrough/butler.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type StrAdSeverParams struct {
Iframe bool
Height uint64
Width uint64
TheTradeDeskUserId string
}

type StrOpenRTBInterface interface {
Expand Down Expand Up @@ -68,6 +69,7 @@ func (s StrOpenRTBTranslator) requestFromOpenRTB(imp openrtb.Imp, request *openr
}

pKey := strImpParams.Pkey
userInfo := s.Util.parseUserExt(request.User)

var height, width uint64
if len(strImpParams.IframeSize) >= 2 {
Expand All @@ -82,11 +84,12 @@ func (s StrOpenRTBTranslator) requestFromOpenRTB(imp openrtb.Imp, request *openr
Pkey: pKey,
BidID: imp.ID,
ConsentRequired: s.Util.gdprApplies(request),
ConsentString: s.Util.gdprConsentString(request),
ConsentString: userInfo.Consent,
Iframe: strImpParams.Iframe,
Height: height,
Width: width,
InstantPlayCapable: s.Util.canAutoPlayVideo(request.Device.UA, s.UserAgentParsers),
TheTradeDeskUserId: userInfo.TtdUid,
}),
Body: nil,
Headers: headers,
Expand Down Expand Up @@ -143,6 +146,9 @@ func (h StrUriHelper) buildUri(params StrAdSeverParams) string {
v.Set("bidId", params.BidID)
v.Set("consent_required", fmt.Sprintf("%t", params.ConsentRequired))
v.Set("consent_string", params.ConsentString)
if params.TheTradeDeskUserId != "" {
v.Set("ttduid", params.TheTradeDeskUserId)
}

v.Set("instant_play_capable", fmt.Sprintf("%t", params.InstantPlayCapable))
v.Set("stayInIframe", fmt.Sprintf("%t", params.Iframe))
Expand Down
2 changes: 2 additions & 0 deletions adapters/sharethrough/butler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@ func TestBuildUri(t *testing.T) {
Iframe: false,
Height: 20,
Width: 30,
TheTradeDeskUserId: "ttd123",
},
expected: []string{
"http://abc.com?",
Expand All @@ -297,6 +298,7 @@ func TestBuildUri(t *testing.T) {
"width=30",
"supplyId=FGMrCMMc",
"strVersion=" + strVersion,
"ttduid=ttd123",
},
},
}
Expand Down
2 changes: 1 addition & 1 deletion adapters/sharethrough/sharethrough.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
)

const supplyId = "FGMrCMMc"
const strVersion = "1.0.1"
const strVersion = "1.0.2"

func NewSharethroughBidder(endpoint string) *SharethroughAdapter {
return &SharethroughAdapter{
Expand Down
34 changes: 25 additions & 9 deletions adapters/sharethrough/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const minSafariVersion = 10

type UtilityInterface interface {
gdprApplies(*openrtb.BidRequest) bool
gdprConsentString(*openrtb.BidRequest) string
parseUserExt(*openrtb.User) userInfo

getAdMarkup(openrtb_ext.ExtImpSharethroughResponse, *StrAdSeverParams) (string, error)
getPlacementSize([]openrtb.Format) (uint64, uint64)
Expand All @@ -36,6 +36,16 @@ type UtilityInterface interface {

type Util struct{}

type userExt struct {
Consent string `json:"consent,omitempty"`
Eids []openrtb_ext.ExtUserEid `json:"eids,omitempty"`
}

type userInfo struct {
Consent string
TtdUid string
}

func (u Util) getAdMarkup(strResp openrtb_ext.ExtImpSharethroughResponse, params *StrAdSeverParams) (string, error) {
strRespId := fmt.Sprintf("str_response_%s", strResp.BidID)
jsonPayload, err := json.Marshal(strResp)
Expand Down Expand Up @@ -183,17 +193,23 @@ func (u Util) gdprApplies(request *openrtb.BidRequest) bool {
return gdprApplies != 0
}

func (u Util) gdprConsentString(request *openrtb.BidRequest) string {
var consentString string

if request.User != nil {
if jsonExtUser, err := request.User.Ext.MarshalJSON(); err == nil {
// empty string is the return value if error, so no need to handle
consentString, _ = jsonparser.GetString(jsonExtUser, "consent")
func (u Util) parseUserExt(user *openrtb.User) (ui userInfo) {
var userExt userExt
if user != nil && user.Ext != nil {
if err := json.Unmarshal(user.Ext, &userExt); err == nil {
ui.Consent = userExt.Consent
for i := 0; i < len(userExt.Eids); i++ {
if userExt.Eids[i].Source == "adserver.org" && len(userExt.Eids[i].Uids) > 0 {
if userExt.Eids[i].Uids[0].ID != "" {
ui.TtdUid = userExt.Eids[i].Uids[0].ID
}
break
}
}
}
}

return consentString
return
}

func (u Util) parseDomain(fullUrl string) string {
Expand Down
134 changes: 54 additions & 80 deletions adapters/sharethrough/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package sharethrough
import (
"github.com/mxmCherry/openrtb"
"github.com/prebid/prebid-server/openrtb_ext"
"github.com/stretchr/testify/assert"
"regexp"
"strings"
"testing"
)

Expand Down Expand Up @@ -51,19 +51,15 @@ func TestGetAdMarkup(t *testing.T) {
},
}

util := Util{}
for testName, test := range tests {
t.Logf("Test case: %s\n", testName)
assert := assert.New(t)

outputSuccess, outputError := util.getAdMarkup(test.inputResponse, test.inputParams)
outputSuccess, outputError := Util{}.getAdMarkup(test.inputResponse, test.inputParams)
for _, markup := range test.expectedSuccess {
if !strings.Contains(outputSuccess, markup) {
t.Errorf("Expected Ad Markup to contain: %s, got %s\n", markup, outputSuccess)
}
}
if outputError != test.expectedError {
t.Errorf("Expected Error to be: %s, got %s\n", test.expectedError, outputError)
assert.Contains(outputSuccess, markup)
}
assert.Equal(outputError, test.expectedError)
}
}

Expand All @@ -90,17 +86,13 @@ func TestGetPlacementSize(t *testing.T) {
},
}

util := Util{}
for testName, test := range tests {
t.Logf("Test case: %s\n", testName)
assert := assert.New(t)

outputHeight, outputWidth := util.getPlacementSize(test.input)
if outputHeight != test.expectedHeight {
t.Errorf("Expected Height: %d, got %d\n", test.expectedHeight, outputHeight)
}
if outputWidth != test.expectedWidth {
t.Errorf("Expected Width: %d, got %d\n", test.expectedWidth, outputWidth)
}
outputHeight, outputWidth := Util{}.getPlacementSize(test.input)
assert.Equal(outputHeight, test.expectedHeight)
assert.Equal(outputWidth, test.expectedWidth)
}
}

Expand All @@ -112,11 +104,10 @@ type userAgentTest struct {
func runUserAgentTests(tests map[string]userAgentTest, fn func(string) bool, t *testing.T) {
for testName, test := range tests {
t.Logf("Test case: %s\n", testName)
assert := assert.New(t)

output := fn(test.input)
if output != test.expected {
t.Errorf("Expected: %t, got %t\n", test.expected, output)
}
assert.Equal(output, test.expected)
}
}

Expand Down Expand Up @@ -155,11 +146,10 @@ func TestCanAutoPlayVideo(t *testing.T) {

for testName, test := range tests {
t.Logf("Test case: %s\n", testName)
assert := assert.New(t)

output := Util{}.canAutoPlayVideo(test.input, uaParsers)
if output != test.expected {
t.Errorf("Expected: %t, got %t\n", test.expected, output)
}
assert.Equal(output, test.expected)
}
}

Expand Down Expand Up @@ -233,11 +223,10 @@ func TestIsAtMinChromeVersion(t *testing.T) {

for testName, test := range tests {
t.Logf("Test case: %s\n", testName)
assert := assert.New(t)

output := Util{}.isAtMinChromeVersion(test.input, regex)
if output != test.expected {
t.Errorf("Expected: %t, got %t\n", test.expected, output)
}
assert.Equal(output, test.expected)
}
}

Expand All @@ -264,11 +253,10 @@ func TestIsAtMinChromeIosVersion(t *testing.T) {

for testName, test := range tests {
t.Logf("Test case: %s\n", testName)
assert := assert.New(t)

output := Util{}.isAtMinChromeVersion(test.input, regex)
if output != test.expected {
t.Errorf("Expected: %t, got %t\n", test.expected, output)
}
assert.Equal(output, test.expected)
}
}

Expand All @@ -295,11 +283,10 @@ func TestIsAtMinSafariVersion(t *testing.T) {

for testName, test := range tests {
t.Logf("Test case: %s\n", testName)
assert := assert.New(t)

output := Util{}.isAtMinSafariVersion(test.input, regex)
if output != test.expected {
t.Errorf("Expected: %t, got %t\n", test.expected, output)
}
assert.Equal(output, test.expected)
}
}

Expand Down Expand Up @@ -345,67 +332,57 @@ func TestGdprApplies(t *testing.T) {
},
}

util := Util{}
for testName, test := range tests {
t.Logf("Test case: %s\n", testName)
assert := assert.New(t)

output := util.gdprApplies(test.input)
if output != test.expected {
t.Errorf("Expected: %t, got %t\n", test.expected, output)
}
output := Util{}.gdprApplies(test.input)
assert.Equal(output, test.expected)
}
}

func TestGdprConsentString(t *testing.T) {
bidRequestWithConsent := openrtb.BidRequest{
User: &openrtb.User{
Ext: []byte(`{"consent": "abc"}`),
func TestParseUserExt(t *testing.T) {
tests := map[string]struct {
input *openrtb.User
expected userInfo
}{
"Return empty strings if no User": {
input: nil,
expected: userInfo{Consent: "", TtdUid: ""},
},
}
bidRequestWithEmptyConsent := openrtb.BidRequest{
User: &openrtb.User{
Ext: []byte(`{"consent": ""}`),
"Return empty strings if no uids": {
input: &openrtb.User{Ext: []byte(`{ "eids": [{"source": "adserver.org", "uids": []}] }`)},
expected: userInfo{Consent: "", TtdUid: ""},
},
}
bidRequestWithoutConsent := openrtb.BidRequest{
User: &openrtb.User{
Ext: []byte(`{"other": "abc"}`),
"Return empty strings if ID is not defined or empty string": {
input: &openrtb.User{Ext: []byte(`{ "eids": [{"source": "adserver.org", "uids": [{"id": null}]}, {"source": "adserver.org", "uids": [{"id": ""}]}] }`)},
expected: userInfo{Consent: "", TtdUid: ""},
},
}
bidRequestWithUserExt := openrtb.BidRequest{
User: &openrtb.User{},
}

tests := map[string]struct {
input *openrtb.BidRequest
expected string
}{
"Return consent string if provided": {
input: &bidRequestWithConsent,
expected: "abc",
"Return consent correctly": {
input: &openrtb.User{Ext: []byte(`{ "consent": "abc" }`)},
expected: userInfo{Consent: "abc", TtdUid: ""},
},
"Return empty string if consent string empty": {
input: &bidRequestWithEmptyConsent,
expected: "",
"Return ttd uid correctly": {
input: &openrtb.User{Ext: []byte(`{ "eids": [{"source": "adserver.org", "uids": [{"id": "abc123"}]}] }`)},
expected: userInfo{Consent: "", TtdUid: "abc123"},
},
"Return empty string if no consent string provided": {
input: &bidRequestWithoutConsent,
expected: "",
"Ignore non-trade-desk uid": {
input: &openrtb.User{Ext: []byte(`{ "eids": [{"source": "something", "uids": [{"id": "xyz"}]}] }`)},
expected: userInfo{Consent: "", TtdUid: ""},
},
"Return empty string if User set": {
input: &bidRequestWithUserExt,
expected: "",
"Full test": {
input: &openrtb.User{Ext: []byte(`{ "consent": "abc", "eids": [{"source": "something", "uids": [{"id": "xyz"}]}, {"source": "adserver.org", "uids": [{"id": "abc123"}]}] }`)},
expected: userInfo{Consent: "abc", TtdUid: "abc123"},
},
}

util := Util{}
for testName, test := range tests {
t.Logf("Test case: %s\n", testName)
assert := assert.New(t)

output := util.gdprConsentString(test.input)
if output != test.expected {
t.Errorf("Expected: %s, got %s\n", test.expected, output)
}
output := Util{}.parseUserExt(test.input)
assert.Equal(output.Consent, test.expected.Consent)
assert.Equal(output.TtdUid, test.expected.TtdUid)
}
}

Expand All @@ -430,12 +407,9 @@ func TestParseDomain(t *testing.T) {

for testName, test := range tests {
t.Logf("Test case: %s\n", testName)
assert := assert.New(t)

output := Util{}.parseDomain(test.input)

if output != test.expected {
t.Errorf("Expected parsed url %s, got %s\n", test.expected, output)
return
}
assert.Equal(output, test.expected)
}
}

0 comments on commit 6d37151

Please sign in to comment.