Repository: prebid/prebid-server
Pull request #1135 (2019-12-05 21:43:35)

CCPA Phase 1: Cookie Sync
Implements: https://github.com/prebid/prebid-server/issues/1107

hhhjort: I think this is conflicting with the AMP PR.
SyntaxNode: > I think this is conflicting with the AMP PR.

Yeah. Not surprising. Fixing...

Patch:
diff --git a/adapters/rubicon/rubicon.go b/adapters/rubicon/rubicon.go
index 86422db0..7f8de46b 100644
--- a/adapters/rubicon/rubicon.go
+++ b/adapters/rubicon/rubicon.go
@@ -213,6 +213,16 @@ var rubiSizeMap = map[rubiSize]int{
 	{w: 640, h: 320}:   156,
 }
 
+// defines the contract for bidrequest.user.ext.eids[i].ext
+type rubiconUserExtEidExt struct {
+	Segments []string `json:"segments,omitempty"`
+}
+
+// defines the contract for bidrequest.user.ext.eids[i].uids[j].ext
+type rubiconUserExtEidUidExt struct {
+	RtiPartner string `json:"rtiPartner,omitempty"`
+}
+
 //MAS algorithm
 func findPrimary(alt []int) (int, []int) {
 	min, pos, primary := 0, 0, 0
@@ -648,20 +658,12 @@ func (a *RubiconAdapter) MakeRequests(request *openrtb.BidRequest, reqInfo *adap
 
 				// set user.ext.tpid
 				if len(userExt.Eids) > 0 {
-					tpIds := make([]rubiconExtUserTpID, 0)
-					for _, eid := range userExt.Eids {
-						if eid.Source == "adserver.org" {
-							uids := eid.Uids
-							if len(uids) > 0 {
-								uid := uids[0]
-								if uid.Ext != nil && uid.Ext.RtiPartner == "TDID" {
-									tpIds = append(tpIds, rubiconExtUserTpID{Source: "tdid", UID: uid.ID})
-								}
-							}
-						}
-					}
-					if len(tpIds) > 0 {
-						userExtRP.TpID = tpIds
+					if tpIds, segments, errors := getTpIdsAndSegments(userExt.Eids); len(errors) > 0 {
+						errs = append(errs, errors...)
+						continue
+					} else if err := updateUserExtWithTpIdsAndSegments(&userExtRP, tpIds, segments); err != nil {
+						errs = append(errs, err)
+						continue
 					}
 				}
 			}
@@ -746,6 +748,82 @@ func (a *RubiconAdapter) MakeRequests(request *openrtb.BidRequest, reqInfo *adap
 	return requestData, errs
 }
 
+func getTpIdsAndSegments(eids []openrtb_ext.ExtUserEid) ([]rubiconExtUserTpID, []string, []error) {
+	tpIds := make([]rubiconExtUserTpID, 0)
+	segments := make([]string, 0)
+	errs := make([]error, 0)
+
+	for _, eid := range eids {
+		switch eid.Source {
+		case "adserver.org":
+			uids := eid.Uids
+			if len(uids) > 0 {
+				uid := uids[0]
+
+				if uid.Ext != nil {
+					var eidUidExt rubiconUserExtEidUidExt
+					if err := json.Unmarshal(uid.Ext, &eidUidExt); err != nil {
+						errs = append(errs, &errortypes.BadInput{
+							Message: err.Error(),
+						})
+						continue
+					}
+
+					if eidUidExt.RtiPartner == "TDID" {
+						tpIds = append(tpIds, rubiconExtUserTpID{Source: "tdid", UID: uid.ID})
+					}
+				}
+			}
+		case "liveintent.com":
+			uids := eid.Uids
+			if len(uids) > 0 {
+				uidId := uids[0].ID
+				if uidId != "" {
+					tpIds = append(tpIds, rubiconExtUserTpID{Source: "liveintent.com", UID: uidId})
+				}
+
+				if eid.Ext != nil {
+					var eidExt rubiconUserExtEidExt
+					if err := json.Unmarshal(eid.Ext, &eidExt); err != nil {
+						errs = append(errs, &errortypes.BadInput{
+							Message: err.Error(),
+						})
+						continue
+					}
+					segments = eidExt.Segments
+				}
+			}
+		}
+	}
+
+	return tpIds, segments, errs
+}
+
+func updateUserExtWithTpIdsAndSegments(userExtRP *rubiconUserExt, tpIds []rubiconExtUserTpID, segments []string) error {
+	if len(tpIds) > 0 {
+		userExtRP.TpID = tpIds
+
+		if segments != nil {
+			userExtRPTarget := make(map[string]interface{})
+
+			if userExtRP.RP.Target != nil {
+				if err := json.Unmarshal(userExtRP.RP.Target, &userExtRPTarget); err != nil {
+					return &errortypes.BadInput{Message: err.Error()}
+				}
+			}
+
+			userExtRPTarget["LIseg"] = segments
+
+			if target, err := json.Marshal(&userExtRPTarget); err != nil {
+				return &errortypes.BadInput{Message: err.Error()}
+			} else {
+				userExtRP.RP.Target = target
+			}
+		}
+	}
+	return nil
+}
+
 func isVideo(imp openrtb.Imp) bool {
 	video := imp.Video
 	if video != nil {
diff --git a/adapters/syncer.go b/adapters/syncer.go
index 21491b2a..d86e3239 100644
--- a/adapters/syncer.go
+++ b/adapters/syncer.go
@@ -5,6 +5,7 @@ import (
 
 	"github.com/prebid/prebid-server/macros"
 	"github.com/prebid/prebid-server/openrtb_ext"
+	"github.com/prebid/prebid-server/privacy"
 	"github.com/prebid/prebid-server/usersync"
 )
 
@@ -41,17 +42,18 @@ const (
 	SyncTypeIframe   SyncType = "iframe"
 )
 
-func (s *Syncer) GetUsersyncInfo(gdpr string, consent string) (*usersync.UsersyncInfo, error) {
-	userSyncURL, err := macros.ResolveMacros(*s.urlTemplate, macros.UserSyncTemplateParams{
-		GDPR:        gdpr,
-		GDPRConsent: consent,
+func (s *Syncer) GetUsersyncInfo(privacyPolicies privacy.Policies) (*usersync.UsersyncInfo, error) {
+	syncURL, err := macros.ResolveMacros(*s.urlTemplate, macros.UserSyncTemplateParams{
+		GDPR:        privacyPolicies.GDPR.Signal,
+		GDPRConsent: privacyPolicies.GDPR.Consent,
+		USPrivacy:   privacyPolicies.CCPA.Signal,
 	})
 	if err != nil {
 		return nil, err
 	}
 
 	return &usersync.UsersyncInfo{
-		URL:         userSyncURL,
+		URL:         syncURL,
 		Type:        string(s.syncType),
 		SupportCORS: false,
 	}, err
diff --git a/config/config.go b/config/config.go
index 3df2eaf8..b20f04df 100644
--- a/config/config.go
+++ b/config/config.go
@@ -728,6 +728,7 @@ func setBidderDefaults(v *viper.Viper, bidder string) {
 	v.SetDefault(adapterCfgPrefix+bidder+".endpoint", "")
 	v.SetDefault(adapterCfgPrefix+bidder+".usersync_url", "")
 	v.SetDefault(adapterCfgPrefix+bidder+".platform_id", "")
+	v.SetDefault(adapterCfgPrefix+bidder+".app_secret", "")
 	v.SetDefault(adapterCfgPrefix+bidder+".xapi.username", "")
 	v.SetDefault(adapterCfgPrefix+bidder+".xapi.password", "")
 	v.SetDefault(adapterCfgPrefix+bidder+".xapi.tracker", "")
diff --git a/endpoints/auction.go b/endpoints/auction.go
index 9a1d670d..bf592e43 100644
--- a/endpoints/auction.go
+++ b/endpoints/auction.go
@@ -23,6 +23,8 @@ import (
 	"github.com/prebid/prebid-server/pbs"
 	"github.com/prebid/prebid-server/pbsmetrics"
 	pbc "github.com/prebid/prebid-server/prebid_cache_client"
+	"github.com/prebid/prebid-server/privacy"
+	gdprPolicy "github.com/prebid/prebid-server/privacy/gdpr"
 	"github.com/prebid/prebid-server/usersync"
 )
 
@@ -188,20 +190,20 @@ func (a *auction) recoverSafely(inner func(*pbs.PBSBidder, pbsmetrics.AdapterLab
 	}
 }
 
-func (a *auction) shouldUsersync(ctx context.Context, bidder openrtb_ext.BidderName, gdprApplies string, consent string) bool {
-	switch gdprApplies {
+func (a *auction) shouldUsersync(ctx context.Context, bidder openrtb_ext.BidderName, gdprPrivacyPolicy gdprPolicy.Policy) bool {
+	switch gdprPrivacyPolicy.Signal {
 	case "0":
 		return true
 	case "1":
-		if consent == "" {
+		if gdprPrivacyPolicy.Consent == "" {
 			return false
 		}
 		fallthrough
 	default:
-		if canSync, err := a.gdprPerms.HostCookiesAllowed(ctx, consent); !canSync || err != nil {
+		if canSync, err := a.gdprPerms.HostCookiesAllowed(ctx, gdprPrivacyPolicy.Consent); !canSync || err != nil {
 			return false
 		}
-		canSync, err := a.gdprPerms.BidderSyncAllowed(ctx, bidder, consent)
+		canSync, err := a.gdprPerms.BidderSyncAllowed(ctx, bidder, gdprPrivacyPolicy.Consent)
 		return canSync && err == nil
 	}
 }
@@ -508,10 +510,14 @@ func (a *auction) processUserSync(req *pbs.PBSRequest, bidder *pbs.PBSBidder, bl
 	uid, _, _ := req.Cookie.GetUID(syncer.FamilyName())
 	if uid == "" {
 		bidder.NoCookie = true
-		gdprApplies := req.ParseGDPR()
-		consent := req.ParseConsent()
-		if a.shouldUsersync(*ctx, openrtb_ext.BidderName(syncerCode), gdprApplies, consent) {
-			syncInfo, err := syncer.GetUsersyncInfo(gdprApplies, consent)
+		privacyPolicies := privacy.Policies{
+			GDPR: gdprPolicy.Policy{
+				Signal:  req.ParseGDPR(),
+				Consent: req.ParseConsent(),
+			},
+		}
+		if a.shouldUsersync(*ctx, openrtb_ext.BidderName(syncerCode), privacyPolicies.GDPR) {
+			syncInfo, err := syncer.GetUsersyncInfo(privacyPolicies)
 			if err == nil {
 				bidder.UsersyncInfo = syncInfo
 			} else {
diff --git a/endpoints/cookie_sync.go b/endpoints/cookie_sync.go
index 48437008..475416e8 100644
--- a/endpoints/cookie_sync.go
+++ b/endpoints/cookie_sync.go
@@ -18,6 +18,9 @@ import (
 	"github.com/prebid/prebid-server/gdpr"
 	"github.com/prebid/prebid-server/openrtb_ext"
 	"github.com/prebid/prebid-server/pbsmetrics"
+	"github.com/prebid/prebid-server/privacy"
+	"github.com/prebid/prebid-server/privacy/ccpa"
+	gdprPolicy "github.com/prebid/prebid-server/privacy/gdpr"
 	"github.com/prebid/prebid-server/usersync"
 )
 
@@ -122,7 +125,16 @@ func (deps *cookieSyncDeps) Endpoint(w http.ResponseWriter, r *http.Request, _ h
 	}
 	for i := 0; i < len(parsedReq.Bidders); i++ {
 		bidder := parsedReq.Bidders[i]
-		syncInfo, err := deps.syncers[openrtb_ext.BidderName(bidder)].GetUsersyncInfo(gdprToString(parsedReq.GDPR), parsedReq.Consent)
+		privacyPolicy := privacy.Policies{
+			GDPR: gdprPolicy.Policy{
+				Signal:  gdprToString(parsedReq.GDPR),
+				Consent: parsedReq.Consent,
+			},
+			CCPA: ccpa.Policy{
+				Signal: parsedReq.USPrivacy,
+			},
+		}
+		syncInfo, err := deps.syncers[openrtb_ext.BidderName(bidder)].GetUsersyncInfo(privacyPolicy)
 		if err == nil {
 			newSync := &usersync.CookieSyncBidders{
 				BidderCode:   bidder,
@@ -190,10 +202,11 @@ func cookieSyncStatus(syncCount int) string {
 }
 
 type cookieSyncRequest struct {
-	Bidders []string `json:"bidders"`
-	GDPR    *int     `json:"gdpr"`
-	Consent string   `json:"gdpr_consent"`
-	Limit   int      `json:"limit"`
+	Bidders   []string `json:"bidders"`
+	GDPR      *int     `json:"gdpr"`
+	Consent   string   `json:"gdpr_consent"`
+	USPrivacy string   `json:"us_privacy"`
+	Limit     int      `json:"limit"`
 }
 
 func (req *cookieSyncRequest) filterExistingSyncs(valid map[openrtb_ext.BidderName]usersync.Usersyncer, cookie *usersync.PBSCookie, needSyncupForSameSite bool) {
diff --git a/endpoints/openrtb2/amp_auction.go b/endpoints/openrtb2/amp_auction.go
index 7328d3c1..6b64238f 100644
--- a/endpoints/openrtb2/amp_auction.go
+++ b/endpoints/openrtb2/amp_auction.go
@@ -382,14 +382,12 @@ func (deps *endpointDeps) overrideWithParams(httpRequest *http.Request, req *ope
 		req.Imp[0].TagID = slot
 	}
 
-	gdprConsent := getQueryParam(httpRequest, "gdpr_consent")
-	ccpaValue := getQueryParam(httpRequest, "us_privacy")
 	privacyPolicies := privacy.Policies{
 		GDPR: gdpr.Policy{
-			Consent: gdprConsent,
+			Consent: getQueryParam(httpRequest, "gdpr_consent"),
 		},
 		CCPA: ccpa.Policy{
-			Value: ccpaValue,
+			Signal: getQueryParam(httpRequest, "us_privacy"),
 		},
 	}
 
diff --git a/macros/macros.go b/macros/macros.go
index dd5832c3..9f9cfad2 100644
--- a/macros/macros.go
+++ b/macros/macros.go
@@ -17,6 +17,7 @@ type EndpointTemplateParams struct {
 type UserSyncTemplateParams struct {
 	GDPR        string
 	GDPRConsent string
+	USPrivacy   string
 }
 
 // ResolveMacros resolves macros in the given template with the provided params
diff --git a/openrtb_ext/user.go b/openrtb_ext/user.go
index 308823a4..520d73a6 100644
--- a/openrtb_ext/user.go
+++ b/openrtb_ext/user.go
@@ -1,5 +1,7 @@
 package openrtb_ext
 
+import "encoding/json"
+
 // ExtUser defines the contract for bidrequest.user.ext
 type ExtUser struct {
 	// Consent is a GDPR consent string. See "Advised Extensions" of
@@ -36,15 +38,11 @@ type ExtUserEid struct {
 	Source string          `json:"source"`
 	ID     string          `json:"id,omitempty"`
 	Uids   []ExtUserEidUid `json:"uids,omitempty"`
+	Ext    json.RawMessage `json:"ext,omitempty"`
 }
 
 // ExtUserEidUid defines the contract for bidrequest.user.ext.eids[i].uids[j]
 type ExtUserEidUid struct {
-	ID  string            `json:"id"`
-	Ext *ExtUserEidUidExt `json:"ext,omitempty"`
-}
-
-// ExtUserEidUidExt defines the contract for bidrequest.user.ext.eids[i].uids[j].ext
-type ExtUserEidUidExt struct {
-	RtiPartner string `json:"rtiPartner,omitempty"`
+	ID  string          `json:"id"`
+	Ext json.RawMessage `json:"ext,omitempty"`
 }
diff --git a/privacy/ccpa/ccpa.go b/privacy/ccpa/ccpa.go
index 612c1073..ba6ac611 100644
--- a/privacy/ccpa/ccpa.go
+++ b/privacy/ccpa/ccpa.go
@@ -9,12 +9,12 @@ import (
 
 // Policy represents the CCPA regulation for an OpenRTB bid request.
 type Policy struct {
-	Value string
+	Signal string
 }
 
 // Write mutates an OpenRTB bid request with the context of the CCPA policy.
 func (p Policy) Write(req *openrtb.BidRequest) error {
-	if p.Value == "" {
+	if p.Signal == "" {
 		return nil
 	}
 
@@ -23,11 +23,11 @@ func (p Policy) Write(req *openrtb.BidRequest) error {
 	}
 
 	if req.Regs.Ext == nil {
-		req.Regs.Ext = json.RawMessage(`{"us_privacy":"` + p.Value + `"}`)
+		req.Regs.Ext = json.RawMessage(`{"us_privacy":"` + p.Signal + `"}`)
 		return nil
 	}
 
 	var err error
-	req.Regs.Ext, err = jsonparser.Set(req.Regs.Ext, []byte(`"`+p.Value+`"`), "us_privacy")
+	req.Regs.Ext, err = jsonparser.Set(req.Regs.Ext, []byte(`"`+p.Signal+`"`), "us_privacy")
 	return err
 }
diff --git a/privacy/gdpr/gdpr.go b/privacy/gdpr/gdpr.go
index 60d6fe8e..61f95ac9 100644
--- a/privacy/gdpr/gdpr.go
+++ b/privacy/gdpr/gdpr.go
@@ -7,8 +7,9 @@ import (
 	"github.com/mxmCherry/openrtb"
 )
 
-// Policy represents the GDPR regulation of an OpenRTB bid request.
+// Policy represents the GDPR regulation for an OpenRTB bid request.
 type Policy struct {
+	Signal  string
 	Consent string
 }
 
diff --git a/stored_requests/events/http/http.go b/stored_requests/events/http/http.go
index 94d8de65..4f141dac 100644
--- a/stored_requests/events/http/http.go
+++ b/stored_requests/events/http/http.go
@@ -6,6 +6,7 @@ import (
 	"encoding/json"
 	"io/ioutil"
 	httpCore "net/http"
+	"net/url"
 	"time"
 
 	"golang.org/x/net/context/ctxhttp"
@@ -94,10 +95,33 @@ func (e *HTTPEvents) refresh(ticker <-chan time.Time) {
 		select {
 		case thisTime := <-ticker:
 			thisTimeInUTC := thisTime.UTC()
-			thisEndpoint := e.Endpoint + "?last-modified=" + e.lastUpdate.Format(time.RFC3339)
+
+			// Parse the endpoint url defined
+			endpointUrl, urlErr := url.Parse(e.Endpoint)
+
+			// Error with url parsing
+			if urlErr != nil {
+				glog.Errorf("Disabling refresh HTTP cache from GET '%s': %v", e.Endpoint, urlErr)
+				return
+			}
+
+			// Parse the url query string
+			urlQuery := endpointUrl.Query()
+
+			// See the last-modified query param
+			urlQuery.Set("last-modified", e.lastUpdate.Format(time.RFC3339))
+
+			// Rebuild
+			endpointUrl.RawQuery = urlQuery.Encode()
+
+			// Convert to string
+			endpoint := endpointUrl.String()
+
+			glog.Infof("Refreshing HTTP cache from GET '%s'", endpoint)
+
 			ctx, cancel := e.ctxProducer()
-			resp, err := ctxhttp.Get(ctx, e.client, thisEndpoint)
-			if respObj, ok := e.parse(thisEndpoint, resp, err); ok {
+			resp, err := ctxhttp.Get(ctx, e.client, endpoint)
+			if respObj, ok := e.parse(endpoint, resp, err); ok {
 				invalidations := events.Invalidation{
 					Requests: extractInvalidations(respObj.StoredRequests),
 					Imps:     extractInvalidations(respObj.StoredImps),
diff --git a/usersync/usersync.go b/usersync/usersync.go
index dbf0a1f7..2b313a02 100644
--- a/usersync/usersync.go
+++ b/usersync/usersync.go
@@ -1,14 +1,14 @@
 package usersync
 
+import "github.com/prebid/prebid-server/privacy"
+
 type Usersyncer interface {
 	// GetUsersyncInfo returns basic info the browser needs in order to run a user sync.
 	// The returned UsersyncInfo object must not be mutated by callers.
 	//
-	// gdpr should be 1 if GDPR is active, 0 if not, and an empty string if we're not sure.
-	// consent should be an empty string or a raw base64 url-encoded IAB Vendor Consent String.
-	//
 	// For more information about user syncs, see http://clearcode.cc/2015/12/cookie-syncing/
-	GetUsersyncInfo(gdpr string, consent string) (*UsersyncInfo, error)
+	GetUsersyncInfo(privacyPolicies privacy.Policies) (*UsersyncInfo, error)
+
 	// FamilyName should be the same as the `BidderName` for this Usersyncer.
 	// This function only exists for legacy reasons.
 	// TODO #362: when the appnexus usersyncer is consistent, delete this and use the key


Test patch:
diff --git a/adapters/33across/usersync_test.go b/adapters/33across/usersync_test.go
index 1efb53ea..f4bb2815 100644
--- a/adapters/33across/usersync_test.go
+++ b/adapters/33across/usersync_test.go
@@ -4,13 +4,19 @@ import (
 	"testing"
 	"text/template"
 
+	"github.com/prebid/prebid-server/privacy"
 	"github.com/stretchr/testify/assert"
 )
 
 func Test33AcrossSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("https://ic.tynt.com/r/d?m=xch&rt=html&ri=123&ru=%2Fsetuid%3Fbidder%3D33across%26uid%3D33XUSERID33X&id=zzz000000000002zzz"))
-	syncer := New33AcrossSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("", "")
+	syncURL := "https://ic.tynt.com/r/d?m=xch&rt=html&ri=123&ru=%2Fsetuid%3Fbidder%3D33across%26uid%3D33XUSERID33X&id=zzz000000000002zzz"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := New33AcrossSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "https://ic.tynt.com/r/d?m=xch&rt=html&ri=123&ru=%2Fsetuid%3Fbidder%3D33across%26uid%3D33XUSERID33X&id=zzz000000000002zzz", syncInfo.URL)
 	assert.Equal(t, "iframe", syncInfo.Type)
diff --git a/adapters/adform/usersync_test.go b/adapters/adform/usersync_test.go
index 815103a8..855506da 100644
--- a/adapters/adform/usersync_test.go
+++ b/adapters/adform/usersync_test.go
@@ -5,12 +5,25 @@ import (
 	"text/template"
 
 	"github.com/stretchr/testify/assert"
+
+	"github.com/prebid/prebid-server/privacy"
+	"github.com/prebid/prebid-server/privacy/gdpr"
 )
 
 func TestAdformSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("//cm.adform.net?return_url=localhost%2Fsetuid%3Fbidder%3Dadform%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID"))
-	syncer := NewAdformSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("1", "BONciguONcjGKADACHENAOLS1rAHDAFAAEAASABQAMwAeACEAFw")
+	syncURL := "//cm.adform.net?return_url=localhost%2Fsetuid%3Fbidder%3Dadform%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewAdformSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{
+		GDPR: gdpr.Policy{
+			Signal:  "1",
+			Consent: "BONciguONcjGKADACHENAOLS1rAHDAFAAEAASABQAMwAeACEAFw",
+		},
+	})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "//cm.adform.net?return_url=localhost%2Fsetuid%3Fbidder%3Dadform%26gdpr%3D1%26gdpr_consent%3DBONciguONcjGKADACHENAOLS1rAHDAFAAEAASABQAMwAeACEAFw%26uid%3D%24UID", syncInfo.URL)
 	assert.Equal(t, "redirect", syncInfo.Type)
diff --git a/adapters/adkernel/usersync_test.go b/adapters/adkernel/usersync_test.go
index d54322db..bd09c361 100644
--- a/adapters/adkernel/usersync_test.go
+++ b/adapters/adkernel/usersync_test.go
@@ -4,13 +4,25 @@ import (
 	"testing"
 	"text/template"
 
+	"github.com/prebid/prebid-server/privacy"
+	"github.com/prebid/prebid-server/privacy/gdpr"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestAdkernelAdnSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("https://sync.adkernel.com/user-sync?t=image&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&r=https%3A%2F%2Flocalhost%3A8888%2Fsetuid%3Fbidder%3Dadkernel%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%7BUID%7D"))
-	syncer := NewAdkernelSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("1", "BONciguONcjGKADACHENAOLS1rAHDAFAAEAASABQAMwAeACEAFw")
+	syncURL := "https://sync.adkernel.com/user-sync?t=image&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&r=https%3A%2F%2Flocalhost%3A8888%2Fsetuid%3Fbidder%3Dadkernel%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%7BUID%7D"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewAdkernelSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{
+		GDPR: gdpr.Policy{
+			Signal:  "1",
+			Consent: "BONciguONcjGKADACHENAOLS1rAHDAFAAEAASABQAMwAeACEAFw",
+		},
+	})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "https://sync.adkernel.com/user-sync?t=image&gdpr=1&gdpr_consent=BONciguONcjGKADACHENAOLS1rAHDAFAAEAASABQAMwAeACEAFw&r=https%3A%2F%2Flocalhost%3A8888%2Fsetuid%3Fbidder%3Dadkernel%26gdpr%3D1%26gdpr_consent%3DBONciguONcjGKADACHENAOLS1rAHDAFAAEAASABQAMwAeACEAFw%26uid%3D%7BUID%7D", syncInfo.URL)
 	assert.Equal(t, "redirect", syncInfo.Type)
diff --git a/adapters/adkernelAdn/usersync_test.go b/adapters/adkernelAdn/usersync_test.go
index 3da1ed95..007cacce 100644
--- a/adapters/adkernelAdn/usersync_test.go
+++ b/adapters/adkernelAdn/usersync_test.go
@@ -4,13 +4,25 @@ import (
 	"testing"
 	"text/template"
 
+	"github.com/prebid/prebid-server/privacy"
+	"github.com/prebid/prebid-server/privacy/gdpr"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestAdkernelAdnSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("https://tag.adkernel.com/syncr?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&r=https%3A%2F%2Flocalhost%3A8888%2Fsetuid%3Fbidder%3DadkernelAdn%26uid%3D%7BUID%7D"))
-	syncer := NewAdkernelAdnSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("1", "BONciguONcjGKADACHENAOLS1rAHDAFAAEAASABQAMwAeACEAFw")
+	syncURL := "https://tag.adkernel.com/syncr?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&r=https%3A%2F%2Flocalhost%3A8888%2Fsetuid%3Fbidder%3DadkernelAdn%26uid%3D%7BUID%7D"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewAdkernelAdnSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{
+		GDPR: gdpr.Policy{
+			Signal:  "1",
+			Consent: "BONciguONcjGKADACHENAOLS1rAHDAFAAEAASABQAMwAeACEAFw",
+		},
+	})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "https://tag.adkernel.com/syncr?gdpr=1&gdpr_consent=BONciguONcjGKADACHENAOLS1rAHDAFAAEAASABQAMwAeACEAFw&r=https%3A%2F%2Flocalhost%3A8888%2Fsetuid%3Fbidder%3DadkernelAdn%26uid%3D%7BUID%7D", syncInfo.URL)
 	assert.Equal(t, "redirect", syncInfo.Type)
diff --git a/adapters/adpone/usersync_test.go b/adapters/adpone/usersync_test.go
index ad662f14..87b4e9ae 100644
--- a/adapters/adpone/usersync_test.go
+++ b/adapters/adpone/usersync_test.go
@@ -4,13 +4,19 @@ import (
 	"testing"
 	"text/template"
 
+	"github.com/prebid/prebid-server/privacy"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestAdponeSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("https://usersync.adpone.com/csync?t=p&ep=0&redir=localhost%2Fsetuid%3Fbidder%3Dadtelligent%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%7Buid%7D"))
-	syncer := NewadponeSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("", "")
+	syncURL := "https://usersync.adpone.com/csync?t=p&ep=0&redir=localhost%2Fsetuid%3Fbidder%3Dadtelligent%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%7Buid%7D"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewadponeSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "https://usersync.adpone.com/csync?t=p&ep=0&redir=localhost%2Fsetuid%3Fbidder%3Dadtelligent%26gdpr%3D%26gdpr_consent%3D%26uid%3D%7Buid%7D", syncInfo.URL)
 	assert.Equal(t, "redirect", syncInfo.Type)
diff --git a/adapters/adtelligent/usersync_test.go b/adapters/adtelligent/usersync_test.go
index ca921dff..1cc5dfe4 100644
--- a/adapters/adtelligent/usersync_test.go
+++ b/adapters/adtelligent/usersync_test.go
@@ -4,13 +4,24 @@ import (
 	"testing"
 	"text/template"
 
+	"github.com/prebid/prebid-server/privacy"
+	"github.com/prebid/prebid-server/privacy/gdpr"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestAdtelligentSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("//sync.adtelligent.com/csync?t=p&ep=0&redir=localhost%2Fsetuid%3Fbidder%3Dadtelligent%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%7Buid%7D"))
-	syncer := NewAdtelligentSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("0", "")
+	syncURL := "//sync.adtelligent.com/csync?t=p&ep=0&redir=localhost%2Fsetuid%3Fbidder%3Dadtelligent%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%7Buid%7D"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewAdtelligentSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{
+		GDPR: gdpr.Policy{
+			Signal: "0",
+		},
+	})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "//sync.adtelligent.com/csync?t=p&ep=0&redir=localhost%2Fsetuid%3Fbidder%3Dadtelligent%26gdpr%3D0%26gdpr_consent%3D%26uid%3D%7Buid%7D", syncInfo.URL)
 	assert.Equal(t, "redirect", syncInfo.Type)
diff --git a/adapters/advangelists/usersync_test.go b/adapters/advangelists/usersync_test.go
index 8880788c..b97652c1 100644
--- a/adapters/advangelists/usersync_test.go
+++ b/adapters/advangelists/usersync_test.go
@@ -4,13 +4,25 @@ import (
 	"testing"
 	"text/template"
 
+	"github.com/prebid/prebid-server/privacy"
+	"github.com/prebid/prebid-server/privacy/gdpr"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestAdvangelistsSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("https://nep.advangelists.com/xp/user-sync?acctid={aid}&&redirect=localhost/setuid?bidder=advangelists&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&uid=$UID"))
-	syncer := NewAdvangelistsSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("1", "BOPVK28OVJoTBABABAENBs-AAAAhuAKAANAAoACwAGgAPAAxAB0AHgAQAAiABOADkA")
+	syncURL := "https://nep.advangelists.com/xp/user-sync?acctid={aid}&&redirect=localhost/setuid?bidder=advangelists&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&uid=$UID"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewAdvangelistsSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{
+		GDPR: gdpr.Policy{
+			Signal:  "1",
+			Consent: "BOPVK28OVJoTBABABAENBs-AAAAhuAKAANAAoACwAGgAPAAxAB0AHgAQAAiABOADkA",
+		},
+	})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "https://nep.advangelists.com/xp/user-sync?acctid={aid}&&redirect=localhost/setuid?bidder=advangelists&gdpr=1&gdpr_consent=BOPVK28OVJoTBABABAENBs-AAAAhuAKAANAAoACwAGgAPAAxAB0AHgAQAAiABOADkA&uid=$UID", syncInfo.URL)
 	assert.Equal(t, "iframe", syncInfo.Type)
diff --git a/adapters/appnexus/usersync_test.go b/adapters/appnexus/usersync_test.go
index 49b68f03..24b9eede 100644
--- a/adapters/appnexus/usersync_test.go
+++ b/adapters/appnexus/usersync_test.go
@@ -4,13 +4,19 @@ import (
 	"testing"
 	"text/template"
 
+	"github.com/prebid/prebid-server/privacy"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestAppNexusSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("//ib.adnxs.com/getuid?https%3A%2F%2Fprebid.adnxs.com%2Fpbs%2Fv1%2Fsetuid%3Fbidder%3Dadnxs%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID"))
-	syncer := NewAppnexusSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("", "")
+	syncURL := "//ib.adnxs.com/getuid?https%3A%2F%2Fprebid.adnxs.com%2Fpbs%2Fv1%2Fsetuid%3Fbidder%3Dadnxs%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewAppnexusSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "//ib.adnxs.com/getuid?https%3A%2F%2Fprebid.adnxs.com%2Fpbs%2Fv1%2Fsetuid%3Fbidder%3Dadnxs%26gdpr%3D%26gdpr_consent%3D%26uid%3D%24UID", syncInfo.URL)
 	assert.Equal(t, "redirect", syncInfo.Type)
diff --git a/adapters/audienceNetwork/usersync_test.go b/adapters/audienceNetwork/usersync_test.go
index 843d67a0..c3836e4f 100644
--- a/adapters/audienceNetwork/usersync_test.go
+++ b/adapters/audienceNetwork/usersync_test.go
@@ -4,13 +4,19 @@ import (
 	"testing"
 	"text/template"
 
+	"github.com/prebid/prebid-server/privacy"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestFacebookSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("https://www.facebook.com/audiencenetwork/idsync/?partner=partnerId&callback=localhost%2Fsetuid%3Fbidder%3DaudienceNetwork%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID"))
-	syncer := NewFacebookSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("", "")
+	syncURL := "https://www.facebook.com/audiencenetwork/idsync/?partner=partnerId&callback=localhost%2Fsetuid%3Fbidder%3DaudienceNetwork%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewFacebookSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "https://www.facebook.com/audiencenetwork/idsync/?partner=partnerId&callback=localhost%2Fsetuid%3Fbidder%3DaudienceNetwork%26gdpr%3D%26gdpr_consent%3D%26uid%3D%24UID", syncInfo.URL)
 	assert.Equal(t, "redirect", syncInfo.Type)
diff --git a/adapters/beachfront/usersync_test.go b/adapters/beachfront/usersync_test.go
index 3693bcad..0b71e0f9 100644
--- a/adapters/beachfront/usersync_test.go
+++ b/adapters/beachfront/usersync_test.go
@@ -4,13 +4,19 @@ import (
 	"testing"
 	"text/template"
 
+	"github.com/prebid/prebid-server/privacy"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestBeachfrontSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("localhost"))
-	syncer := NewBeachfrontSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("", "")
+	syncURL := "localhost"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewBeachfrontSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "localhost", syncInfo.URL)
 	assert.Equal(t, "iframe", syncInfo.Type)
diff --git a/adapters/brightroll/usersync_test.go b/adapters/brightroll/usersync_test.go
index 0bf485ab..08104c04 100644
--- a/adapters/brightroll/usersync_test.go
+++ b/adapters/brightroll/usersync_test.go
@@ -4,13 +4,19 @@ import (
 	"testing"
 	"text/template"
 
+	"github.com/prebid/prebid-server/privacy"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestBrightrollSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("http://test-bh.ybp.yahoo.com/sync/appnexuspbs?gdpr={{.GDPR}}&euconsent={{.GDPRConsent}}&url=localhost%2Fsetuid%3Fbidder%3Dbrightroll%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24%7BUID%7D"))
-	syncer := NewBrightrollSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("", "")
+	syncURL := "http://test-bh.ybp.yahoo.com/sync/appnexuspbs?gdpr={{.GDPR}}&euconsent={{.GDPRConsent}}&url=localhost%2Fsetuid%3Fbidder%3Dbrightroll%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24%7BUID%7D"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewBrightrollSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "http://test-bh.ybp.yahoo.com/sync/appnexuspbs?gdpr=&euconsent=&url=localhost%2Fsetuid%3Fbidder%3Dbrightroll%26gdpr%3D%26gdpr_consent%3D%26uid%3D%24%7BUID%7D", syncInfo.URL)
 	assert.Equal(t, "redirect", syncInfo.Type)
diff --git a/adapters/consumable/usersync_test.go b/adapters/consumable/usersync_test.go
index 297a863a..7def6be0 100644
--- a/adapters/consumable/usersync_test.go
+++ b/adapters/consumable/usersync_test.go
@@ -4,17 +4,25 @@ import (
 	"testing"
 	"text/template"
 
+	"github.com/prebid/prebid-server/privacy"
+	"github.com/prebid/prebid-server/privacy/gdpr"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestConsumableSyncer(t *testing.T) {
+	syncURL := "//e.serverbid.com/udb/9969/match?redir=http%3A%2F%2Flocalhost%3A8000%2Fsetuid%3Fbidder%3Dconsumable%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
 
-	temp := template.Must(template.New("sync-template").Parse(
-		"//e.serverbid.com/udb/9969/match?redir=http%3A%2F%2Flocalhost%3A8000%2Fsetuid%3Fbidder%3Dconsumable%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D"))
+	syncer := NewConsumableSyncer(syncURLTemplate)
+	u, err := syncer.GetUsersyncInfo(privacy.Policies{
+		GDPR: gdpr.Policy{
+			Signal: "0",
+		},
+	})
 
-	syncer := NewConsumableSyncer(temp)
-
-	u, _ := syncer.GetUsersyncInfo("0", "")
+	assert.NoError(t, err)
 	assert.Equal(t, "//e.serverbid.com/udb/9969/match?redir=http%3A%2F%2Flocalhost%3A8000%2Fsetuid%3Fbidder%3Dconsumable%26gdpr%3D0%26gdpr_consent%3D%26uid%3D", u.URL)
 	assert.Equal(t, "redirect", u.Type)
 	assert.Equal(t, uint16(65535), syncer.GDPRVendorID())
diff --git a/adapters/conversant/usersync_test.go b/adapters/conversant/usersync_test.go
index afbac845..16affbd1 100644
--- a/adapters/conversant/usersync_test.go
+++ b/adapters/conversant/usersync_test.go
@@ -4,13 +4,24 @@ import (
 	"testing"
 	"text/template"
 
+	"github.com/prebid/prebid-server/privacy"
+	"github.com/prebid/prebid-server/privacy/gdpr"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestConversantSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("usersync?rurl=localhost%2Fsetuid%3Fbidder%3Dconversant%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D"))
-	syncer := NewConversantSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("0", "")
+	syncURL := "usersync?rurl=localhost%2Fsetuid%3Fbidder%3Dconversant%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewConversantSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{
+		GDPR: gdpr.Policy{
+			Signal: "0",
+		},
+	})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "usersync?rurl=localhost%2Fsetuid%3Fbidder%3Dconversant%26gdpr%3D0%26gdpr_consent%3D%26uid%3D", syncInfo.URL)
 	assert.Equal(t, "redirect", syncInfo.Type)
diff --git a/adapters/datablocks/usersync_test.go b/adapters/datablocks/usersync_test.go
index f91fc94a..9dcaf829 100644
--- a/adapters/datablocks/usersync_test.go
+++ b/adapters/datablocks/usersync_test.go
@@ -1,15 +1,28 @@
 package datablocks
 
 import (
-	"github.com/stretchr/testify/assert"
 	"testing"
 	"text/template"
+
+	"github.com/prebid/prebid-server/privacy"
+	"github.com/prebid/prebid-server/privacy/gdpr"
+	"github.com/stretchr/testify/assert"
 )
 
 func TestDatablocksSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("https://sync.v5prebid.datablocks.net/s2ssync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&r=https%3A%2F%2Flocalhost%3A8888%2Fsetuid%3Fbidder%3Ddatablocks%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24%7Buid%7D"))
-	syncer := NewDatablocksSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("1", "BONciguONcjGKADACHENAOLS1rAHDAFAAEAASABQAMwAeACEAFw")
+	syncURL := "https://sync.v5prebid.datablocks.net/s2ssync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&r=https%3A%2F%2Flocalhost%3A8888%2Fsetuid%3Fbidder%3Ddatablocks%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24%7Buid%7D"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewDatablocksSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{
+		GDPR: gdpr.Policy{
+			Signal:  "1",
+			Consent: "BONciguONcjGKADACHENAOLS1rAHDAFAAEAASABQAMwAeACEAFw",
+		},
+	})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "https://sync.v5prebid.datablocks.net/s2ssync?gdpr=1&gdpr_consent=BONciguONcjGKADACHENAOLS1rAHDAFAAEAASABQAMwAeACEAFw&r=https%3A%2F%2Flocalhost%3A8888%2Fsetuid%3Fbidder%3Ddatablocks%26gdpr%3D1%26gdpr_consent%3DBONciguONcjGKADACHENAOLS1rAHDAFAAEAASABQAMwAeACEAFw%26uid%3D%24%7Buid%7D", syncInfo.URL)
 	assert.Equal(t, "redirect", syncInfo.Type)
diff --git a/adapters/emx_digital/usersync_test.go b/adapters/emx_digital/usersync_test.go
index 34ec28dc..d8f874c8 100644
--- a/adapters/emx_digital/usersync_test.go
+++ b/adapters/emx_digital/usersync_test.go
@@ -4,13 +4,25 @@ import (
 	"testing"
 	"text/template"
 
+	"github.com/prebid/prebid-server/privacy"
+	"github.com/prebid/prebid-server/privacy/gdpr"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestEMXDigitalSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("https://cs.emxdgt.com/um?ssp=pbs&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&redirect=localhost%2Fsetuid%3Fbidder%3Demx_digital%26uid%3D%24UID"))
-	syncer := NewEMXDigitalSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("1", "BOPVK28OVJoTBABABAENBs-AAAAhuAKAANAAoACwAGgAPAAxAB0AHgAQAAiABOADkA")
+	syncURL := "https://cs.emxdgt.com/um?ssp=pbs&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&redirect=localhost%2Fsetuid%3Fbidder%3Demx_digital%26uid%3D%24UID"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewEMXDigitalSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{
+		GDPR: gdpr.Policy{
+			Signal:  "1",
+			Consent: "BOPVK28OVJoTBABABAENBs-AAAAhuAKAANAAoACwAGgAPAAxAB0AHgAQAAiABOADkA",
+		},
+	})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "https://cs.emxdgt.com/um?ssp=pbs&gdpr=1&gdpr_consent=BOPVK28OVJoTBABABAENBs-AAAAhuAKAANAAoACwAGgAPAAxAB0AHgAQAAiABOADkA&redirect=localhost%2Fsetuid%3Fbidder%3Demx_digital%26uid%3D%24UID", syncInfo.URL)
 	assert.Equal(t, "iframe", syncInfo.Type)
diff --git a/adapters/engagebdr/usersync_test.go b/adapters/engagebdr/usersync_test.go
index 1e24ff5e..fbcde923 100644
--- a/adapters/engagebdr/usersync_test.go
+++ b/adapters/engagebdr/usersync_test.go
@@ -1,15 +1,28 @@
 package engagebdr
 
 import (
-	"github.com/stretchr/testify/assert"
 	"testing"
 	"text/template"
+
+	"github.com/prebid/prebid-server/privacy"
+	"github.com/prebid/prebid-server/privacy/gdpr"
+	"github.com/stretchr/testify/assert"
 )
 
 func TestEngageBDRSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("https://match.bnmla.com/usersync/prbds2s?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&r=localhost%2Fsetuid%3Fbidder%3Dgumgum%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D"))
-	syncer := NewEngageBDRSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("1", "BOPVK28OVJoTBABABAENBs-AAAAhuAKAANAAoACwAGgAPAAxAB0AHgAQAAiABOADkA")
+	syncURL := "https://match.bnmla.com/usersync/prbds2s?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&r=localhost%2Fsetuid%3Fbidder%3Dgumgum%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewEngageBDRSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{
+		GDPR: gdpr.Policy{
+			Signal:  "1",
+			Consent: "BOPVK28OVJoTBABABAENBs-AAAAhuAKAANAAoACwAGgAPAAxAB0AHgAQAAiABOADkA",
+		},
+	})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "https://match.bnmla.com/usersync/prbds2s?gdpr=1&gdpr_consent=BOPVK28OVJoTBABABAENBs-AAAAhuAKAANAAoACwAGgAPAAxAB0AHgAQAAiABOADkA&r=localhost%2Fsetuid%3Fbidder%3Dgumgum%26gdpr%3D1%26gdpr_consent%3DBOPVK28OVJoTBABABAENBs-AAAAhuAKAANAAoACwAGgAPAAxAB0AHgAQAAiABOADkA%26uid%3D", syncInfo.URL)
 	assert.Equal(t, "iframe", syncInfo.Type)
diff --git a/adapters/eplanning/usersync_test.go b/adapters/eplanning/usersync_test.go
index 146f71d6..890832ba 100644
--- a/adapters/eplanning/usersync_test.go
+++ b/adapters/eplanning/usersync_test.go
@@ -4,13 +4,19 @@ import (
 	"testing"
 	"text/template"
 
+	"github.com/prebid/prebid-server/privacy"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestEPlanningSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("https://ads.us.e-planning.net/uspd/1/?du=https%3A%2F%2Fads.us.e-planning.net%2Fgetuid%2F1%2F5a1ad71d2d53a0f5%3Flocalhost%2Fsetuid%3Fbidder%3Deplanning%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID"))
-	syncer := NewEPlanningSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("", "")
+	syncURL := "https://ads.us.e-planning.net/uspd/1/?du=https%3A%2F%2Fads.us.e-planning.net%2Fgetuid%2F1%2F5a1ad71d2d53a0f5%3Flocalhost%2Fsetuid%3Fbidder%3Deplanning%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewEPlanningSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "https://ads.us.e-planning.net/uspd/1/?du=https%3A%2F%2Fads.us.e-planning.net%2Fgetuid%2F1%2F5a1ad71d2d53a0f5%3Flocalhost%2Fsetuid%3Fbidder%3Deplanning%26gdpr%3D%26gdpr_consent%3D%26uid%3D%24UID", syncInfo.URL)
 	assert.Equal(t, "iframe", syncInfo.Type)
diff --git a/adapters/gamma/usersync_test.go b/adapters/gamma/usersync_test.go
index 38239f4d..4278f9ab 100644
--- a/adapters/gamma/usersync_test.go
+++ b/adapters/gamma/usersync_test.go
@@ -4,13 +4,24 @@ import (
 	"testing"
 	"text/template"
 
+	"github.com/prebid/prebid-server/privacy"
+	"github.com/prebid/prebid-server/privacy/gdpr"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestGammaSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("//hb.gammaplatform.com/sync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&redirectUri=http%3A%2F%2Flocalhost%2F%2Fsetuid%3Fbidder%3Dgamma%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID"))
-	syncer := NewGammaSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("0", "")
+	syncURL := "//hb.gammaplatform.com/sync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&redirectUri=http%3A%2F%2Flocalhost%2F%2Fsetuid%3Fbidder%3Dgamma%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewGammaSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{
+		GDPR: gdpr.Policy{
+			Signal: "0",
+		},
+	})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "//hb.gammaplatform.com/sync?gdpr=0&gdpr_consent=&redirectUri=http%3A%2F%2Flocalhost%2F%2Fsetuid%3Fbidder%3Dgamma%26gdpr%3D0%26gdpr_consent%3D%26uid%3D%24UID", syncInfo.URL)
 	assert.Equal(t, "iframe", syncInfo.Type)
diff --git a/adapters/gamoshi/usersync_test.go b/adapters/gamoshi/usersync_test.go
index 21b8bd80..10e23c02 100644
--- a/adapters/gamoshi/usersync_test.go
+++ b/adapters/gamoshi/usersync_test.go
@@ -4,14 +4,19 @@ import (
 	"testing"
 	"text/template"
 
+	"github.com/prebid/prebid-server/privacy"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestGamoshiSyncer(t *testing.T) {
+	syncURL := "https://rtb.gamoshi.io/pix/1707/scm?gdpr={{.GDPR}}&consent={{.GDPRConsent}}&rurl=localhost/setuid%3Fbidder%3Dgamoshi%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%5Bgusr%5D"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewGamoshiSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{})
 
-	temp := template.Must(template.New("sync-template").Parse("https://rtb.gamoshi.io/pix/1707/scm?gdpr={{.GDPR}}&consent={{.GDPRConsent}}&rurl=localhost/setuid%3Fbidder%3Dgamoshi%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%5Bgusr%5D"))
-	syncer := NewGamoshiSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("", "")
 	assert.NoError(t, err)
 	assert.Equal(t, "https://rtb.gamoshi.io/pix/1707/scm?gdpr=&consent=&rurl=localhost/setuid%3Fbidder%3Dgamoshi%26gdpr%3D%26gdpr_consent%3D%26uid%3D%5Bgusr%5D", syncInfo.URL)
 	assert.Equal(t, "redirect", syncInfo.Type)
diff --git a/adapters/grid/usersync_test.go b/adapters/grid/usersync_test.go
index 6ce58bcb..9b97f605 100644
--- a/adapters/grid/usersync_test.go
+++ b/adapters/grid/usersync_test.go
@@ -4,13 +4,24 @@ import (
 	"testing"
 	"text/template"
 
+	"github.com/prebid/prebid-server/privacy"
+	"github.com/prebid/prebid-server/privacy/gdpr"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestGridSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("//not_localhost/synclocalhost%2Fsetuid%3Fbidder%3Dgrid%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID"))
-	syncer := NewGridSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("0", "")
+	syncURL := "//not_localhost/synclocalhost%2Fsetuid%3Fbidder%3Dgrid%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewGridSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{
+		GDPR: gdpr.Policy{
+			Signal: "0",
+		},
+	})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "//not_localhost/synclocalhost%2Fsetuid%3Fbidder%3Dgrid%26gdpr%3D0%26gdpr_consent%3D%26uid%3D%24UID", syncInfo.URL)
 	assert.Equal(t, "redirect", syncInfo.Type)
diff --git a/adapters/gumgum/usersync_test.go b/adapters/gumgum/usersync_test.go
index 6f5ae965..22c42695 100644
--- a/adapters/gumgum/usersync_test.go
+++ b/adapters/gumgum/usersync_test.go
@@ -4,13 +4,25 @@ import (
 	"testing"
 	"text/template"
 
+	"github.com/prebid/prebid-server/privacy"
+	"github.com/prebid/prebid-server/privacy/gdpr"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestGumGumSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("https://rtb.gumgum.com/usync/prbds2s?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&r=localhost%2Fsetuid%3Fbidder%3Dgumgum%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D"))
-	syncer := NewGumGumSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("1", "BOPVK28OVJoTBABABAENBs-AAAAhuAKAANAAoACwAGgAPAAxAB0AHgAQAAiABOADkA")
+	syncURL := "https://rtb.gumgum.com/usync/prbds2s?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&r=localhost%2Fsetuid%3Fbidder%3Dgumgum%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewGumGumSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{
+		GDPR: gdpr.Policy{
+			Signal:  "1",
+			Consent: "BOPVK28OVJoTBABABAENBs-AAAAhuAKAANAAoACwAGgAPAAxAB0AHgAQAAiABOADkA",
+		},
+	})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "https://rtb.gumgum.com/usync/prbds2s?gdpr=1&gdpr_consent=BOPVK28OVJoTBABABAENBs-AAAAhuAKAANAAoACwAGgAPAAxAB0AHgAQAAiABOADkA&r=localhost%2Fsetuid%3Fbidder%3Dgumgum%26gdpr%3D1%26gdpr_consent%3DBOPVK28OVJoTBABABAENBs-AAAAhuAKAANAAoACwAGgAPAAxAB0AHgAQAAiABOADkA%26uid%3D", syncInfo.URL)
 	assert.Equal(t, "iframe", syncInfo.Type)
