github.com/prebid/prebid-server/v2@v2.18.0/exchange/adapter_util_test.go (about)

     1  package exchange
     2  
     3  import (
     4  	"errors"
     5  	"net/http"
     6  	"testing"
     7  
     8  	"github.com/prebid/openrtb/v20/openrtb2"
     9  	"github.com/prebid/prebid-server/v2/adapters"
    10  	"github.com/prebid/prebid-server/v2/adapters/appnexus"
    11  	"github.com/prebid/prebid-server/v2/adapters/rubicon"
    12  	"github.com/prebid/prebid-server/v2/config"
    13  	metrics "github.com/prebid/prebid-server/v2/metrics/config"
    14  	"github.com/prebid/prebid-server/v2/openrtb_ext"
    15  	"github.com/stretchr/testify/assert"
    16  	"github.com/stretchr/testify/require"
    17  )
    18  
    19  var (
    20  	infoEnabled  = config.BidderInfo{Disabled: false}
    21  	infoDisabled = config.BidderInfo{Disabled: true}
    22  )
    23  
    24  func TestBuildAdapters(t *testing.T) {
    25  	client := &http.Client{}
    26  	metricEngine := &metrics.NilMetricsEngine{}
    27  
    28  	appnexusBidder, _ := appnexus.Builder(openrtb_ext.BidderAppnexus, config.Adapter{}, config.Server{})
    29  	appnexusBidderWithInfo := adapters.BuildInfoAwareBidder(appnexusBidder, infoEnabled)
    30  	appnexusBidderAdapted := AdaptBidder(appnexusBidderWithInfo, client, &config.Configuration{}, metricEngine, openrtb_ext.BidderAppnexus, nil, "")
    31  	appnexusValidated := addValidatedBidderMiddleware(appnexusBidderAdapted)
    32  
    33  	rubiconBidder, _ := rubicon.Builder(openrtb_ext.BidderRubicon, config.Adapter{}, config.Server{})
    34  	rubiconBidderWithInfo := adapters.BuildInfoAwareBidder(rubiconBidder, infoEnabled)
    35  	rubiconBidderAdapted := AdaptBidder(rubiconBidderWithInfo, client, &config.Configuration{}, metricEngine, openrtb_ext.BidderRubicon, nil, "")
    36  	rubiconBidderValidated := addValidatedBidderMiddleware(rubiconBidderAdapted)
    37  
    38  	testCases := []struct {
    39  		description     string
    40  		bidderInfos     map[string]config.BidderInfo
    41  		expectedBidders map[openrtb_ext.BidderName]AdaptedBidder
    42  		expectedErrors  []error
    43  	}{
    44  		{
    45  			description:     "No Bidders",
    46  			bidderInfos:     map[string]config.BidderInfo{},
    47  			expectedBidders: map[openrtb_ext.BidderName]AdaptedBidder{},
    48  		},
    49  		{
    50  			description: "One Bidder",
    51  			bidderInfos: map[string]config.BidderInfo{"appnexus": infoEnabled},
    52  			expectedBidders: map[openrtb_ext.BidderName]AdaptedBidder{
    53  				openrtb_ext.BidderAppnexus: appnexusValidated,
    54  			},
    55  		},
    56  		{
    57  			description: "Many Bidders",
    58  			bidderInfos: map[string]config.BidderInfo{"appnexus": infoEnabled, "rubicon": infoEnabled},
    59  			expectedBidders: map[openrtb_ext.BidderName]AdaptedBidder{
    60  				openrtb_ext.BidderAppnexus: appnexusValidated,
    61  				openrtb_ext.BidderRubicon:  rubiconBidderValidated,
    62  			},
    63  		},
    64  		{
    65  			description: "Invalid - Builder Errors",
    66  			bidderInfos: map[string]config.BidderInfo{"unknown": {}, "appNexus": {}},
    67  			expectedErrors: []error{
    68  				errors.New("unknown: unknown bidder"),
    69  			},
    70  		},
    71  	}
    72  
    73  	cfg := &config.Configuration{}
    74  	for _, test := range testCases {
    75  		bidders, errs := BuildAdapters(client, cfg, test.bidderInfos, metricEngine)
    76  		assert.Equal(t, test.expectedBidders, bidders, test.description+":bidders")
    77  		assert.ElementsMatch(t, test.expectedErrors, errs, test.description+":errors")
    78  	}
    79  }
    80  
    81  func TestBuildBidders(t *testing.T) {
    82  	appnexusBidder := fakeBidder{"a"}
    83  	appnexusBuilder := fakeBuilder{appnexusBidder, nil}.Builder
    84  	appnexusBuilderWithError := fakeBuilder{appnexusBidder, errors.New("anyError")}.Builder
    85  
    86  	rubiconBidder := fakeBidder{"b"}
    87  	rubiconBuilder := fakeBuilder{rubiconBidder, nil}.Builder
    88  
    89  	server := config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}
    90  
    91  	testCases := []struct {
    92  		description     string
    93  		bidderInfos     map[string]config.BidderInfo
    94  		builders        map[openrtb_ext.BidderName]adapters.Builder
    95  		expectedBidders map[openrtb_ext.BidderName]adapters.Bidder
    96  		expectedErrors  []error
    97  	}{
    98  		{
    99  			description: "Invalid - Unknown Bidder",
   100  			bidderInfos: map[string]config.BidderInfo{"unknown": infoEnabled},
   101  			builders:    map[openrtb_ext.BidderName]adapters.Builder{openrtb_ext.BidderAppnexus: appnexusBuilder},
   102  			expectedErrors: []error{
   103  				errors.New("unknown: unknown bidder"),
   104  			},
   105  		},
   106  		{
   107  			description: "Invalid - No Builder",
   108  			bidderInfos: map[string]config.BidderInfo{"appnexus": infoEnabled},
   109  			builders:    map[openrtb_ext.BidderName]adapters.Builder{},
   110  			expectedErrors: []error{
   111  				errors.New("appnexus: builder not registered"),
   112  			},
   113  		},
   114  		{
   115  			description: "Success - Builder Error",
   116  			bidderInfos: map[string]config.BidderInfo{"appnexus": infoEnabled},
   117  			builders:    map[openrtb_ext.BidderName]adapters.Builder{openrtb_ext.BidderAppnexus: appnexusBuilderWithError},
   118  			expectedErrors: []error{
   119  				errors.New("appnexus: anyError"),
   120  			},
   121  		},
   122  		{
   123  			description: "Success - None",
   124  			bidderInfos: map[string]config.BidderInfo{},
   125  			builders:    map[openrtb_ext.BidderName]adapters.Builder{},
   126  		},
   127  		{
   128  			description: "Success - One",
   129  			bidderInfos: map[string]config.BidderInfo{"appnexus": infoEnabled},
   130  			builders:    map[openrtb_ext.BidderName]adapters.Builder{openrtb_ext.BidderAppnexus: appnexusBuilder},
   131  			expectedBidders: map[openrtb_ext.BidderName]adapters.Bidder{
   132  				openrtb_ext.BidderAppnexus: adapters.BuildInfoAwareBidder(appnexusBidder, infoEnabled),
   133  			},
   134  		},
   135  		{
   136  			description: "Success - Many",
   137  			bidderInfos: map[string]config.BidderInfo{"appnexus": infoEnabled, "rubicon": infoEnabled},
   138  			builders:    map[openrtb_ext.BidderName]adapters.Builder{openrtb_ext.BidderAppnexus: appnexusBuilder, openrtb_ext.BidderRubicon: rubiconBuilder},
   139  			expectedBidders: map[openrtb_ext.BidderName]adapters.Bidder{
   140  				openrtb_ext.BidderAppnexus: adapters.BuildInfoAwareBidder(appnexusBidder, infoEnabled),
   141  				openrtb_ext.BidderRubicon:  adapters.BuildInfoAwareBidder(rubiconBidder, infoEnabled),
   142  			},
   143  		},
   144  		{
   145  			description: "Success - Ignores Disabled",
   146  			bidderInfos: map[string]config.BidderInfo{"appnexus": infoDisabled, "rubicon": infoEnabled},
   147  			builders:    map[openrtb_ext.BidderName]adapters.Builder{openrtb_ext.BidderAppnexus: appnexusBuilder, openrtb_ext.BidderRubicon: rubiconBuilder},
   148  			expectedBidders: map[openrtb_ext.BidderName]adapters.Bidder{
   149  				openrtb_ext.BidderRubicon: adapters.BuildInfoAwareBidder(rubiconBidder, infoEnabled),
   150  			},
   151  		},
   152  	}
   153  
   154  	for _, test := range testCases {
   155  		bidders, errs := buildBidders(test.bidderInfos, test.builders, server)
   156  
   157  		// For Test Setup Convenience
   158  		if test.expectedBidders == nil {
   159  			test.expectedBidders = make(map[openrtb_ext.BidderName]adapters.Bidder)
   160  		}
   161  
   162  		assert.Equal(t, test.expectedBidders, bidders, test.description+":bidders")
   163  		assert.ElementsMatch(t, test.expectedErrors, errs, test.description+":errors")
   164  	}
   165  }
   166  
   167  func TestSetAliasBuilder(t *testing.T) {
   168  	rubiconBidder := fakeBidder{"b"}
   169  	ixBidder := fakeBidder{"ix"}
   170  	rubiconBuilder := fakeBuilder{rubiconBidder, nil}.Builder
   171  	ixBuilder := fakeBuilder{ixBidder, nil}.Builder
   172  
   173  	testCases := []struct {
   174  		description      string
   175  		bidderInfo       config.BidderInfo
   176  		builders         map[openrtb_ext.BidderName]adapters.Builder
   177  		bidderName       openrtb_ext.BidderName
   178  		expectedBuilders map[openrtb_ext.BidderName]adapters.Builder
   179  		expectedError    error
   180  	}{
   181  		{
   182  			description:      "Success - Alias builder",
   183  			bidderInfo:       config.BidderInfo{Disabled: false, AliasOf: "rubicon"},
   184  			bidderName:       openrtb_ext.BidderName("appnexus"),
   185  			builders:         map[openrtb_ext.BidderName]adapters.Builder{openrtb_ext.BidderRubicon: rubiconBuilder},
   186  			expectedBuilders: map[openrtb_ext.BidderName]adapters.Builder{openrtb_ext.BidderRubicon: rubiconBuilder, openrtb_ext.BidderAppnexus: rubiconBuilder},
   187  		},
   188  		{
   189  			description:   "Failure - Invalid parent bidder builder",
   190  			bidderInfo:    config.BidderInfo{Disabled: false, AliasOf: "rubicon"},
   191  			bidderName:    openrtb_ext.BidderName("appnexus"),
   192  			builders:      map[openrtb_ext.BidderName]adapters.Builder{openrtb_ext.BidderIx: ixBuilder},
   193  			expectedError: errors.New("rubicon: parent builder not registered"),
   194  		},
   195  		{
   196  			description:   "Failure - Invalid parent for alias",
   197  			bidderInfo:    config.BidderInfo{Disabled: false, AliasOf: "unknown"},
   198  			bidderName:    openrtb_ext.BidderName("appnexus"),
   199  			builders:      map[openrtb_ext.BidderName]adapters.Builder{openrtb_ext.BidderIx: ixBuilder},
   200  			expectedError: errors.New("unknown parent bidder: unknown for alias: appnexus"),
   201  		},
   202  	}
   203  
   204  	for _, test := range testCases {
   205  		err := setAliasBuilder(test.bidderInfo, test.builders, test.bidderName)
   206  
   207  		if test.expectedBuilders != nil {
   208  			assert.ObjectsAreEqual(test.builders, test.expectedBuilders)
   209  		}
   210  		if test.expectedError != nil {
   211  			assert.EqualError(t, test.expectedError, err.Error(), test.description+":errors")
   212  		}
   213  	}
   214  }
   215  
   216  func TestGetActiveBidders(t *testing.T) {
   217  	testCases := []struct {
   218  		description string
   219  		bidderInfos map[string]config.BidderInfo
   220  		expected    map[string]openrtb_ext.BidderName
   221  	}{
   222  		{
   223  			description: "None",
   224  			bidderInfos: map[string]config.BidderInfo{},
   225  			expected:    map[string]openrtb_ext.BidderName{},
   226  		},
   227  		{
   228  			description: "Enabled",
   229  			bidderInfos: map[string]config.BidderInfo{"appnexus": infoEnabled},
   230  			expected:    map[string]openrtb_ext.BidderName{"appnexus": openrtb_ext.BidderAppnexus},
   231  		},
   232  		{
   233  			description: "Disabled",
   234  			bidderInfos: map[string]config.BidderInfo{"appnexus": infoDisabled},
   235  			expected:    map[string]openrtb_ext.BidderName{},
   236  		},
   237  		{
   238  			description: "Mixed",
   239  			bidderInfos: map[string]config.BidderInfo{"appnexus": infoDisabled, "openx": infoEnabled},
   240  			expected:    map[string]openrtb_ext.BidderName{"openx": openrtb_ext.BidderOpenx},
   241  		},
   242  	}
   243  
   244  	for _, test := range testCases {
   245  		result := GetActiveBidders(test.bidderInfos)
   246  		assert.Equal(t, test.expected, result, test.description)
   247  	}
   248  }
   249  
   250  func TestGetDisabledBidderWarningMessages(t *testing.T) {
   251  	t.Run("removed", func(t *testing.T) {
   252  		result := GetDisabledBidderWarningMessages(nil)
   253  
   254  		// test proper construction by verifying one expected bidder is in the list
   255  		require.Contains(t, result, "groupm")
   256  		assert.Equal(t, result["groupm"], `Bidder "groupm" is no longer available in Prebid Server. Please update your configuration.`)
   257  	})
   258  
   259  	t.Run("removed-and-disabled", func(t *testing.T) {
   260  		result := GetDisabledBidderWarningMessages(map[string]config.BidderInfo{"bidderA": infoDisabled})
   261  
   262  		// test proper construction by verifying one expected bidder is in the list with the disabled bidder
   263  		require.Contains(t, result, "groupm")
   264  		assert.Equal(t, result["groupm"], `Bidder "groupm" is no longer available in Prebid Server. Please update your configuration.`)
   265  
   266  		require.Contains(t, result, "bidderA")
   267  		assert.Equal(t, result["bidderA"], `Bidder "bidderA" has been disabled on this instance of Prebid Server. Please work with the PBS host to enable this bidder again.`)
   268  	})
   269  }
   270  
   271  func TestMergeRemovedAndDisabledBidderWarningMessages(t *testing.T) {
   272  	testCases := []struct {
   273  		name             string
   274  		givenRemoved     map[string]string
   275  		givenBidderInfos map[string]config.BidderInfo
   276  		expected         map[string]string
   277  	}{
   278  		{
   279  			name:             "none",
   280  			givenRemoved:     map[string]string{},
   281  			givenBidderInfos: map[string]config.BidderInfo{},
   282  			expected:         map[string]string{},
   283  		},
   284  		{
   285  			name:             "removed",
   286  			givenRemoved:     map[string]string{"bidderA": `Bidder A Message`},
   287  			givenBidderInfos: map[string]config.BidderInfo{},
   288  			expected:         map[string]string{"bidderA": `Bidder A Message`},
   289  		},
   290  		{
   291  			name:             "enabled",
   292  			givenRemoved:     map[string]string{},
   293  			givenBidderInfos: map[string]config.BidderInfo{"bidderA": infoEnabled},
   294  			expected:         map[string]string{},
   295  		},
   296  		{
   297  			name:             "disabled",
   298  			givenRemoved:     map[string]string{},
   299  			givenBidderInfos: map[string]config.BidderInfo{"bidderA": infoDisabled},
   300  			expected:         map[string]string{"bidderA": `Bidder "bidderA" has been disabled on this instance of Prebid Server. Please work with the PBS host to enable this bidder again.`},
   301  		},
   302  		{
   303  			name:             "mixed",
   304  			givenRemoved:     map[string]string{"bidderA": `Bidder A Message`},
   305  			givenBidderInfos: map[string]config.BidderInfo{"bidderB": infoEnabled, "bidderC": infoDisabled},
   306  			expected:         map[string]string{"bidderA": `Bidder A Message`, "bidderC": `Bidder "bidderC" has been disabled on this instance of Prebid Server. Please work with the PBS host to enable this bidder again.`},
   307  		},
   308  	}
   309  
   310  	for _, test := range testCases {
   311  		t.Run(test.name, func(t *testing.T) {
   312  			result := mergeRemovedAndDisabledBidderWarningMessages(test.givenRemoved, test.givenBidderInfos)
   313  			assert.Equal(t, test.expected, result, test.name)
   314  		})
   315  	}
   316  }
   317  
   318  type fakeBidder struct {
   319  	name string
   320  }
   321  
   322  func (fakeBidder) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
   323  	return nil, nil
   324  }
   325  
   326  func (fakeBidder) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) {
   327  	return nil, nil
   328  }
   329  
   330  type fakeBuilder struct {
   331  	bidder adapters.Bidder
   332  	err    error
   333  }
   334  
   335  func (b fakeBuilder) Builder(name openrtb_ext.BidderName, cfg config.Adapter, server config.Server) (adapters.Bidder, error) {
   336  	return b.bidder, b.err
   337  }