Repository: prebid/prebid-server
Pull request #2806 (2023-05-26 01:40:56)

Correct use of named return parameters
This pull request removes return value variables that got shadowed by local variables or were not really necessary


Patch:
diff --git a/.gitignore b/.gitignore
index 514e217b..4e298f2a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -51,3 +51,8 @@ analytics/filesystem/testFiles/
 # autogenerated mac file
 
 .DS_Store
+
+# Autogenerated Vim swap files
+*~
+*.swp
+*.swo
diff --git a/config/account.go b/config/account.go
index 393194bc..8beff9b6 100644
--- a/config/account.go
+++ b/config/account.go
@@ -165,7 +165,8 @@ func (a *AccountGDPR) PurposeEnforced(purpose consentconstants.Purpose) (value,
 // PurposeEnforcementAlgo checks the purpose enforcement algo for a given purpose by first
 // looking at the account settings, and if not set there, defaulting to the host configuration.
 func (a *AccountGDPR) PurposeEnforcementAlgo(purpose consentconstants.Purpose) (value TCF2EnforcementAlgo, exists bool) {
-	c, exists := a.PurposeConfigs[purpose]
+	var c *AccountGDPRPurpose
+	c, exists = a.PurposeConfigs[purpose]
 
 	if exists && (c.EnforceAlgoID == TCF2BasicEnforcement || c.EnforceAlgoID == TCF2FullEnforcement) {
 		return c.EnforceAlgoID, true
diff --git a/config/config.go b/config/config.go
index eabf62ca..ee18c746 100644
--- a/config/config.go
+++ b/config/config.go
@@ -352,7 +352,7 @@ func (t *TCF2) IsEnabled() bool {
 
 // PurposeEnforced checks if full enforcement is turned on for a given purpose. With full enforcement enabled, the
 // GDPR full enforcement algorithm will execute for that purpose determining legal basis; otherwise it's skipped.
-func (t *TCF2) PurposeEnforced(purpose consentconstants.Purpose) (value bool) {
+func (t *TCF2) PurposeEnforced(purpose consentconstants.Purpose) (enforce bool) {
 	if t.PurposeConfigs[purpose] == nil {
 		return false
 	}
@@ -360,7 +360,7 @@ func (t *TCF2) PurposeEnforced(purpose consentconstants.Purpose) (value bool) {
 }
 
 // PurposeEnforcementAlgo returns the default enforcement algorithm for a given purpose
-func (t *TCF2) PurposeEnforcementAlgo(purpose consentconstants.Purpose) (value TCF2EnforcementAlgo) {
+func (t *TCF2) PurposeEnforcementAlgo(purpose consentconstants.Purpose) (enforcement TCF2EnforcementAlgo) {
 	if c, exists := t.PurposeConfigs[purpose]; exists {
 		return c.EnforceAlgoID
 	}
@@ -369,7 +369,7 @@ func (t *TCF2) PurposeEnforcementAlgo(purpose consentconstants.Purpose) (value T
 
 // PurposeEnforcingVendors checks if enforcing vendors is turned on for a given purpose. With enforcing vendors
 // enabled, the GDPR full enforcement algorithm considers the GVL when determining legal basis; otherwise it's skipped.
-func (t *TCF2) PurposeEnforcingVendors(purpose consentconstants.Purpose) (value bool) {
+func (t *TCF2) PurposeEnforcingVendors(purpose consentconstants.Purpose) (enforce bool) {
 	if t.PurposeConfigs[purpose] == nil {
 		return false
 	}
@@ -378,7 +378,7 @@ func (t *TCF2) PurposeEnforcingVendors(purpose consentconstants.Purpose) (value
 
 // PurposeVendorExceptions returns the vendor exception map for a given purpose if it exists, otherwise it returns
 // an empty map of vendor exceptions
-func (t *TCF2) PurposeVendorExceptions(purpose consentconstants.Purpose) (value map[openrtb_ext.BidderName]struct{}) {
+func (t *TCF2) PurposeVendorExceptions(purpose consentconstants.Purpose) (vendorExceptions map[openrtb_ext.BidderName]struct{}) {
 	c, exists := t.PurposeConfigs[purpose]
 
 	if exists && c.VendorExceptionMap != nil {
@@ -389,13 +389,13 @@ func (t *TCF2) PurposeVendorExceptions(purpose consentconstants.Purpose) (value
 
 // FeatureOneEnforced checks if special feature one is enforced. If it is enforced, PBS will determine whether geo
 // information may be passed through in the bid request.
-func (t *TCF2) FeatureOneEnforced() (value bool) {
+func (t *TCF2) FeatureOneEnforced() bool {
 	return t.SpecialFeature1.Enforce
 }
 
 // FeatureOneVendorException checks if the specified bidder is considered a vendor exception for special feature one.
 // If a bidder is a vendor exception, PBS will bypass the pass geo calculation passing the geo information in the bid request.
-func (t *TCF2) FeatureOneVendorException(bidder openrtb_ext.BidderName) (value bool) {
+func (t *TCF2) FeatureOneVendorException(bidder openrtb_ext.BidderName) bool {
 	if _, ok := t.SpecialFeature1.VendorExceptionMap[bidder]; ok {
 		return true
 	}
@@ -403,12 +403,12 @@ func (t *TCF2) FeatureOneVendorException(bidder openrtb_ext.BidderName) (value b
 }
 
 // PurposeOneTreatmentEnabled checks if purpose one treatment is enabled.
-func (t *TCF2) PurposeOneTreatmentEnabled() (value bool) {
+func (t *TCF2) PurposeOneTreatmentEnabled() bool {
 	return t.PurposeOneTreatment.Enabled
 }
 
 // PurposeOneTreatmentAccessAllowed checks if purpose one treatment access is allowed.
-func (t *TCF2) PurposeOneTreatmentAccessAllowed() (value bool) {
+func (t *TCF2) PurposeOneTreatmentAccessAllowed() bool {
 	return t.PurposeOneTreatment.AccessAllowed
 }
 
diff --git a/endpoints/events/event.go b/endpoints/events/event.go
index ba77f3ce..089d5606 100644
--- a/endpoints/events/event.go
+++ b/endpoints/events/event.go
@@ -217,7 +217,7 @@ func HandleAccountServiceErrors(errs []error) (status int, messages []string) {
 		}
 	}
 
-	return status, messages
+	return
 }
 
 func optionalParameters(request *analytics.EventRequest) string {
diff --git a/endpoints/openrtb2/amp_auction.go b/endpoints/openrtb2/amp_auction.go
index 0947c6f4..73f4842a 100644
--- a/endpoints/openrtb2/amp_auction.go
+++ b/endpoints/openrtb2/amp_auction.go
@@ -804,7 +804,7 @@ func setEffectiveAmpPubID(req *openrtb2.BidRequest, account string) {
 	}
 }
 
-func setTrace(req *openrtb2.BidRequest, value string) (err error) {
+func setTrace(req *openrtb2.BidRequest, value string) error {
 	if value == "" {
 		return nil
 	}
diff --git a/exchange/exchange.go b/exchange/exchange.go
index 4251c3e2..e7ba2839 100644
--- a/exchange/exchange.go
+++ b/exchange/exchange.go
@@ -1006,24 +1006,11 @@ func applyCategoryMapping(ctx context.Context, targeting openrtb_ext.ExtRequestT
 
 			priceBucket = GetPriceBucket(*bid.Bid, *targData)
 
-			newDur := duration
-			if len(targeting.DurationRangeSec) > 0 {
-				durationRange := make([]int, len(targeting.DurationRangeSec))
-				copy(durationRange, targeting.DurationRangeSec)
-				sort.Ints(durationRange)
-
-				//if the bid is above the range of the listed durations (and outside the buffer), reject the bid
-				if duration > durationRange[len(durationRange)-1] {
-					bidsToRemove = append(bidsToRemove, bidInd)
-					rejections = updateRejections(rejections, bidID, "Bid duration exceeds maximum allowed")
-					continue
-				}
-				for _, dur := range durationRange {
-					if duration <= dur {
-						newDur = dur
-						break
-					}
-				}
+			newDur, err := findDurationRange(duration, targeting.DurationRangeSec)
+			if err != nil {
+				bidsToRemove = append(bidsToRemove, bidInd)
+				rejections = updateRejections(rejections, bidID, err.Error())
+				continue
 			}
 
 			var categoryDuration string
@@ -1113,6 +1100,33 @@ func applyCategoryMapping(ctx context.Context, targeting openrtb_ext.ExtRequestT
 	return res, seatBids, rejections, nil
 }
 
+// findDurationRange returns the element in the array 'durationRanges' that is both greater than 'dur' and closest
+// in value to 'dur' unless a value equal to 'dur' is found. Returns an error if all elements in 'durationRanges'
+// are less than 'dur'.
+func findDurationRange(dur int, durationRanges []int) (int, error) {
+	newDur := dur
+	madeSelection := false
+	var err error
+
+	for i := range durationRanges {
+		if dur > durationRanges[i] {
+			continue
+		}
+		if dur == durationRanges[i] {
+			return durationRanges[i], nil
+		}
+		// dur < durationRanges[i]
+		if durationRanges[i] < newDur || !madeSelection {
+			newDur = durationRanges[i]
+			madeSelection = true
+		}
+	}
+	if !madeSelection && len(durationRanges) > 0 {
+		err = errors.New("bid duration exceeds maximum allowed")
+	}
+	return newDur, err
+}
+
 func removeBidById(seatBid *entities.PbsOrtbSeatBid, bidID string) {
 	//Find index of bid to remove
 	dupeBidIndex := -1
diff --git a/hooks/repo.go b/hooks/repo.go
index 033a3f8f..40276701 100644
--- a/hooks/repo.go
+++ b/hooks/repo.go
@@ -2,6 +2,7 @@ package hooks
 
 import (
 	"fmt"
+
 	"github.com/prebid/prebid-server/hooks/hookstage"
 )
 
@@ -50,7 +51,7 @@ type hookRepository struct {
 	auctionResponseHooks         map[string]hookstage.AuctionResponse
 }
 
-func (r *hookRepository) GetEntrypointHook(id string) (h hookstage.Entrypoint, ok bool) {
+func (r *hookRepository) GetEntrypointHook(id string) (hookstage.Entrypoint, bool) {
 	return getHook(r.entrypointHooks, id)
 }
 
diff --git a/server/listener.go b/server/listener.go
index 065cb2de..43917ac0 100644
--- a/server/listener.go
+++ b/server/listener.go
@@ -38,7 +38,7 @@ func (l *monitorableConnection) Close() error {
 	return err
 }
 
-func (ln *monitorableListener) Accept() (c net.Conn, err error) {
+func (ln *monitorableListener) Accept() (net.Conn, error) {
 	tc, err := ln.Listener.Accept()
 	if err != nil {
 		glog.Errorf("Error accepting connection: %v", err)
diff --git a/static/bidder-info/lunamedia.yaml b/static/bidder-info/lunamedia.yaml
index 79e19a43..ef34143e 100644
--- a/static/bidder-info/lunamedia.yaml
+++ b/static/bidder-info/lunamedia.yaml
@@ -1,4 +1,4 @@
-endpoint: "http://api.lunamedia.io/xp/get?pubid={{.PublisherID}}"
+endpoint: "http://rtb.lunamedia.live/?pid={{.PublisherID}}"
 maintainer:
   email: "josh@lunamedia.io"
 capabilities:
@@ -6,13 +6,11 @@ capabilities:
     mediaTypes:
     - banner
     - video
-    
   app:
     mediaTypes:
     - banner
     - video
 userSync:
   iframe:
-    url: "https://api.lunamedia.io/xp/user-sync?redirect={{.RedirectURL}}"
-    userMacro: "$UID"
-
+    url: "https://sync.lunamedia.live/psync?t=s&e=0&cb={{.RedirectURL}}"
+    userMacro: "%USER_ID%"


Test patch:
diff --git a/adapters/lunamedia/lunamedia_test.go b/adapters/lunamedia/lunamedia_test.go
index ef109d92..961cd545 100644
--- a/adapters/lunamedia/lunamedia_test.go
+++ b/adapters/lunamedia/lunamedia_test.go
@@ -11,7 +11,7 @@ import (
 
 func TestJsonSamples(t *testing.T) {
 	bidder, buildErr := Builder(openrtb_ext.BidderLunaMedia, config.Adapter{
-		Endpoint: "http://api.lunamedia.io/xp/get?pubid={{.PublisherID}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"})
+		Endpoint: "http://rtb.lunamedia.live/?pid={{.PublisherID}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"})
 
 	if buildErr != nil {
 		t.Fatalf("Builder returned unexpected error %v", buildErr)
diff --git a/adapters/lunamedia/lunamediatest/exemplary/banner.json b/adapters/lunamedia/lunamediatest/exemplary/banner.json
index 3b5c417f..fa92565b 100644
--- a/adapters/lunamedia/lunamediatest/exemplary/banner.json
+++ b/adapters/lunamedia/lunamediatest/exemplary/banner.json
@@ -31,7 +31,7 @@
   "httpCalls": [
     {
       "expectedRequest": {
-        "uri": "http://api.lunamedia.io/xp/get?pubid=19f1b372c7548ec1fe734d2c9f8dc688",
+        "uri": "http://rtb.lunamedia.live/?pid=19f1b372c7548ec1fe734d2c9f8dc688",
         "body":{
           "id": "testid",
           "imp": [{
diff --git a/adapters/lunamedia/lunamediatest/exemplary/video.json b/adapters/lunamedia/lunamediatest/exemplary/video.json
index 82217373..834963ff 100644
--- a/adapters/lunamedia/lunamediatest/exemplary/video.json
+++ b/adapters/lunamedia/lunamediatest/exemplary/video.json
@@ -24,7 +24,7 @@
   "httpCalls": [
     {
       "expectedRequest": {
-        "uri": "http://api.lunamedia.io/xp/get?pubid=19f1b372c7548ec1fe734d2c9f8dc688",
+        "uri": "http://rtb.lunamedia.live/?pid=19f1b372c7548ec1fe734d2c9f8dc688",
         "body":{
           "id": "testid",
           "imp": [{
diff --git a/adapters/lunamedia/lunamediatest/supplemental/compat.json b/adapters/lunamedia/lunamediatest/supplemental/compat.json
index 5b84d3a5..7fc713e0 100644
--- a/adapters/lunamedia/lunamediatest/supplemental/compat.json
+++ b/adapters/lunamedia/lunamediatest/supplemental/compat.json
@@ -23,7 +23,7 @@
   "httpCalls": [
     {
       "expectedRequest": {
-        "uri": "http://api.lunamedia.io/xp/get?pubid=19f1b372c7548ec1fe734d2c9f8dc688",
+        "uri": "http://rtb.lunamedia.live/?pid=19f1b372c7548ec1fe734d2c9f8dc688",
         "body":{
           "id": "testid",
           "imp": [{
diff --git a/adapters/lunamedia/lunamediatest/supplemental/responseCode.json b/adapters/lunamedia/lunamediatest/supplemental/responseCode.json
index 739af044..075d121a 100644
--- a/adapters/lunamedia/lunamediatest/supplemental/responseCode.json
+++ b/adapters/lunamedia/lunamediatest/supplemental/responseCode.json
@@ -33,7 +33,7 @@
   "httpCalls": [
       {
           "expectedRequest": {
-              "uri": "http://api.lunamedia.io/xp/get?pubid=yu",
+              "uri": "http://rtb.lunamedia.live/?pid=yu",
               "body": {
                   "id": "testid",
                   "imp": [
diff --git a/adapters/lunamedia/lunamediatest/supplemental/responsebid.json b/adapters/lunamedia/lunamediatest/supplemental/responsebid.json
index e9d8c3c5..f8c5b67a 100644
--- a/adapters/lunamedia/lunamediatest/supplemental/responsebid.json
+++ b/adapters/lunamedia/lunamediatest/supplemental/responsebid.json
@@ -33,7 +33,7 @@
   "httpCalls": [
       {
           "expectedRequest": {
-              "uri": "http://api.lunamedia.io/xp/get?pubid=yu",
+              "uri": "http://rtb.lunamedia.live/?pid=yu",
               "body": {
                   "id": "testid",
                   "imp": [
diff --git a/adapters/lunamedia/lunamediatest/supplemental/site.json b/adapters/lunamedia/lunamediatest/supplemental/site.json
index 81d71554..b2610cec 100644
--- a/adapters/lunamedia/lunamediatest/supplemental/site.json
+++ b/adapters/lunamedia/lunamediatest/supplemental/site.json
@@ -33,7 +33,7 @@
   "httpCalls": [
       {
           "expectedRequest": {
-              "uri": "http://api.lunamedia.io/xp/get?pubid=19f1b372c7548ec1fe734d2c9f8dc688",
+              "uri": "http://rtb.lunamedia.live/?pid=19f1b372c7548ec1fe734d2c9f8dc688",
               "body": {
                   "id": "testid",
                   "imp": [
diff --git a/exchange/exchange_test.go b/exchange/exchange_test.go
index 962b1dd9..511fd84b 100644
--- a/exchange/exchange_test.go
+++ b/exchange/exchange_test.go
@@ -7,6 +7,7 @@ import (
 	"errors"
 	"fmt"
 	"io"
+	"math"
 	"net/http"
 	"net/http/httptest"
 	"os"
@@ -3188,7 +3189,7 @@ func TestCategoryMappingBidderNameNoCategories(t *testing.T) {
 		includeWinners:   true,
 	}
 
-	requestExt.Prebid.Targeting.DurationRangeSec = []int{15, 30}
+	requestExt.Prebid.Targeting.DurationRangeSec = []int{30, 10, 25, 5, 20, 50}
 
 	adapterBids := make(map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid)
 
@@ -3197,8 +3198,8 @@ func TestCategoryMappingBidderNameNoCategories(t *testing.T) {
 	bid1 := openrtb2.Bid{ID: "bid_id1", ImpID: "imp_id1", Price: 10.0000, Cat: cats1, W: 1, H: 1}
 	bid2 := openrtb2.Bid{ID: "bid_id2", ImpID: "imp_id2", Price: 12.0000, Cat: cats2, W: 1, H: 1}
 
-	bid1_1 := entities.PbsOrtbBid{&bid1, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, nil, 0, false, "", 10.0000, "USD", ""}
-	bid1_2 := entities.PbsOrtbBid{&bid2, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, nil, 0, false, "", 12.0000, "USD", ""}
+	bid1_1 := entities.PbsOrtbBid{&bid1, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 17}, nil, nil, 0, false, "", 10.0000, "USD", ""}
+	bid1_2 := entities.PbsOrtbBid{&bid2, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 8}, nil, nil, 0, false, "", 12.0000, "USD", ""}
 
 	innerBids1 := []*entities.PbsOrtbBid{
 		&bid1_1,
@@ -3220,8 +3221,8 @@ func TestCategoryMappingBidderNameNoCategories(t *testing.T) {
 
 	assert.NoError(t, err, "Category mapping error should be empty")
 	assert.Empty(t, rejections, "There should be 0 bid rejection messages")
-	assert.Equal(t, "10.00_30s_bidder1", bidCategory["bid_id1"], "Category mapping doesn't match")
-	assert.Equal(t, "12.00_30s_bidder2", bidCategory["bid_id2"], "Category mapping doesn't match")
+	assert.Equal(t, "10.00_20s_bidder1", bidCategory["bid_id1"], "Category mapping doesn't match")
+	assert.Equal(t, "12.00_10s_bidder2", bidCategory["bid_id2"], "Category mapping doesn't match")
 	assert.Len(t, adapterBids[bidderName1].Bids, 1, "Bidders number doesn't match")
 	assert.Len(t, adapterBids[bidderName2].Bids, 1, "Bidders number doesn't match")
 	assert.Len(t, bidCategory, 2, "Bidders category mapping doesn't match")
@@ -3287,7 +3288,7 @@ func TestBidRejectionErrors(t *testing.T) {
 			},
 			duration: 70,
 			expectedRejections: []string{
-				"bid rejected [bid ID: bid_id1] reason: Bid duration exceeds maximum allowed",
+				"bid rejected [bid ID: bid_id1] reason: bid duration exceeds maximum allowed",
 			},
 		},
 		{
@@ -5641,6 +5642,77 @@ func TestNilAuctionRequest(t *testing.T) {
 	assert.Nil(t, err)
 }
 
+func TestSelectNewDuration(t *testing.T) {
+	type testInput struct {
+		dur       int
+		durRanges []int
+	}
+	type testOutput struct {
+		dur int
+		err error
+	}
+	testCases := []struct {
+		desc     string
+		in       testInput
+		expected testOutput
+	}{
+		{
+			desc: "nil duration range array, don't expect error",
+			in: testInput{
+				dur:       1,
+				durRanges: nil,
+			},
+			expected: testOutput{1, nil},
+		},
+		{
+			desc: "empty duration range array, don't expect error",
+			in: testInput{
+				dur:       1,
+				durRanges: []int{},
+			},
+			expected: testOutput{1, nil},
+		},
+		{
+			desc: "all duration range array elements less than duration, expect error",
+			in: testInput{
+				dur:       5,
+				durRanges: []int{-1, 0, 1, 2, 3},
+			},
+			expected: testOutput{5, errors.New("bid duration exceeds maximum allowed")},
+		},
+		{
+			desc: "all duration range array elements greater than duration, expect smallest element in durRanges and nil error",
+			in: testInput{
+				dur:       5,
+				durRanges: []int{9, math.MaxInt32, 8},
+			},
+			expected: testOutput{8, nil},
+		},
+		{
+			desc: "some array elements greater than duration, expect the value greater than dur that is closest in value.",
+			in: testInput{
+				dur:       5,
+				durRanges: []int{math.MaxInt32, -3, 7, 2},
+			},
+			expected: testOutput{7, nil},
+		},
+		{
+			desc: "an entry in the duration range array is equal to duration, expect its value in return.",
+			in: testInput{
+				dur:       5,
+				durRanges: []int{-3, math.MaxInt32, 5, 7},
+			},
+			expected: testOutput{5, nil},
+		},
+	}
+	for _, tc := range testCases {
+		newDur, err := findDurationRange(tc.in.dur, tc.in.durRanges)
+
+		assert.Equal(t, tc.expected.dur, newDur, tc.desc)
+		assert.Equal(t, tc.expected.err, err, tc.desc)
+	}
+}
+
 func TestSetSeatNonBid(t *testing.T) {
 	type args struct {
 		bidResponseExt *openrtb_ext.ExtBidResponse
diff --git a/exchange/utils_test.go b/exchange/utils_test.go
index 6fe0e55f..8bb82fe4 100644
--- a/exchange/utils_test.go
+++ b/exchange/utils_test.go
@@ -39,8 +39,8 @@ func (p *permissionsMock) BidderSyncAllowed(ctx context.Context, bidder openrtb_
 	return true, nil
 }
 
-func (p *permissionsMock) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) (permissions gdpr.AuctionPermissions, err error) {
-	permissions = gdpr.AuctionPermissions{
+func (p *permissionsMock) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) (gdpr.AuctionPermissions, error) {
+	permissions := gdpr.AuctionPermissions{
 		PassGeo: p.passGeo,
 		PassID:  p.passID,
 	}