diff --git a/adapters/improvedigital/usersync_test.go b/adapters/improvedigital/usersync_test.go
index 06c4ec10..861e4875 100644
--- a/adapters/improvedigital/usersync_test.go
+++ b/adapters/improvedigital/usersync_test.go
@@ -4,13 +4,24 @@ import (
 	"testing"
 	"text/template"
 
+	"github.com/prebid/prebid-server/privacy"
+	"github.com/prebid/prebid-server/privacy/gdpr"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestImprovedigitalSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("//not_localhost/synclocalhost%2Fsetuid%3Fbidder%3Dimprovedigital%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%7BPUB_USER_ID%7D"))
-	syncer := NewImprovedigitalSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("0", "")
+	syncURL := "//not_localhost/synclocalhost%2Fsetuid%3Fbidder%3Dimprovedigital%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%7BPUB_USER_ID%7D"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewImprovedigitalSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{
+		GDPR: gdpr.Policy{
+			Signal: "0",
+		},
+	})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "//not_localhost/synclocalhost%2Fsetuid%3Fbidder%3Dimprovedigital%26gdpr%3D0%26gdpr_consent%3D%26uid%3D%7BPUB_USER_ID%7D", syncInfo.URL)
 	assert.Equal(t, "redirect", syncInfo.Type)
diff --git a/adapters/ix/usersync_test.go b/adapters/ix/usersync_test.go
index a0c15c40..10f91da1 100644
--- a/adapters/ix/usersync_test.go
+++ b/adapters/ix/usersync_test.go
@@ -4,13 +4,19 @@ import (
 	"testing"
 	"text/template"
 
+	"github.com/prebid/prebid-server/privacy"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestIxSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("//ssum-sec.casalemedia.com/usermatchredir?s=184932&cb=localhost%2Fsetuid%3Fbidder%3Dix%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D"))
-	syncer := NewIxSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("", "")
+	syncURL := "//ssum-sec.casalemedia.com/usermatchredir?s=184932&cb=localhost%2Fsetuid%3Fbidder%3Dix%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewIxSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "//ssum-sec.casalemedia.com/usermatchredir?s=184932&cb=localhost%2Fsetuid%3Fbidder%3Dix%26gdpr%3D%26gdpr_consent%3D%26uid%3D", syncInfo.URL)
 	assert.Equal(t, "redirect", syncInfo.Type)
diff --git a/adapters/lifestreet/usersync_test.go b/adapters/lifestreet/usersync_test.go
index 138aed76..8fee0935 100644
--- a/adapters/lifestreet/usersync_test.go
+++ b/adapters/lifestreet/usersync_test.go
@@ -4,13 +4,24 @@ import (
 	"testing"
 	"text/template"
 
+	"github.com/prebid/prebid-server/privacy"
+	"github.com/prebid/prebid-server/privacy/gdpr"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestLifestreetSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("//ads.lfstmedia.com/idsync/137062?synced=1&ttl=1s&rurl=localhost%2Fsetuid%3Fbidder%3Dlifestreet%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24%24visitor_cookie%24%24"))
-	syncer := NewLifestreetSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("0", "")
+	syncURL := "//ads.lfstmedia.com/idsync/137062?synced=1&ttl=1s&rurl=localhost%2Fsetuid%3Fbidder%3Dlifestreet%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24%24visitor_cookie%24%24"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewLifestreetSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{
+		GDPR: gdpr.Policy{
+			Signal: "0",
+		},
+	})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "//ads.lfstmedia.com/idsync/137062?synced=1&ttl=1s&rurl=localhost%2Fsetuid%3Fbidder%3Dlifestreet%26gdpr%3D0%26gdpr_consent%3D%26uid%3D%24%24visitor_cookie%24%24", syncInfo.URL)
 	assert.Equal(t, "redirect", syncInfo.Type)
diff --git a/adapters/lockerdome/usersync_test.go b/adapters/lockerdome/usersync_test.go
index b7466ef2..b0307c0f 100644
--- a/adapters/lockerdome/usersync_test.go
+++ b/adapters/lockerdome/usersync_test.go
@@ -4,13 +4,19 @@ import (
 	"testing"
 	"text/template"
 
+	"github.com/prebid/prebid-server/privacy"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestLockerDomeSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("https://lockerdome.com/usync/prebidserver?pid=&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&redirect=https%3A%2F%2Flocalhost%2Fsetuid%3Fbidder%3Dlockerdome%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%7B%7Buid%7D%7D"))
-	syncer := NewLockerDomeSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("", "")
+	syncURL := "https://lockerdome.com/usync/prebidserver?pid=&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&redirect=https%3A%2F%2Flocalhost%2Fsetuid%3Fbidder%3Dlockerdome%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%7B%7Buid%7D%7D"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewLockerDomeSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "https://lockerdome.com/usync/prebidserver?pid=&gdpr=&gdpr_consent=&redirect=https%3A%2F%2Flocalhost%2Fsetuid%3Fbidder%3Dlockerdome%26gdpr%3D%26gdpr_consent%3D%26uid%3D%7B%7Buid%7D%7D", syncInfo.URL)
 	assert.Equal(t, "redirect", syncInfo.Type)
diff --git a/adapters/mgid/usersync_test.go b/adapters/mgid/usersync_test.go
index 7bb4d1e0..2ce634ee 100644
--- a/adapters/mgid/usersync_test.go
+++ b/adapters/mgid/usersync_test.go
@@ -1,15 +1,27 @@
 package mgid
 
 import (
-	"github.com/stretchr/testify/assert"
 	"testing"
 	"text/template"
+
+	"github.com/prebid/prebid-server/privacy"
+	"github.com/prebid/prebid-server/privacy/gdpr"
+	"github.com/stretchr/testify/assert"
 )
 
 func TestMgidSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("https://cm.mgid.com/m?cdsp=363893&adu=https%3A//external.com%2Fsetuid%3Fbidder%3Dmgid%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%7Bmuidn%7D"))
-	syncer := NewMgidSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("0", "")
+	syncURL := "https://cm.mgid.com/m?cdsp=363893&adu=https%3A//external.com%2Fsetuid%3Fbidder%3Dmgid%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%7Bmuidn%7D"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewMgidSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{
+		GDPR: gdpr.Policy{
+			Signal: "0",
+		},
+	})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "https://cm.mgid.com/m?cdsp=363893&adu=https%3A//external.com%2Fsetuid%3Fbidder%3Dmgid%26gdpr%3D0%26gdpr_consent%3D%26uid%3D%7Bmuidn%7D", syncInfo.URL)
 	assert.Equal(t, "redirect", syncInfo.Type)
diff --git a/adapters/openx/usersync_test.go b/adapters/openx/usersync_test.go
index 5453fbef..86f9bb01 100644
--- a/adapters/openx/usersync_test.go
+++ b/adapters/openx/usersync_test.go
@@ -4,13 +4,19 @@ import (
 	"testing"
 	"text/template"
 
+	"github.com/prebid/prebid-server/privacy"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestOpenxSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("https://rtb.openx.net/sync/prebid?r=localhost%2Fsetuid%3Fbidder%3Dopenx%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24%7BUID%7D"))
-	syncer := NewOpenxSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("", "")
+	syncURL := "https://rtb.openx.net/sync/prebid?r=localhost%2Fsetuid%3Fbidder%3Dopenx%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24%7BUID%7D"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewOpenxSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "https://rtb.openx.net/sync/prebid?r=localhost%2Fsetuid%3Fbidder%3Dopenx%26gdpr%3D%26gdpr_consent%3D%26uid%3D%24%7BUID%7D", syncInfo.URL)
 	assert.Equal(t, "redirect", syncInfo.Type)
diff --git a/adapters/pubmatic/usersync_test.go b/adapters/pubmatic/usersync_test.go
index 532eda5c..ef81d223 100644
--- a/adapters/pubmatic/usersync_test.go
+++ b/adapters/pubmatic/usersync_test.go
@@ -4,13 +4,25 @@ import (
 	"testing"
 	"text/template"
 
+	"github.com/prebid/prebid-server/privacy"
+	"github.com/prebid/prebid-server/privacy/gdpr"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestPubmaticSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("//ads.pubmatic.com/AdServer/js/user_sync.html?predirect=localhost%2Fsetuid%3Fbidder%3Dpubmatic%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D"))
-	syncer := NewPubmaticSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("1", "BONciguONcjGKADACHENAOLS1rAHDAFAAEAASABQAMwAeACEAFw")
+	syncURL := "//ads.pubmatic.com/AdServer/js/user_sync.html?predirect=localhost%2Fsetuid%3Fbidder%3Dpubmatic%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewPubmaticSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{
+		GDPR: gdpr.Policy{
+			Signal:  "1",
+			Consent: "BONciguONcjGKADACHENAOLS1rAHDAFAAEAASABQAMwAeACEAFw",
+		},
+	})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "//ads.pubmatic.com/AdServer/js/user_sync.html?predirect=localhost%2Fsetuid%3Fbidder%3Dpubmatic%26gdpr%3D1%26gdpr_consent%3DBONciguONcjGKADACHENAOLS1rAHDAFAAEAASABQAMwAeACEAFw%26uid%3D", syncInfo.URL)
 	assert.Equal(t, "iframe", syncInfo.Type)
diff --git a/adapters/pulsepoint/usersync_test.go b/adapters/pulsepoint/usersync_test.go
index 28d31077..e1680fd2 100644
--- a/adapters/pulsepoint/usersync_test.go
+++ b/adapters/pulsepoint/usersync_test.go
@@ -4,13 +4,19 @@ import (
 	"testing"
 	"text/template"
 
+	"github.com/prebid/prebid-server/privacy"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestPulsepointSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("//bh.contextweb.com/rtset?pid=561205&ev=1&rurl=http%3A%2F%2Flocalhost%2Fsetuid%3Fbidder%3Dpulsepoint%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%25%25VGUID%25%25"))
-	syncer := NewPulsepointSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("", "")
+	syncURL := "//bh.contextweb.com/rtset?pid=561205&ev=1&rurl=http%3A%2F%2Flocalhost%2Fsetuid%3Fbidder%3Dpulsepoint%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%25%25VGUID%25%25"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewPulsepointSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "//bh.contextweb.com/rtset?pid=561205&ev=1&rurl=http%3A%2F%2Flocalhost%2Fsetuid%3Fbidder%3Dpulsepoint%26gdpr%3D%26gdpr_consent%3D%26uid%3D%25%25VGUID%25%25", syncInfo.URL)
 	assert.Equal(t, "redirect", syncInfo.Type)
diff --git a/adapters/rhythmone/usersync_test.go b/adapters/rhythmone/usersync_test.go
index 0ec6d157..0dcf4fbd 100644
--- a/adapters/rhythmone/usersync_test.go
+++ b/adapters/rhythmone/usersync_test.go
@@ -4,13 +4,25 @@ import (
 	"testing"
 	"text/template"
 
+	"github.com/prebid/prebid-server/privacy"
+	"github.com/prebid/prebid-server/privacy/gdpr"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestRhythmoneSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("https://sync.1rx.io/usersync2/rmphb?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&redir=localhost%2Fsetuid%3Fbidder%3Drhythmone%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%5BRX_UUID%5D"))
-	syncer := NewRhythmoneSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("1", "BOPVK28OVJoTBABABAENBs-AAAAhuAKAANAAoACwAGgAPAAxAB0AHgAQAAiABOADkA")
+	syncURL := "https://sync.1rx.io/usersync2/rmphb?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&redir=localhost%2Fsetuid%3Fbidder%3Drhythmone%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%5BRX_UUID%5D"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewRhythmoneSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{
+		GDPR: gdpr.Policy{
+			Signal:  "1",
+			Consent: "BOPVK28OVJoTBABABAENBs-AAAAhuAKAANAAoACwAGgAPAAxAB0AHgAQAAiABOADkA",
+		},
+	})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "https://sync.1rx.io/usersync2/rmphb?gdpr=1&gdpr_consent=BOPVK28OVJoTBABABAENBs-AAAAhuAKAANAAoACwAGgAPAAxAB0AHgAQAAiABOADkA&redir=localhost%2Fsetuid%3Fbidder%3Drhythmone%26gdpr%3D1%26gdpr_consent%3DBOPVK28OVJoTBABABAENBs-AAAAhuAKAANAAoACwAGgAPAAxAB0AHgAQAAiABOADkA%26uid%3D%5BRX_UUID%5D", syncInfo.URL)
 	assert.Equal(t, "redirect", syncInfo.Type)
diff --git a/adapters/rtbhouse/usersync_test.go b/adapters/rtbhouse/usersync_test.go
index d73cc3b5..bb139f7a 100644
--- a/adapters/rtbhouse/usersync_test.go
+++ b/adapters/rtbhouse/usersync_test.go
@@ -4,16 +4,23 @@ import (
 	"testing"
 	"text/template"
 
+	"github.com/prebid/prebid-server/privacy"
+	"github.com/prebid/prebid-server/privacy/gdpr"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestRTBHouseSyncer(t *testing.T) {
-	syncURLText := "https://creativecdn.com/cm-notify?pi=prebidsrvtst&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}"
+	syncURL := "https://creativecdn.com/cm-notify?pi=prebidsrvtst&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}"
 	syncURLTemplate := template.Must(
-		template.New("sync-template").Parse(syncURLText),
+		template.New("sync-template").Parse(syncURL),
 	)
+
 	syncer := NewRTBHouseSyncer(syncURLTemplate)
-	syncInfo, err := syncer.GetUsersyncInfo("0", "")
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{
+		GDPR: gdpr.Policy{
+			Signal: "0",
+		},
+	})
 
 	assert.NoError(t, err)
 	assert.Equal(t, "https://creativecdn.com/cm-notify?pi=prebidsrvtst&gdpr=0&gdpr_consent=", syncInfo.URL)
diff --git a/adapters/rubicon/rubicon_test.go b/adapters/rubicon/rubicon_test.go
index c59e1574..bc3d2e8a 100644
--- a/adapters/rubicon/rubicon_test.go
+++ b/adapters/rubicon/rubicon_test.go
@@ -7,7 +7,6 @@ import (
 	"io/ioutil"
 	"net/http"
 	"net/http/httptest"
-	"reflect"
 	"testing"
 	"time"
 
@@ -24,6 +23,8 @@ import (
 	"github.com/prebid/prebid-server/adapters"
 	"github.com/prebid/prebid-server/config"
 	"github.com/prebid/prebid-server/openrtb_ext"
+
+	"github.com/stretchr/testify/assert"
 )
 
 type rubiAppendTrackerUrlTestScenario struct {
@@ -64,7 +65,14 @@ type rubiBidInfo struct {
 var rubidata rubiBidInfo
 
 func DummyRubiconServer(w http.ResponseWriter, r *http.Request) {
-	defer r.Body.Close()
+	defer func() {
+		err := r.Body.Close()
+		if err != nil {
+			http.Error(w, err.Error(), http.StatusInternalServerError)
+			return
+		}
+	}()
+
 	body, err := ioutil.ReadAll(r.Body)
 	if err != nil {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
@@ -268,37 +276,28 @@ func TestRubiconBasicResponse(t *testing.T) {
 	an, ctx, pbReq := CreatePrebidRequest(server, t)
 
 	bids, err := an.Call(ctx, pbReq, pbReq.Bidders[0])
-	if err != nil {
-		t.Fatalf("Should not have gotten an error: %v", err)
-	}
-	if len(bids) != 3 {
-		t.Fatalf("Received %d bids instead of 3", len(bids))
-	}
+	assert.Nil(t, err, "Should not have gotten an error: %v", err)
+	assert.Equal(t, 3, len(bids), "Received %d bids instead of 3", len(bids))
+
 	for _, bid := range bids {
 		matched := false
 		for _, tag := range rubidata.tags {
 			if bid.AdUnitCode == tag.code {
 				matched = true
-				if bid.BidderCode != "rubicon" {
-					t.Errorf("Incorrect BidderCode '%s'", bid.BidderCode)
-				}
-				if bid.Price != tag.bid {
-					t.Errorf("Incorrect bid price '%.2f' expected '%.2f'", bid.Price, tag.bid)
-				}
-				if bid.Adm != tag.content {
-					t.Errorf("Incorrect bid markup '%s' expected '%s'", bid.Adm, tag.content)
-				}
-				if !reflect.DeepEqual(bid.AdServerTargeting, tag.adServerTargeting) {
-					t.Errorf("Incorrect targeting '%+v' expected '%+v'", bid.AdServerTargeting, tag.adServerTargeting)
-				}
-				if bid.CreativeMediaType != tag.mediaType {
-					t.Errorf("Incorrect media type '%s' expected '%s'", bid.CreativeMediaType, tag.mediaType)
-				}
+
+				assert.Equal(t, "rubicon", bid.BidderCode, "Incorrect BidderCode '%s'", bid.BidderCode)
+
+				assert.Equal(t, tag.bid, bid.Price, "Incorrect bid price '%.2f' expected '%.2f'", bid.Price, tag.bid)
+
+				assert.Equal(t, tag.content, bid.Adm, "Incorrect bid markup '%s' expected '%s'", bid.Adm, tag.content)
+
+				assert.Equal(t, bid.AdServerTargeting, tag.adServerTargeting,
+					"Incorrect targeting '%+v' expected '%+v'", bid.AdServerTargeting, tag.adServerTargeting)
+
+				assert.Equal(t, tag.mediaType, bid.CreativeMediaType, "Incorrect media type '%s' expected '%s'", bid.CreativeMediaType, tag.mediaType)
 			}
 		}
-		if !matched {
-			t.Errorf("Received bid for unknown ad unit '%s'", bid.AdUnitCode)
-		}
+		assert.True(t, matched, "Received bid for unknown ad unit '%s'", bid.AdUnitCode)
 	}
 
 	// same test but with request timing out
@@ -307,23 +306,15 @@ func TestRubiconBasicResponse(t *testing.T) {
 	defer cancel()
 
 	bids, err = an.Call(ctx, pbReq, pbReq.Bidders[0])
-	if err == nil {
-		t.Fatalf("Should have gotten a timeout error: %v", err)
-	}
+	assert.NotNil(t, err, "Should have gotten a timeout error: %v", err)
 }
 
 func TestRubiconUserSyncInfo(t *testing.T) {
 	an := NewRubiconAdapter(adapters.DefaultHTTPAdapterConfig, "uri", "xuser", "xpass", "pbs-test-tracker")
 
-	adapterName := an.Name()
-	if adapterName != "rubicon" {
-		t.Errorf("Name '%s' != 'rubicon'", adapterName)
-	}
+	assert.Equal(t, "rubicon", an.Name(), "Name '%s' != 'rubicon'", an.Name())
 
-	skipNoCookies := an.SkipNoCookies()
-	if skipNoCookies != false {
-		t.Errorf("SkipNoCookies should be false")
-	}
+	assert.False(t, an.SkipNoCookies(), "SkipNoCookies should be false")
 }
 
 func getTestSizes() map[int]openrtb.Format {
@@ -339,7 +330,6 @@ func getTestSizes() map[int]openrtb.Format {
 }
 
 func TestParseSizes(t *testing.T) {
-
 	SIZE_ID := getTestSizes()
 
 	sizes := []openrtb.Format{
@@ -347,18 +337,10 @@ func TestParseSizes(t *testing.T) {
 		SIZE_ID[15],
 	}
 	primary, alt, err := parseRubiconSizes(sizes)
-	if err != nil {
-		t.Errorf("Parsing error: %v", err)
-	}
-	if primary != 15 {
-		t.Errorf("Primary %d != 15", primary)
-	}
-	if len(alt) != 1 {
-		t.Fatalf("Alt not len 1")
-	}
-	if alt[0] != 10 {
-		t.Errorf("Alt not 10: %d", alt[0])
-	}
+	assert.Nil(t, err, "Parsing error: %v", err)
+	assert.Equal(t, 15, primary, "Primary %d != 15", primary)
+	assert.Equal(t, 1, len(alt), "Alt not len 1")
+	assert.Equal(t, 10, alt[0], "Alt not 10: %d", alt[0])
 
 	sizes = []openrtb.Format{
 		{
@@ -368,31 +350,17 @@ func TestParseSizes(t *testing.T) {
 		SIZE_ID[15],
 	}
 	primary, alt, err = parseRubiconSizes(sizes)
-
-	if err != nil {
-		t.Errorf("Shouldn't have thrown error for invalid size 1111x1111 since we still have a valid one")
-	}
-	if primary != 15 {
-		t.Errorf("Primary %d != 15", primary)
-	}
-	if len(alt) != 0 {
-		t.Fatalf("Alt len %d != 0", len(alt))
-	}
+	assert.Nil(t, err, "Shouldn't have thrown error for invalid size 1111x1111 since we still have a valid one")
+	assert.Equal(t, 15, primary, "Primary %d != 15", primary)
+	assert.Equal(t, 0, len(alt), "Alt len %d != 0", len(alt))
 
 	sizes = []openrtb.Format{
 		SIZE_ID[15],
 	}
 	primary, alt, err = parseRubiconSizes(sizes)
-
-	if err != nil {
-		t.Errorf("Parsing error: %v", err)
-	}
-	if primary != 15 {
-		t.Errorf("Primary %d != 15", primary)
-	}
-	if len(alt) != 0 {
-		t.Fatalf("Alt len %d != 0", len(alt))
-	}
+	assert.Nil(t, err, "Parsing error: %v", err)
+	assert.Equal(t, 15, primary, "Primary %d != 15", primary)
+	assert.Equal(t, 0, len(alt), "Alt len %d != 0", len(alt))
 
 	sizes = []openrtb.Format{
 		{
@@ -401,16 +369,9 @@ func TestParseSizes(t *testing.T) {
 		},
 	}
 	primary, alt, err = parseRubiconSizes(sizes)
-
-	if err == nil {
-		t.Errorf("Parsing error: %v", err)
-	}
-	if primary != 0 {
-		t.Errorf("Primary %d != 0", primary)
-	}
-	if len(alt) != 0 {
-		t.Errorf("Alt len %d != 0", len(alt))
-	}
+	assert.NotNil(t, err, "Parsing error: %v", err)
+	assert.Equal(t, 0, primary, "Primary %d != 15", primary)
+	assert.Equal(t, 0, len(alt), "Alt len %d != 0", len(alt))
 }
 
 func TestMASAlgorithm(t *testing.T) {
@@ -526,17 +487,19 @@ func TestMASAlgorithm(t *testing.T) {
 
 	for _, test := range testStubs {
 		prim, alt, err := parseRubiconSizes(test.input)
-		if prim != test.output.primary {
-			t.Fatalf("Error in parsing rubicon sizes: MAS algorithm fail at primary: testcase %v", test.input)
-		}
-		if len(alt) != len(test.output.alt) {
-			t.Fatalf("Error in parsing rubicon sizes: MAS Algorithm fail at alt: testcase %v", test.input)
-		}
-		if (err != nil && !test.output.ok) || (err == nil && test.output.ok) {
-			t.Fatalf("Error in parsing rubicon sizes: MAS Algorithm fail at throwing error: testcase %v", test.input)
-		}
-	}
 
+		assert.Equal(t, test.output.primary, prim,
+			"Error in parsing rubicon sizes: MAS algorithm fail at primary: testcase %v", test.input)
+
+		assert.Equal(t, len(test.output.alt), len(alt),
+			"Error in parsing rubicon sizes: MAS Algorithm fail at alt: testcase %v", test.input)
+
+		assert.False(t, err != nil && !test.output.ok,
+			"Error in parsing rubicon sizes: MAS Algorithm fail at throwing error: testcase %v", test.input)
+
+		assert.False(t, err == nil && test.output.ok,
+			"Error in parsing rubicon sizes: MAS Algorithm fail at throwing error: testcase %v", test.input)
+	}
 }
 
 func TestAppendTracker(t *testing.T) {
@@ -555,14 +518,11 @@ func TestAppendTracker(t *testing.T) {
 
 	for _, scenario := range testScenarios {
 		res := appendTrackerToUrl(scenario.source, scenario.tracker)
-		if res != scenario.expected {
-			t.Fatalf("Failed to convert '%s' to '%s'", res, scenario.expected)
-		}
+		assert.Equal(t, scenario.expected, res, "Failed to convert '%s' to '%s'", res, scenario.expected)
 	}
 }
 
 func TestNoContentResponse(t *testing.T) {
-
 	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 		w.WriteHeader(http.StatusNoContent)
 	}))
@@ -571,22 +531,15 @@ func TestNoContentResponse(t *testing.T) {
 	an, ctx, pbReq := CreatePrebidRequest(server, t)
 	bids, err := an.Call(ctx, pbReq, pbReq.Bidders[0])
 
-	if len(bids) != 0 {
-		t.Fatalf("Length of bids should be 0 instead of: %v", len(bids))
-	}
+	assert.Empty(t, bids, "Length of bids should be 0 instead of: %v", len(bids))
 
-	if pbReq.Bidders[0].Debug[0].StatusCode != 204 {
-		t.Fatalf("StatusCode should be 204 instead of: %v", pbReq.Bidders[0].Debug[0].StatusCode)
-	}
-
-	if err != nil {
-		t.Fatalf("Should not have gotten an error: %v", err)
-	}
+	assert.Equal(t, 204, pbReq.Bidders[0].Debug[0].StatusCode,
+		"StatusCode should be 204 instead of: %v", pbReq.Bidders[0].Debug[0].StatusCode)
 
+	assert.Nil(t, err, "Should not have gotten an error: %v", err)
 }
 
 func TestNotFoundResponse(t *testing.T) {
-
 	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 		w.WriteHeader(http.StatusNotFound)
 	}))
@@ -595,22 +548,16 @@ func TestNotFoundResponse(t *testing.T) {
 	an, ctx, pbReq := CreatePrebidRequest(server, t)
 	_, err := an.Call(ctx, pbReq, pbReq.Bidders[0])
 
-	if pbReq.Bidders[0].Debug[0].StatusCode != 404 {
-		t.Fatalf("StatusCode should be 404 instead of: %v", pbReq.Bidders[0].Debug[0].StatusCode)
-	}
-
-	if err == nil {
-		t.Fatalf("Should have gotten an error: %v", err)
-	}
+	assert.Equal(t, 404, pbReq.Bidders[0].Debug[0].StatusCode,
+		"StatusCode should be 404 instead of: %v", pbReq.Bidders[0].Debug[0].StatusCode)
 
-	if !strings.HasPrefix(err.Error(), "HTTP status 404") {
-		t.Fatalf("Should start with 'HTTP status' instead of: %v", err.Error())
-	}
+	assert.NotNil(t, err, "Should have gotten an error: %v", err)
 
+	assert.True(t, strings.HasPrefix(err.Error(), "HTTP status 404"),
+		"Should start with 'HTTP status' instead of: %v", err.Error())
 }
 
 func TestWrongFormatResponse(t *testing.T) {
-
 	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 		w.Write([]byte("This is text."))
 	}))
@@ -619,22 +566,16 @@ func TestWrongFormatResponse(t *testing.T) {
 	an, ctx, pbReq := CreatePrebidRequest(server, t)
 	_, err := an.Call(ctx, pbReq, pbReq.Bidders[0])
 
-	if pbReq.Bidders[0].Debug[0].StatusCode != 200 {
-		t.Fatalf("StatusCode should be 200 instead of: %v", pbReq.Bidders[0].Debug[0].StatusCode)
-	}
-
-	if err == nil {
-		t.Fatalf("Should have gotten an error: %v", err)
-	}
+	assert.Equal(t, 200, pbReq.Bidders[0].Debug[0].StatusCode,
+		"StatusCode should be 200 instead of: %v", pbReq.Bidders[0].Debug[0].StatusCode)
 
-	if !strings.HasPrefix(err.Error(), "invalid character") {
-		t.Fatalf("Should start with 'invalid character' instead of: %v", err)
-	}
+	assert.NotNil(t, err, "Should have gotten an error: %v", err)
 
+	assert.True(t, strings.HasPrefix(err.Error(), "invalid character"),
+		"Should start with 'invalid character' instead of: %v", err)
 }
 
 func TestZeroSeatBidResponse(t *testing.T) {
-
 	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 		resp := openrtb.BidResponse{
 			ID:      "test-response-id",
@@ -650,18 +591,12 @@ func TestZeroSeatBidResponse(t *testing.T) {
 	an, ctx, pbReq := CreatePrebidRequest(server, t)
 	bids, err := an.Call(ctx, pbReq, pbReq.Bidders[0])
 
-	if len(bids) != 0 {
-		t.Fatalf("Length of bids should be 0 instead of: %v", len(bids))
-	}
-
-	if err != nil {
-		t.Fatalf("Should not have gotten an error: %v", err)
-	}
+	assert.Empty(t, bids, "Length of bids should be 0 instead of: %v", len(bids))
 
+	assert.Nil(t, err, "Should not have gotten an error: %v", err)
 }
 
 func TestEmptyBidResponse(t *testing.T) {
-
 	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 		resp := openrtb.BidResponse{
 			ID:    "test-response-id",
@@ -682,18 +617,12 @@ func TestEmptyBidResponse(t *testing.T) {
 	an, ctx, pbReq := CreatePrebidRequest(server, t)
 	bids, err := an.Call(ctx, pbReq, pbReq.Bidders[0])
 
-	if len(bids) != 0 {
-		t.Fatalf("Length of bids should be 0 instead of: %v", len(bids))
-	}
-
-	if err != nil {
-		t.Fatalf("Should not have gotten an error: %v", err)
-	}
+	assert.Empty(t, bids, "Length of bids should be 0 instead of: %v", len(bids))
 
+	assert.Nil(t, err, "Should not have gotten an error: %v", err)
 }
 
 func TestWrongBidIdResponse(t *testing.T) {
-
 	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 		resp := openrtb.BidResponse{
 			ID:    "test-response-id",
@@ -721,18 +650,12 @@ func TestWrongBidIdResponse(t *testing.T) {
 	an, ctx, pbReq := CreatePrebidRequest(server, t)
 	bids, err := an.Call(ctx, pbReq, pbReq.Bidders[0])
 
-	if len(bids) != 0 {
-		t.Fatalf("Length of bids should be 0 instead of: %v", len(bids))
-	}
+	assert.Empty(t, bids, "Length of bids should be 0 instead of: %v", len(bids))
 
-	if err == nil {
-		t.Fatalf("Should not have gotten an error: %v", err)
-	}
-
-	if !strings.HasPrefix(err.Error(), "Unknown ad unit code") {
-		t.Fatalf("Should start with 'Unknown ad unit code' instead of: %v", err)
-	}
+	assert.NotNil(t, err, "Should not have gotten an error: %v", err)
 
+	assert.True(t, strings.HasPrefix(err.Error(), "Unknown ad unit code"),
+		"Should start with 'Unknown ad unit code' instead of: %v", err)
 }
 
 func TestZeroPriceBidResponse(t *testing.T) {
@@ -764,10 +687,7 @@ func TestZeroPriceBidResponse(t *testing.T) {
 	an, ctx, pbReq := CreatePrebidRequest(server, t)
 	b, err := an.Call(ctx, pbReq, pbReq.Bidders[0])
 
-	if b != nil {
-		t.Fatalf("\n\n\n0 price bids are being included %d, err : %v", len(b), err)
-	}
-
+	assert.Nil(t, b, "\n\n\n0 price bids are being included %d, err : %v", len(b), err)
 }
 
 func TestDifferentRequest(t *testing.T) {
@@ -782,10 +702,9 @@ func TestDifferentRequest(t *testing.T) {
 		ID:   "com.test",
 		Name: "testApp",
 	}
+
 	_, err := an.Call(ctx, pbReq, pbReq.Bidders[0])
-	if err == nil {
-		t.Fatalf("Should have gotten an error: %v", err)
-	}
+	assert.NotNil(t, err, "Should have gotten an error: %v", err)
 
 	// set app back to normal
 	pbReq.App = nil
@@ -793,9 +712,7 @@ func TestDifferentRequest(t *testing.T) {
 	// test video media type
 	pbReq.Bidders[0].AdUnits[0].MediaTypes = []pbs.MediaType{pbs.MEDIA_TYPE_VIDEO}
 	_, err = an.Call(ctx, pbReq, pbReq.Bidders[0])
-	if err == nil {
-		t.Fatalf("Should have gotten an error: %v", err)
-	}
+	assert.NotNil(t, err, "Should have gotten an error: %v", err)
 
 	// set media back to normal
 	pbReq.Bidders[0].AdUnits[0].MediaTypes = []pbs.MediaType{pbs.MEDIA_TYPE_BANNER}
@@ -803,9 +720,7 @@ func TestDifferentRequest(t *testing.T) {
 	// test wrong params
 	pbReq.Bidders[0].AdUnits[0].Params = json.RawMessage(fmt.Sprintf("{\"zoneId\": %s, \"siteId\": %d, \"visitor\": %s, \"inventory\": %s}", "zma", rubidata.siteID, rubidata.visitorTargeting, rubidata.inventoryTargeting))
 	_, err = an.Call(ctx, pbReq, pbReq.Bidders[0])
-	if err == nil {
-		t.Fatalf("Should have gotten an error: %v", err)
-	}
+	assert.NotNil(t, err, "Should have gotten an error: %v", err)
 
 	// set params back to normal
 	pbReq.Bidders[0].AdUnits[0].Params = json.RawMessage(fmt.Sprintf("{\"zoneId\": %d, \"siteId\": %d, \"accountId\": %d, \"visitor\": %s, \"inventory\": %s}", 8394, rubidata.siteID, rubidata.accountID, rubidata.visitorTargeting, rubidata.inventoryTargeting))
@@ -829,9 +744,7 @@ func TestDifferentRequest(t *testing.T) {
 	}
 	pbReq.Bidders[0].AdUnits = pbReq.Bidders[0].AdUnits[:len(pbReq.Bidders[0].AdUnits)-1]
 	b, err := an.Call(ctx, pbReq, pbReq.Bidders[0])
-	if err == nil || len(b) != 0 {
-		t.Fatalf("Filtering bids based on ad unit sizes failed. Got %d bids instead of 0", len(b))
-	}
+	assert.NotNil(t, err, "Should have gotten an error: %v", err)
 
 	pbReq.Bidders[0].AdUnits[1].Sizes = []openrtb.Format{
 		{
@@ -842,9 +755,10 @@ func TestDifferentRequest(t *testing.T) {
 		SIZE_ID[15],
 	}
 	b, err = an.Call(ctx, pbReq, pbReq.Bidders[0])
-	if err != nil || len(b) != 1 {
-		t.Fatalf("Filtering bids based on ad unit sizes failed. Got %d bids instead of 1, error = %v", len(b), err)
-	}
+	assert.Nil(t, err, "Should have not gotten an error: %v", err)
+
+	assert.Equal(t, 1, len(b),
+		"Filtering bids based on ad unit sizes failed. Got %d bids instead of 1, error = %v", len(b), err)
 }
 
 func CreatePrebidRequest(server *httptest.Server, t *testing.T) (an *RubiconAdapter, ctx context.Context, pbReq *pbs.PBSRequest) {
@@ -957,18 +871,16 @@ func CreatePrebidRequest(server *httptest.Server, t *testing.T) (an *RubiconAdap
 		Max:     2000,
 	}, cacheClient, &hcc)
 	pbReq.IsDebug = true
-	if err != nil {
-		t.Fatalf("ParsePBSRequest failed: %v", err)
-	}
-	if len(pbReq.Bidders) != 1 {
-		t.Fatalf("ParsePBSRequest returned %d bidders instead of 1", len(pbReq.Bidders))
-	}
-	if pbReq.Bidders[0].BidderCode != "rubicon" {
-		t.Fatalf("ParsePBSRequest returned invalid bidder")
-	}
 
-	ctx = context.TODO()
+	assert.Nil(t, err, "ParsePBSRequest failed: %v", err)
 
+	assert.Equal(t, 1, len(pbReq.Bidders),
+		"ParsePBSRequest returned %d bidders instead of 1", len(pbReq.Bidders))
+
+	assert.Equal(t, "rubicon", pbReq.Bidders[0].BidderCode,
+		"ParsePBSRequest returned invalid bidder")
+
+	ctx = context.TODO()
 	return
 }
 
@@ -1037,15 +949,6 @@ func TestOpenRTBRequest(t *testing.T) {
                     "pref": 0
                 },
 				"eids": [{
-                    "source": "adserver.org",
-                    "uids": [{
-                        "id": "3d50a262-bd8e-4be3-90b8-246291523907",
-                        "ext": {
-                            "rtiPartner": "TDID"
-                        }
-                    }]
-                },
-                {
                     "source": "pubcid",
                     "id": "2402fc76-7b39-4f0e-bfc2-060ef7693648"
 				}]
@@ -1056,36 +959,22 @@ func TestOpenRTBRequest(t *testing.T) {
 
 	reqs, errs := bidder.MakeRequests(request, &adapters.ExtraRequestInfo{})
 
-	if len(errs) > 0 {
-		t.Errorf("Got unexpected errors while building HTTP requests: %v", errs)
-	}
-	if len(reqs) != 2 {
-		t.Fatalf("Unexpected number of HTTP requests. Got %d. Expected %d", len(reqs), 2)
-	}
+	assert.Empty(t, errs, "Got unexpected errors while building HTTP requests: %v", errs)
+	assert.Equal(t, 2, len(reqs), "Unexpected number of HTTP requests. Got %d. Expected %d", len(reqs), 2)
 
 	for i := 0; i < len(reqs); i++ {
 		httpReq := reqs[i]
-		if httpReq.Method != "POST" {
-			t.Errorf("Expected a POST message. Got %s", httpReq.Method)
-		}
+		assert.Equal(t, "POST", httpReq.Method, "Expected a POST message. Got %s", httpReq.Method)
 
 		var rpRequest openrtb.BidRequest
 		if err := json.Unmarshal(httpReq.Body, &rpRequest); err != nil {
 			t.Fatalf("Failed to unmarshal HTTP request: %v", rpRequest)
 		}
 
-		if rpRequest.ID != request.ID {
-			t.Errorf("Bad Request ID. Expected %s, Got %s", request.ID, rpRequest.ID)
-		}
-		if len(rpRequest.Imp) != len(request.Imp) {
-			t.Fatalf("Wrong len(request.Imp). Expected %d, Got %d", len(request.Imp), len(rpRequest.Imp))
-		}
-		if rpRequest.Cur != nil {
-			t.Fatalf("Wrong request.Cur. Expected nil, Got %s", rpRequest.Cur)
-		}
-		if request.Ext != nil {
-			t.Fatalf("Wrong request.ext. Expected nil, Got %v", request.Ext)
-		}
+		assert.Equal(t, request.ID, rpRequest.ID, "Bad Request ID. Expected %s, Got %s", request.ID, rpRequest.ID)
+		assert.Equal(t, len(request.Imp), len(rpRequest.Imp), "Wrong len(request.Imp). Expected %d, Got %d", len(request.Imp), len(rpRequest.Imp))
+		assert.Nil(t, rpRequest.Cur, "Wrong request.Cur. Expected nil, Got %s", rpRequest.Cur)
+		assert.Nil(t, request.Ext, "Wrong request.ext. Expected nil, Got %v", request.Ext)
 
 		if rpRequest.Imp[0].ID == "test-imp-banner-id" {
 			var rpExt rubiconBannerExt
@@ -1093,58 +982,52 @@ func TestOpenRTBRequest(t *testing.T) {
 				t.Fatal("Error unmarshalling request from the outgoing request.")
 			}
 
-			if rpRequest.Imp[0].Banner.Format[0].W != 300 {
-				t.Fatalf("Banner width does not match. Expected %d, Got %d", 300, rpRequest.Imp[0].Banner.Format[0].W)
-			}
-			if rpRequest.Imp[0].Banner.Format[0].H != 250 {
-				t.Fatalf("Banner height does not match. Expected %d, Got %d", 250, rpRequest.Imp[0].Banner.Format[0].H)
-			}
-			if rpRequest.Imp[0].Banner.Format[1].W != 300 {
-				t.Fatalf("Banner width does not match. Expected %d, Got %d", 300, rpRequest.Imp[0].Banner.Format[1].W)
-			}
-			if rpRequest.Imp[0].Banner.Format[1].H != 600 {
-				t.Fatalf("Banner height does not match. Expected %d, Got %d", 600, rpRequest.Imp[0].Banner.Format[1].H)
-			}
+			assert.Equal(t, uint64(300), rpRequest.Imp[0].Banner.Format[0].W,
+				"Banner width does not match. Expected %d, Got %d", 300, rpRequest.Imp[0].Banner.Format[0].W)
+
+			assert.Equal(t, uint64(250), rpRequest.Imp[0].Banner.Format[0].H,
+				"Banner height does not match. Expected %d, Got %d", 250, rpRequest.Imp[0].Banner.Format[0].H)
+
+			assert.Equal(t, uint64(300), rpRequest.Imp[0].Banner.Format[1].W,
+				"Banner width does not match. Expected %d, Got %d", 300, rpRequest.Imp[0].Banner.Format[1].W)
+
+			assert.Equal(t, uint64(600), rpRequest.Imp[0].Banner.Format[1].H,
+				"Banner height does not match. Expected %d, Got %d", 600, rpRequest.Imp[0].Banner.Format[1].H)
 		} else if rpRequest.Imp[0].ID == "test-imp-video-id" {
 			var rpExt rubiconVideoExt
 			if err := json.Unmarshal(rpRequest.Imp[0].Ext, &rpExt); err != nil {
 				t.Fatal("Error unmarshalling request from the outgoing request.")
 			}
 
-			if rpRequest.Imp[0].Video.W != 640 {
-				t.Fatalf("Video width does not match. Expected %d, Got %d", 640, rpRequest.Imp[0].Video.W)
-			}
-			if rpRequest.Imp[0].Video.H != 360 {
-				t.Fatalf("Video height does not match. Expected %d, Got %d", 360, rpRequest.Imp[0].Video.H)
-			}
-			if rpRequest.Imp[0].Video.MIMEs[0] != "video/mp4" {
-				t.Fatalf("Video MIMEs do not match. Expected %s, Got %s", "video/mp4", rpRequest.Imp[0].Video.MIMEs[0])
-			}
-			if rpRequest.Imp[0].Video.MinDuration != 15 {
-				t.Fatalf("Video min duration does not match. Expected %d, Got %d", 15, rpRequest.Imp[0].Video.MinDuration)
-			}
-			if rpRequest.Imp[0].Video.MaxDuration != 30 {
-				t.Fatalf("Video max duration does not match. Expected %d, Got %d", 30, rpRequest.Imp[0].Video.MaxDuration)
-			}
+			assert.Equal(t, uint64(640), rpRequest.Imp[0].Video.W,
+				"Video width does not match. Expected %d, Got %d", 640, rpRequest.Imp[0].Video.W)
+
+			assert.Equal(t, uint64(360), rpRequest.Imp[0].Video.H,
+				"Video height does not match. Expected %d, Got %d", 360, rpRequest.Imp[0].Video.H)
+
+			assert.Equal(t, "video/mp4", rpRequest.Imp[0].Video.MIMEs[0], "Video MIMEs do not match. Expected %s, Got %s", "video/mp4", rpRequest.Imp[0].Video.MIMEs[0])
+
+			assert.Equal(t, int64(15), rpRequest.Imp[0].Video.MinDuration,
+				"Video min duration does not match. Expected %d, Got %d", 15, rpRequest.Imp[0].Video.MinDuration)
+
+			assert.Equal(t, int64(30), rpRequest.Imp[0].Video.MaxDuration,
+				"Video max duration does not match. Expected %d, Got %d", 30, rpRequest.Imp[0].Video.MaxDuration)
 		}
 
-		if rpRequest.User.Ext != nil {
-			var userExt rubiconUserExt
-			if err := json.Unmarshal(rpRequest.User.Ext, &userExt); err != nil {
-				t.Fatal("Error unmarshalling request.user.ext object.")
-			}
-			if userExt.DigiTrust.ID != "some-digitrust-id" || userExt.DigiTrust.KeyV != 1 || userExt.DigiTrust.Pref != 0 {
-				t.Fatal("DigiTrust values are not as expected!")
-			}
-			if userExt.Eids == nil || len(userExt.Eids) != 2 {
-				t.Fatal("Eids values are not as expected!")
-			}
-			if userExt.TpID == nil || len(userExt.TpID) != 1 {
-				t.Fatal("TpID values are not as expected!")
-			}
-		} else {
-			t.Fatalf("User.Ext object should not be nil since it contains a valid digitrust object.")
+		assert.NotNil(t, rpRequest.User.Ext, "User.Ext object should not be nil.")
+
+		var userExt rubiconUserExt
+		if err := json.Unmarshal(rpRequest.User.Ext, &userExt); err != nil {
+			t.Fatal("Error unmarshalling request.user.ext object.")
 		}
+
+		assert.Equal(t, "some-digitrust-id", userExt.DigiTrust.ID, "DigiTrust ID id not as expected!")
+		assert.Equal(t, 1, userExt.DigiTrust.KeyV, "DigiTrust KeyV id not as expected!")
+		assert.Equal(t, 0, userExt.DigiTrust.Pref, "DigiTrust Pref id not as expected!")
+
+		assert.NotNil(t, userExt.Eids)
+		assert.Equal(t, 1, len(userExt.Eids), "Eids values are not as expected!")
+		assert.Contains(t, userExt.Eids, openrtb_ext.ExtUserEid{Source: "pubcid", ID: "2402fc76-7b39-4f0e-bfc2-060ef7693648"})
 	}
 }
 
@@ -1179,29 +1062,20 @@ func TestOpenRTBRequestWithBannerImpEvenIfImpHasVideo(t *testing.T) {
 
 	reqs, errs := bidder.MakeRequests(request, &adapters.ExtraRequestInfo{})
 
-	if len(errs) > 0 {
-		t.Errorf("Got unexpected errors while building HTTP requests: %v", errs)
-	}
-	if len(reqs) != 1 {
-		t.Fatalf("Unexpected number of HTTP requests. Got %d. Expected %d", len(reqs), 1)
-	}
+	assert.Empty(t, errs, "Got unexpected errors while building HTTP requests: %v", errs)
+
+	assert.Equal(t, 1, len(reqs), "Unexpected number of HTTP requests. Got %d. Expected %d", len(reqs), 1)
 
 	rubiconReq := &openrtb.BidRequest{}
 	if err := json.Unmarshal(reqs[0].Body, rubiconReq); err != nil {
-		t.Errorf("Unexpected error while decoding request: %s", err)
+		t.Fatalf("Unexpected error while decoding request: %s", err)
 	}
 
-	if len(rubiconReq.Imp) != 1 {
-		t.Fatalf("Unexpected number of request impressions. Got %d. Expected %d", len(rubiconReq.Imp), 1)
-	}
+	assert.Equal(t, 1, len(rubiconReq.Imp), "Unexpected number of request impressions. Got %d. Expected %d", len(rubiconReq.Imp), 1)
 
-	if rubiconReq.Imp[0].Video != nil {
-		t.Error("Unexpected video object in request impression")
-	}
+	assert.Nil(t, rubiconReq.Imp[0].Video, "Unexpected video object in request impression")
 
-	if rubiconReq.Imp[0].Banner == nil {
-		t.Error("Banner object must be in request impression")
-	}
+	assert.NotNil(t, rubiconReq.Imp[0].Banner, "Banner object must be in request impression")
 }
 
 func TestOpenRTBRequestWithImpAndAdSlotIncluded(t *testing.T) {
@@ -1239,12 +1113,11 @@ func TestOpenRTBRequestWithImpAndAdSlotIncluded(t *testing.T) {
 
 	rubiconReq := &openrtb.BidRequest{}
 	if err := json.Unmarshal(reqs[0].Body, rubiconReq); err != nil {
-		t.Errorf("Unexpected error while decoding request: %s", err)
+		t.Fatalf("Unexpected error while decoding request: %s", err)
 	}
 
-	if len(rubiconReq.Imp) != 1 {
-		t.Fatalf("Unexpected number of request impressions. Got %d. Expected %d", len(rubiconReq.Imp), 1)
-	}
+	assert.Equal(t, 1, len(rubiconReq.Imp),
+		"Unexpected number of request impressions. Got %d. Expected %d", len(rubiconReq.Imp), 1)
 
 	var rpImpExt rubiconImpExt
 	if err := json.Unmarshal(rubiconReq.Imp[0].Ext, &rpImpExt); err != nil {
@@ -1256,9 +1129,92 @@ func TestOpenRTBRequestWithImpAndAdSlotIncluded(t *testing.T) {
 		t.Fatal("Error unmarshalling imp.ext.rp.target")
 	}
 
-	if rubiconExtInventory["dfp_ad_unit_code"] != "test-adslot" {
-		t.Fatalf("Unexpected dfp_ad_unit_code: %s", rubiconExtInventory["dfp_ad_unit_code"])
+	assert.Equal(t, "test-adslot", rubiconExtInventory["dfp_ad_unit_code"],
+		"Unexpected dfp_ad_unit_code: %s", rubiconExtInventory["dfp_ad_unit_code"])
+}
+
+func TestOpenRTBRequestWithSpecificExtUserEids(t *testing.T) {
+	SIZE_ID := getTestSizes()
+	bidder := new(RubiconAdapter)
+
+	request := &openrtb.BidRequest{
+		ID: "test-request-id",
+		Imp: []openrtb.Imp{{
+			ID: "test-imp-id",
+			Banner: &openrtb.Banner{
+				Format: []openrtb.Format{
+					SIZE_ID[15],
+					SIZE_ID[10],
+				},
+			},
+			Ext: json.RawMessage(`{"bidder": {
+				"zoneId": 8394,
+				"siteId": 283282,
+				"accountId": 7891
+			}}`),
+		}},
+		User: &openrtb.User{
+			Ext: json.RawMessage(`{"eids": [
+			{
+				"source": "pubcid",
+				"id": "2402fc76-7b39-4f0e-bfc2-060ef7693648"
+			},
+			{
+				"source": "adserver.org",
+				"uids": [{
+					"id": "3d50a262-bd8e-4be3-90b8-246291523907",
+					"ext": {
+						"rtiPartner": "TDID"
+					}
+				}]
+			},
+			{
+				"source": "liveintent.com",
+				"uids": [{
+					"id": "T7JiRRvsRAmh88"
+				}],
+				"ext": {
+					"segments": ["999","888"]
+				}
+			}
+			]}`),
+		},
+	}
+
+	reqs, _ := bidder.MakeRequests(request, &adapters.ExtraRequestInfo{})
+
+	rubiconReq := &openrtb.BidRequest{}
+	if err := json.Unmarshal(reqs[0].Body, rubiconReq); err != nil {
+		t.Fatalf("Unexpected error while decoding request: %s", err)
 	}
+
+	assert.NotNil(t, rubiconReq.User.Ext, "User.Ext object should not be nil.")
+
+	var userExt rubiconUserExt
+	if err := json.Unmarshal(rubiconReq.User.Ext, &userExt); err != nil {
+		t.Fatal("Error unmarshalling request.user.ext object.")
+	}
+
+	assert.NotNil(t, userExt.Eids)
+	assert.Equal(t, 3, len(userExt.Eids), "Eids values are not as expected!")
+
+	assert.NotNil(t, userExt.TpID)
+	assert.Equal(t, 2, len(userExt.TpID), "TpID values are not as expected!")
+
+	// adserver.org
+	assert.Equal(t, "tdid", userExt.TpID[0].Source, "TpID source value is not as expected!")
+
+	// liveintent.com
+	assert.Equal(t, "liveintent.com", userExt.TpID[1].Source, "TpID source value is not as expected!")
+
+	userExtRPTarget := make(map[string]interface{})
+	if err := json.Unmarshal(userExt.RP.Target, &userExtRPTarget); err != nil {
+		t.Fatal("Error unmarshalling request.user.ext.rp.target object.")
+	}
+
+	assert.Contains(t, userExtRPTarget, "LIseg", "request.user.ext.rp.target value is not as expected!")
+	assert.Contains(t, userExtRPTarget["LIseg"], "888", "No segment with 888 as expected!")
+	assert.Contains(t, userExtRPTarget["LIseg"], "999", "No segment with 999 as expected!")
 }
 
 func TestOpenRTBRequestWithVideoImpEvenIfImpHasBannerButAllRequiredVideoFields(t *testing.T) {
@@ -1296,29 +1252,21 @@ func TestOpenRTBRequestWithVideoImpEvenIfImpHasBannerButAllRequiredVideoFields(t
 
 	reqs, errs := bidder.MakeRequests(request, &adapters.ExtraRequestInfo{})
 
-	if len(errs) > 0 {
-		t.Errorf("Got unexpected errors while building HTTP requests: %v", errs)
-	}
-	if len(reqs) != 1 {
-		t.Fatalf("Unexpected number of HTTP requests. Got %d. Expected %d", len(reqs), 1)
-	}
+	assert.Empty(t, errs, "Got unexpected errors while building HTTP requests: %v", errs)
+
+	assert.Equal(t, 1, len(reqs), "Unexpected number of HTTP requests. Got %d. Expected %d", len(reqs), 1)
 
 	rubiconReq := &openrtb.BidRequest{}
 	if err := json.Unmarshal(reqs[0].Body, rubiconReq); err != nil {
-		t.Errorf("Unexpected error while decoding request: %s", err)
+		t.Fatalf("Unexpected error while decoding request: %s", err)
 	}
 
-	if len(rubiconReq.Imp) != 1 {
-		t.Fatalf("Unexpected number of request impressions. Got %d. Expected %d", len(rubiconReq.Imp), 1)
-	}
+	assert.Equal(t, 1, len(rubiconReq.Imp),
+		"Unexpected number of request impressions. Got %d. Expected %d", len(rubiconReq.Imp), 1)
 
-	if rubiconReq.Imp[0].Banner != nil {
-		t.Error("Unexpected banner object in request impression")
-	}
+	assert.Nil(t, rubiconReq.Imp[0].Banner, "Unexpected banner object in request impression")
 
-	if rubiconReq.Imp[0].Video == nil {
-		t.Error("Video object must be in request impression")
-	}
+	assert.NotNil(t, rubiconReq.Imp[0].Video, "Video object must be in request impression")
 }
 
 func TestOpenRTBEmptyResponse(t *testing.T) {
@@ -1327,12 +1275,9 @@ func TestOpenRTBEmptyResponse(t *testing.T) {
 	}
 	bidder := new(RubiconAdapter)
 	bidResponse, errs := bidder.MakeBids(nil, nil, httpResp)
-	if bidResponse != nil && len(bidResponse.Bids) != 0 {
-		t.Errorf("Expected 0 bids. Got %d", len(bidResponse.Bids))
-	}
-	if len(errs) != 0 {
-		t.Errorf("Expected 0 errors. Got %d", len(errs))
-	}
+
+	assert.Nil(t, bidResponse, "Expected empty response")
+	assert.Empty(t, errs, "Expected 0 errors. Got %d", len(errs))
 }
 
 func TestOpenRTBSurpriseResponse(t *testing.T) {
@@ -1341,12 +1286,10 @@ func TestOpenRTBSurpriseResponse(t *testing.T) {
 	}
 	bidder := new(RubiconAdapter)
 	bidResponse, errs := bidder.MakeBids(nil, nil, httpResp)
-	if bidResponse != nil && len(bidResponse.Bids) != 0 {
-		t.Errorf("Expected 0 bids. Got %d", len(bidResponse.Bids))
-	}
-	if len(errs) != 1 {
-		t.Errorf("Expected 1 error. Got %d", len(errs))
-	}
+
+	assert.Nil(t, bidResponse, "Expected empty response")
+
+	assert.Equal(t, 1, len(errs), "Expected 1 error. Got %d", len(errs))
 }
 
 func TestOpenRTBStandardResponse(t *testing.T) {
@@ -1384,19 +1327,16 @@ func TestOpenRTBStandardResponse(t *testing.T) {
 	bidder := new(RubiconAdapter)
 	bidResponse, errs := bidder.MakeBids(request, reqData, httpResp)
 
-	if bidResponse != nil && len(bidResponse.Bids) != 1 {
-		t.Fatalf("Expected 1 bid. Got %d", len(bidResponse.Bids))
-	}
-	if len(errs) != 0 {
-		t.Errorf("Expected 0 errors. Got %d", len(errs))
-	}
-	if bidResponse.Bids[0].BidType != openrtb_ext.BidTypeBanner {
-		t.Errorf("Expected a banner bid. Got: %s", bidResponse.Bids[0].BidType)
-	}
+	assert.NotNil(t, bidResponse, "Expected not empty response")
+	assert.Equal(t, 1, len(bidResponse.Bids), "Expected 1 bid. Got %d", len(bidResponse.Bids))
+
+	assert.Empty(t, errs, "Expected 0 errors. Got %d", len(errs))
+
+	assert.Equal(t, openrtb_ext.BidTypeBanner, bidResponse.Bids[0].BidType,
+		"Expected a banner bid. Got: %s", bidResponse.Bids[0].BidType)
+
 	theBid := bidResponse.Bids[0].Bid
-	if theBid.ID != "1234567890" {
-		t.Errorf("Bad bid ID. Expected %s, got %s", "1234567890", theBid.ID)
-	}
+	assert.Equal(t, "1234567890", theBid.ID, "Bad bid ID. Expected %s, got %s", "1234567890", theBid.ID)
 }
 
 func TestOpenRTBCopyBidIdFromResponseIfZero(t *testing.T) {
@@ -1417,9 +1357,7 @@ func TestOpenRTBCopyBidIdFromResponseIfZero(t *testing.T) {
 	bidResponse, _ := bidder.MakeBids(request, reqData, httpResp)
 
 	theBid := bidResponse.Bids[0].Bid
-	if theBid.ID != "1234567890" {
-		t.Errorf("Bad bid ID. Expected %s, got %s", "1234567890", theBid.ID)
-	}
+	assert.Equal(t, "1234567890", theBid.ID, "Bad bid ID. Expected %s, got %s", "1234567890", theBid.ID)
 }
 
 func TestJsonSamples(t *testing.T) {
diff --git a/adapters/rubicon/usersync_test.go b/adapters/rubicon/usersync_test.go
index 072e297a..646ebff2 100644
--- a/adapters/rubicon/usersync_test.go
+++ b/adapters/rubicon/usersync_test.go
@@ -4,13 +4,24 @@ import (
 	"testing"
 	"text/template"
 
+	"github.com/prebid/prebid-server/privacy"
+	"github.com/prebid/prebid-server/privacy/gdpr"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestRubiconSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("https://pixel.rubiconproject.com/exchange/sync.php?p=prebid&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}"))
-	syncer := NewRubiconSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("0", "")
+	syncURL := "https://pixel.rubiconproject.com/exchange/sync.php?p=prebid&gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewRubiconSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{
+		GDPR: gdpr.Policy{
+			Signal: "0",
+		},
+	})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "https://pixel.rubiconproject.com/exchange/sync.php?p=prebid&gdpr=0&gdpr_consent=", syncInfo.URL)
 	assert.Equal(t, "redirect", syncInfo.Type)
diff --git a/adapters/sharethrough/usersync_test.go b/adapters/sharethrough/usersync_test.go
index 0cfc177f..48023295 100644
--- a/adapters/sharethrough/usersync_test.go
+++ b/adapters/sharethrough/usersync_test.go
@@ -1,15 +1,27 @@
 package sharethrough
 
 import (
-	"github.com/stretchr/testify/assert"
 	"testing"
 	"text/template"
+
+	"github.com/prebid/prebid-server/privacy"
+	"github.com/prebid/prebid-server/privacy/gdpr"
+	"github.com/stretchr/testify/assert"
 )
 
 func TestSharethroughSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("https://match.sharethrough.com?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}"))
-	syncer := NewSharethroughSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("0", "")
+	syncURL := "https://match.sharethrough.com?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewSharethroughSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{
+		GDPR: gdpr.Policy{
+			Signal: "0",
+		},
+	})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "https://match.sharethrough.com?gdpr=0&gdpr_consent=", syncInfo.URL)
 	assert.Equal(t, "redirect", syncInfo.Type)
diff --git a/adapters/somoaudience/usersync_test.go b/adapters/somoaudience/usersync_test.go
index 95ef72d8..86460506 100644
--- a/adapters/somoaudience/usersync_test.go
+++ b/adapters/somoaudience/usersync_test.go
@@ -4,13 +4,19 @@ import (
 	"testing"
 	"text/template"
 
+	"github.com/prebid/prebid-server/privacy"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestSomoaudienceSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("//publisher-east.mobileadtrading.com/usersync?ru=localhost%2Fsetuid%3Fbidder%3Dsomoaudience%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24%7BUID%7D"))
-	syncer := NewSomoaudienceSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("", "")
+	syncURL := "//publisher-east.mobileadtrading.com/usersync?ru=localhost%2Fsetuid%3Fbidder%3Dsomoaudience%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24%7BUID%7D"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewSomoaudienceSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "//publisher-east.mobileadtrading.com/usersync?ru=localhost%2Fsetuid%3Fbidder%3Dsomoaudience%26gdpr%3D%26gdpr_consent%3D%26uid%3D%24%7BUID%7D", syncInfo.URL)
 	assert.Equal(t, "redirect", syncInfo.Type)
diff --git a/adapters/sonobi/usersync_test.go b/adapters/sonobi/usersync_test.go
index 4fc15795..bfe5859e 100644
--- a/adapters/sonobi/usersync_test.go
+++ b/adapters/sonobi/usersync_test.go
@@ -4,13 +4,24 @@ import (
 	"testing"
 	"text/template"
 
+	"github.com/prebid/prebid-server/privacy"
+	"github.com/prebid/prebid-server/privacy/gdpr"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestSonobiSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("//sync.go.sonobi.com/us.gif?loc=external.com%2Fsetuid%3Fbidder%3Dsonobi%26consent_string%3D{{.GDPR}}%26gdpr%3D{{.GDPRConsent}}%26uid%3D%5BUID%5D"))
-	syncer := NewSonobiSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("0", "")
+	syncURL := "//sync.go.sonobi.com/us.gif?loc=external.com%2Fsetuid%3Fbidder%3Dsonobi%26consent_string%3D{{.GDPR}}%26gdpr%3D{{.GDPRConsent}}%26uid%3D%5BUID%5D"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewSonobiSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{
+		GDPR: gdpr.Policy{
+			Signal: "0",
+		},
+	})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "//sync.go.sonobi.com/us.gif?loc=external.com%2Fsetuid%3Fbidder%3Dsonobi%26consent_string%3D0%26gdpr%3D%26uid%3D%5BUID%5D", syncInfo.URL)
 	assert.Equal(t, "redirect", syncInfo.Type)
diff --git a/adapters/sovrn/usersync_test.go b/adapters/sovrn/usersync_test.go
index 5dad5451..4a4dfd9d 100644
--- a/adapters/sovrn/usersync_test.go
+++ b/adapters/sovrn/usersync_test.go
@@ -4,13 +4,24 @@ import (
 	"testing"
 	"text/template"
 
+	"github.com/prebid/prebid-server/privacy"
+	"github.com/prebid/prebid-server/privacy/gdpr"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestSovrnSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("//ap.lijit.com/pixel?redir=external.com%2Fsetuid%3Fbidder%3Dsovrn%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID"))
-	syncer := NewSovrnSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("0", "")
+	syncURL := "//ap.lijit.com/pixel?redir=external.com%2Fsetuid%3Fbidder%3Dsovrn%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewSovrnSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{
+		GDPR: gdpr.Policy{
+			Signal: "0",
+		},
+	})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "//ap.lijit.com/pixel?redir=external.com%2Fsetuid%3Fbidder%3Dsovrn%26gdpr%3D0%26gdpr_consent%3D%26uid%3D%24UID", syncInfo.URL)
 	assert.Equal(t, "redirect", syncInfo.Type)
diff --git a/adapters/synacormedia/usersync_test.go b/adapters/synacormedia/usersync_test.go
index 3f98fc40..538efb30 100644
--- a/adapters/synacormedia/usersync_test.go
+++ b/adapters/synacormedia/usersync_test.go
@@ -1,15 +1,22 @@
 package synacormedia
 
 import (
-	"github.com/stretchr/testify/assert"
 	"testing"
 	"text/template"
+
+	"github.com/prebid/prebid-server/privacy"
+	"github.com/stretchr/testify/assert"
 )
 
 func TestSynacormediaSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("//sync.technoratimedia.com/services?srv=cs&pid=70&cb=localhost%2Fsetuid%3Fbidder%3Dsynacormedia%26uid%3D%5BUSER_ID%5D"))
-	syncer := NewSynacorMediaSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("", "")
+	syncURL := "//sync.technoratimedia.com/services?srv=cs&pid=70&cb=localhost%2Fsetuid%3Fbidder%3Dsynacormedia%26uid%3D%5BUSER_ID%5D"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewSynacorMediaSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "//sync.technoratimedia.com/services?srv=cs&pid=70&cb=localhost%2Fsetuid%3Fbidder%3Dsynacormedia%26uid%3D%5BUSER_ID%5D", syncInfo.URL)
 	assert.Equal(t, "iframe", syncInfo.Type)
diff --git a/adapters/syncer_test.go b/adapters/syncer_test.go
new file mode 100644
index 00000000..8defd7b6
--- /dev/null
+++ b/adapters/syncer_test.go
@@ -0,0 +1,36 @@
+package adapters
+
+import (
+	"testing"
+	"text/template"
+
+	"github.com/prebid/prebid-server/privacy"
+	"github.com/prebid/prebid-server/privacy/ccpa"
+	"github.com/prebid/prebid-server/privacy/gdpr"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestGetUsersyncInfo(t *testing.T) {
+	privacyPolicies := privacy.Policies{
+		GDPR: gdpr.Policy{
+			Signal:  "A",
+			Consent: "B",
+		},
+		CCPA: ccpa.Policy{
+			Signal: "C",
+		},
+	}
+
+	syncURL := "{{.GDPR}}{{.GDPRConsent}}{{.USPrivacy}}"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+	syncer := Syncer{
+		urlTemplate: syncURLTemplate,
+	}
+
+	syncInfo, err := syncer.GetUsersyncInfo(privacyPolicies)
+
+	assert.NoError(t, err)
+	assert.Equal(t, "ABC", syncInfo.URL)
+}
diff --git a/adapters/triplelift/usersync_test.go b/adapters/triplelift/usersync_test.go
index 3fe2418b..b4bc8459 100644
--- a/adapters/triplelift/usersync_test.go
+++ b/adapters/triplelift/usersync_test.go
@@ -4,13 +4,19 @@ import (
 	"testing"
 	"text/template"
 
+	"github.com/prebid/prebid-server/privacy"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestTripleliftSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("//eb2.3lift.com/getuid?gdpr={{.GDPR}}&cmp_cs={{.GDPRConsent}}&redir=https%3A%2F%2Feb2.3lift.com%2Fsetuid%3Fbidder%3Dtriplelift%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID"))
-	syncer := NewTripleliftSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("", "")
+	syncURL := "//eb2.3lift.com/getuid?gdpr={{.GDPR}}&cmp_cs={{.GDPRConsent}}&redir=https%3A%2F%2Feb2.3lift.com%2Fsetuid%3Fbidder%3Dtriplelift%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewTripleliftSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "//eb2.3lift.com/getuid?gdpr=&cmp_cs=&redir=https%3A%2F%2Feb2.3lift.com%2Fsetuid%3Fbidder%3Dtriplelift%26gdpr%3D%26gdpr_consent%3D%26uid%3D%24UID", syncInfo.URL)
 	assert.Equal(t, "redirect", syncInfo.Type)
diff --git a/adapters/triplelift_native/usersync_test.go b/adapters/triplelift_native/usersync_test.go
index 85610f61..2fb66c2b 100644
--- a/adapters/triplelift_native/usersync_test.go
+++ b/adapters/triplelift_native/usersync_test.go
@@ -4,13 +4,19 @@ import (
 	"testing"
 	"text/template"
 
+	"github.com/prebid/prebid-server/privacy"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestTripleliftSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("//eb2.3lift.com/getuid?gdpr={{.GDPR}}&cmp_cs={{.GDPRConsent}}&redir=https%3A%2F%2Feb2.3lift.com%2Fsetuid%3Fbidder%3Dtriplelift%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID"))
-	syncer := NewTripleliftSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("", "")
+	syncURL := "//eb2.3lift.com/getuid?gdpr={{.GDPR}}&cmp_cs={{.GDPRConsent}}&redir=https%3A%2F%2Feb2.3lift.com%2Fsetuid%3Fbidder%3Dtriplelift%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewTripleliftSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "//eb2.3lift.com/getuid?gdpr=&cmp_cs=&redir=https%3A%2F%2Feb2.3lift.com%2Fsetuid%3Fbidder%3Dtriplelift%26gdpr%3D%26gdpr_consent%3D%26uid%3D%24UID", syncInfo.URL)
 	assert.Equal(t, "redirect", syncInfo.Type)
diff --git a/adapters/unruly/usersync_test.go b/adapters/unruly/usersync_test.go
index b9a25b07..8db8f750 100644
--- a/adapters/unruly/usersync_test.go
+++ b/adapters/unruly/usersync_test.go
@@ -4,13 +4,24 @@ import (
 	"testing"
 	"text/template"
 
+	"github.com/prebid/prebid-server/privacy"
+	"github.com/prebid/prebid-server/privacy/gdpr"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestUnrulySyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("//unrulymedia.com/pixel?redir=external.com%2Fsetuid%3Fbidder%3Dunruly%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID"))
-	syncer := NewUnrulySyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("0", "")
+	syncURL := "//unrulymedia.com/pixel?redir=external.com%2Fsetuid%3Fbidder%3Dunruly%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewUnrulySyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{
+		GDPR: gdpr.Policy{
+			Signal: "0",
+		},
+	})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "//unrulymedia.com/pixel?redir=external.com%2Fsetuid%3Fbidder%3Dunruly%26gdpr%3D0%26gdpr_consent%3D%26uid%3D%24UID", syncInfo.URL)
 	assert.Equal(t, "iframe", syncInfo.Type)
diff --git a/adapters/verizonmedia/usersync_test.go b/adapters/verizonmedia/usersync_test.go
index 4643b957..ad77ef0e 100644
--- a/adapters/verizonmedia/usersync_test.go
+++ b/adapters/verizonmedia/usersync_test.go
@@ -1,15 +1,22 @@
 package verizonmedia
 
 import (
-	"github.com/stretchr/testify/assert"
 	"testing"
 	"text/template"
+
+	"github.com/prebid/prebid-server/privacy"
+	"github.com/stretchr/testify/assert"
 )
 
 func TestVerizonMediaSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("https://pixel.advertising.com/ups/58207/occ?http://localhost/%2Fsetuid%3Fbidder%3Dverizonmedia%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID"))
-	syncer := NewVerizonMediaSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("", "")
+	syncURL := "https://pixel.advertising.com/ups/58207/occ?http://localhost/%2Fsetuid%3Fbidder%3Dverizonmedia%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewVerizonMediaSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "redirect", syncInfo.Type)
 	assert.EqualValues(t, 25, syncer.GDPRVendorID())
diff --git a/adapters/visx/usersync_test.go b/adapters/visx/usersync_test.go
index 02ca66df..9133c5df 100644
--- a/adapters/visx/usersync_test.go
+++ b/adapters/visx/usersync_test.go
@@ -4,13 +4,24 @@ import (
 	"testing"
 	"text/template"
 
+	"github.com/prebid/prebid-server/privacy"
+	"github.com/prebid/prebid-server/privacy/gdpr"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestVisxSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("//not_localhost/synclocalhost%2Fsetuid%3Fbidder%3Dvisx%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24%7BUUID%7D"))
-	syncer := NewVisxSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("0", "")
+	syncURL := "//not_localhost/synclocalhost%2Fsetuid%3Fbidder%3Dvisx%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24%7BUUID%7D"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewVisxSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{
+		GDPR: gdpr.Policy{
+			Signal: "0",
+		},
+	})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "//not_localhost/synclocalhost%2Fsetuid%3Fbidder%3Dvisx%26gdpr%3D0%26gdpr_consent%3D%26uid%3D%24%7BUUID%7D", syncInfo.URL)
 	assert.Equal(t, "redirect", syncInfo.Type)
diff --git a/adapters/vrtcal/usersync_test.go b/adapters/vrtcal/usersync_test.go
index 106c9a6e..26e5838d 100644
--- a/adapters/vrtcal/usersync_test.go
+++ b/adapters/vrtcal/usersync_test.go
@@ -4,13 +4,24 @@ import (
 	"testing"
 	"text/template"
 
+	"github.com/prebid/prebid-server/privacy"
+	"github.com/prebid/prebid-server/privacy/gdpr"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestVrtcalSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("http://usync-prebid.vrtcal.com/s?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}"))
-	syncer := NewVrtcalSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("0", "")
+	syncURL := "http://usync-prebid.vrtcal.com/s?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewVrtcalSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{
+		GDPR: gdpr.Policy{
+			Signal: "0",
+		},
+	})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "http://usync-prebid.vrtcal.com/s?gdpr=0&gdpr_consent=", syncInfo.URL)
 	assert.Equal(t, "redirect", syncInfo.Type)
diff --git a/adapters/yieldmo/usersync_test.go b/adapters/yieldmo/usersync_test.go
index 0aa230e7..93ab907f 100644
--- a/adapters/yieldmo/usersync_test.go
+++ b/adapters/yieldmo/usersync_test.go
@@ -4,13 +4,24 @@ import (
 	"testing"
 	"text/template"
 
+	"github.com/prebid/prebid-server/privacy"
+	"github.com/prebid/prebid-server/privacy/gdpr"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestYieldmoSyncer(t *testing.T) {
-	temp := template.Must(template.New("sync-template").Parse("//ads.yieldmo.com/pbsync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&redirectUri=http%3A%2F%2Flocalhost%2F%2Fsetuid%3Fbidder%3Dyieldmo%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID"))
-	syncer := NewYieldmoSyncer(temp)
-	syncInfo, err := syncer.GetUsersyncInfo("0", "")
+	syncURL := "//ads.yieldmo.com/pbsync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&redirectUri=http%3A%2F%2Flocalhost%2F%2Fsetuid%3Fbidder%3Dyieldmo%26gdpr%3D{{.GDPR}}%26gdpr_consent%3D{{.GDPRConsent}}%26uid%3D%24UID"
+	syncURLTemplate := template.Must(
+		template.New("sync-template").Parse(syncURL),
+	)
+
+	syncer := NewYieldmoSyncer(syncURLTemplate)
+	syncInfo, err := syncer.GetUsersyncInfo(privacy.Policies{
+		GDPR: gdpr.Policy{
+			Signal: "0",
+		},
+	})
+
 	assert.NoError(t, err)
 	assert.Equal(t, "//ads.yieldmo.com/pbsync?gdpr=0&gdpr_consent=&redirectUri=http%3A%2F%2Flocalhost%2F%2Fsetuid%3Fbidder%3Dyieldmo%26gdpr%3D0%26gdpr_consent%3D%26uid%3D%24UID", syncInfo.URL)
 	assert.Equal(t, "redirect", syncInfo.Type)
diff --git a/config/config_test.go b/config/config_test.go
index 14eda749..4d2b0a1c 100644
--- a/config/config_test.go
+++ b/config/config_test.go
@@ -8,6 +8,7 @@ import (
 	"time"
 
 	"encoding/json"
+
 	"github.com/prebid/prebid-server/openrtb_ext"
 	"github.com/spf13/viper"
 	"github.com/stretchr/testify/assert"
@@ -91,6 +92,7 @@ adapters:
     endpoint: http://facebook.com/pbs
     usersync_url: http://facebook.com/ortb/prebid-s2s
     platform_id: abcdefgh1234
+    app_secret: 987abc
   ix:
     endpoint: http://ixtest.com/api
   rubicon:
@@ -256,6 +258,7 @@ func TestFullConfig(t *testing.T) {
 	cmpStrings(t, "adapters.audiencenetwork.endpoint", cfg.Adapters[strings.ToLower(string(openrtb_ext.BidderFacebook))].Endpoint, "http://facebook.com/pbs")
 	cmpStrings(t, "adapters.audiencenetwork.usersync_url", cfg.Adapters[strings.ToLower(string(openrtb_ext.BidderFacebook))].UserSyncURL, "http://facebook.com/ortb/prebid-s2s")
 	cmpStrings(t, "adapters.audiencenetwork.platform_id", cfg.Adapters[strings.ToLower(string(openrtb_ext.BidderFacebook))].PlatformID, "abcdefgh1234")
+	cmpStrings(t, "adapters.audiencenetwork.app_secret", cfg.Adapters[strings.ToLower(string(openrtb_ext.BidderFacebook))].AppSecret, "987abc")
 	cmpStrings(t, "adapters.ix.endpoint", cfg.Adapters[strings.ToLower(string(openrtb_ext.BidderIx))].Endpoint, "http://ixtest.com/api")
 	cmpStrings(t, "adapters.rubicon.endpoint", cfg.Adapters[string(openrtb_ext.BidderRubicon)].Endpoint, "http://rubitest.com/api")
 	cmpStrings(t, "adapters.rubicon.usersync_url", cfg.Adapters[string(openrtb_ext.BidderRubicon)].UserSyncURL, "http://pixel.rubiconproject.com/sync.php?p=prebid")
diff --git a/endpoints/auction_test.go b/endpoints/auction_test.go
index e968003a..df91f8ca 100644
--- a/endpoints/auction_test.go
+++ b/endpoints/auction_test.go
@@ -19,6 +19,7 @@ import (
 	"github.com/prebid/prebid-server/pbsmetrics"
 	metricsConf "github.com/prebid/prebid-server/pbsmetrics/config"
 	"github.com/prebid/prebid-server/prebid_cache_client"
+	gdprPolicy "github.com/prebid/prebid-server/privacy/gdpr"
 	"github.com/prebid/prebid-server/usersync/usersyncers"
 	"github.com/spf13/viper"
 )
@@ -386,7 +387,11 @@ func TestShouldUsersync(t *testing.T) {
 			},
 			metricsEngine: nil,
 		}
-		allowSyncs := deps.shouldUsersync(context.Background(), openrtb_ext.BidderAdform, gdprApplies, consent)
+		privacyPolicy := gdprPolicy.Policy{
+			Signal:  gdprApplies,
+			Consent: consent,
+		}
+		allowSyncs := deps.shouldUsersync(context.Background(), openrtb_ext.BidderAdform, privacyPolicy)
 		if allowSyncs != expectAllow {
 			t.Errorf("Expected syncs: %t, allowed syncs: %t", expectAllow, allowSyncs)
 		}
diff --git a/endpoints/setuid_test.go b/endpoints/setuid_test.go
index cccc6659..555f6173 100644
--- a/endpoints/setuid_test.go
+++ b/endpoints/setuid_test.go
@@ -12,6 +12,7 @@ import (
 
 	"github.com/prebid/prebid-server/config"
 	"github.com/prebid/prebid-server/pbsmetrics"
+	"github.com/prebid/prebid-server/privacy"
 	"github.com/prebid/prebid-server/usersync"
 	"github.com/stretchr/testify/assert"
 
@@ -456,7 +457,7 @@ func (s fakeSyncer) FamilyName() string {
 }
 
 // GetUsersyncInfo implements the Usersyncer interface with a no-op.
-func (s fakeSyncer) GetUsersyncInfo(gdpr string, consent string) (*usersync.UsersyncInfo, error) {
+func (s fakeSyncer) GetUsersyncInfo(privacyPolicies privacy.Policies) (*usersync.UsersyncInfo, error) {
 	return nil, nil
 }
 
diff --git a/privacy/ccpa/ccpa_test.go b/privacy/ccpa/ccpa_test.go
index a5b48d14..5847dcf0 100644
--- a/privacy/ccpa/ccpa_test.go
+++ b/privacy/ccpa/ccpa_test.go
@@ -18,43 +18,43 @@ func TestWrite(t *testing.T) {
 	}{
 		{
 			description: "Disabled",
-			policy:      Policy{Value: ""},
+			policy:      Policy{Signal: ""},
 			request:     &openrtb.BidRequest{},
 			expected:    &openrtb.BidRequest{},
 		},
 		{
 			description: "Enabled With Nil Request Regs Object",
-			policy:      Policy{Value: "anyValue"},
+			policy:      Policy{Signal: "anySignal"},
 			request:     &openrtb.BidRequest{},
 			expected: &openrtb.BidRequest{Regs: &openrtb.Regs{
-				Ext: json.RawMessage(`{"us_privacy":"anyValue"}`)}},
+				Ext: json.RawMessage(`{"us_privacy":"anySignal"}`)}},
 		},
 		{
 			description: "Enabled With Nil Request Regs Ext Object",
-			policy:      Policy{Value: "anyValue"},
+			policy:      Policy{Signal: "anySignal"},
 			request:     &openrtb.BidRequest{Regs: &openrtb.Regs{}},
 			expected: &openrtb.BidRequest{Regs: &openrtb.Regs{
-				Ext: json.RawMessage(`{"us_privacy":"anyValue"}`)}},
+				Ext: json.RawMessage(`{"us_privacy":"anySignal"}`)}},
 		},
 		{
 			description: "Enabled With Existing Request Regs Ext Object - Doesn't Overwrite",
-			policy:      Policy{Value: "anyValue"},
+			policy:      Policy{Signal: "anySignal"},
 			request: &openrtb.BidRequest{Regs: &openrtb.Regs{
 				Ext: json.RawMessage(`{"existing":"any"}`)}},
 			expected: &openrtb.BidRequest{Regs: &openrtb.Regs{
-				Ext: json.RawMessage(`{"existing":"any","us_privacy":"anyValue"}`)}},
+				Ext: json.RawMessage(`{"existing":"any","us_privacy":"anySignal"}`)}},
 		},
 		{
 			description: "Enabled With Existing Request Regs Ext Object - Overwrites",
-			policy:      Policy{Value: "anyValue"},
+			policy:      Policy{Signal: "anySignal"},
 			request: &openrtb.BidRequest{Regs: &openrtb.Regs{
 				Ext: json.RawMessage(`{"existing":"any","us_privacy":"toBeOverwritten"}`)}},
 			expected: &openrtb.BidRequest{Regs: &openrtb.Regs{
-				Ext: json.RawMessage(`{"existing":"any","us_privacy":"anyValue"}`)}},
+				Ext: json.RawMessage(`{"existing":"any","us_privacy":"anySignal"}`)}},
 		},
 		{
 			description: "Enabled With Existing Malformed Request Regs Ext Object",
-			policy:      Policy{Value: "anyValue"},
+			policy:      Policy{Signal: "anySignal"},
 			request: &openrtb.BidRequest{Regs: &openrtb.Regs{
 				Ext: json.RawMessage(`malformed`)}},
 			expectedError: true,
diff --git a/privacy/gdpr/gdpr_test.go b/privacy/gdpr/gdpr_test.go
index 34605f07..80bd882d 100644
--- a/privacy/gdpr/gdpr_test.go
+++ b/privacy/gdpr/gdpr_test.go
@@ -24,37 +24,37 @@ func TestWrite(t *testing.T) {
 		},
 		{
 			description: "Enabled With Nil Request User Object",
-			policy:      Policy{Consent: "anyValue"},
+			policy:      Policy{Consent: "anyConsent"},
 			request:     &openrtb.BidRequest{},
 			expected: &openrtb.BidRequest{User: &openrtb.User{
-				Ext: json.RawMessage(`{"consent":"anyValue"}`)}},
+				Ext: json.RawMessage(`{"consent":"anyConsent"}`)}},
 		},
 		{
 			description: "Enabled With Nil Request User Ext Object",
-			policy:      Policy{Consent: "anyValue"},
+			policy:      Policy{Consent: "anyConsent"},
 			request:     &openrtb.BidRequest{User: &openrtb.User{}},
 			expected: &openrtb.BidRequest{User: &openrtb.User{
-				Ext: json.RawMessage(`{"consent":"anyValue"}`)}},
+				Ext: json.RawMessage(`{"consent":"anyConsent"}`)}},
 		},
 		{
 			description: "Enabled With Existing Request User Ext Object - Doesn't Overwrite",
-			policy:      Policy{Consent: "anyValue"},
+			policy:      Policy{Consent: "anyConsent"},
 			request: &openrtb.BidRequest{User: &openrtb.User{
 				Ext: json.RawMessage(`{"existing":"any"}`)}},
 			expected: &openrtb.BidRequest{User: &openrtb.User{
-				Ext: json.RawMessage(`{"existing":"any","consent":"anyValue"}`)}},
+				Ext: json.RawMessage(`{"existing":"any","consent":"anyConsent"}`)}},
 		},
 		{
 			description: "Enabled With Existing Request User Ext Object - Overwrites",
-			policy:      Policy{Consent: "anyValue"},
+			policy:      Policy{Consent: "anyConsent"},
 			request: &openrtb.BidRequest{User: &openrtb.User{
 				Ext: json.RawMessage(`{"existing":"any","consent":"toBeOverwritten"}`)}},
 			expected: &openrtb.BidRequest{User: &openrtb.User{
-				Ext: json.RawMessage(`{"existing":"any","consent":"anyValue"}`)}},
+				Ext: json.RawMessage(`{"existing":"any","consent":"anyConsent"}`)}},
 		},
 		{
 			description: "Enabled With Existing Malformed Request User Ext Object",
-			policy:      Policy{Consent: "anyValue"},
+			policy:      Policy{Consent: "anyConsent"},
 			request: &openrtb.BidRequest{User: &openrtb.User{
 				Ext: json.RawMessage(`malformed`)}},
 			expectedError: true,