github.com/prebid/prebid-server@v0.275.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/v19/openrtb2"
     9  	"github.com/prebid/prebid-server/adapters"
    10  	"github.com/prebid/prebid-server/adapters/appnexus"
    11  	"github.com/prebid/prebid-server/adapters/rubicon"
    12  	"github.com/prebid/prebid-server/config"
    13  	metrics "github.com/prebid/prebid-server/metrics/config"
    14  	"github.com/prebid/prebid-server/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  			description: "Alias feature disabled",
    73  			bidderInfos: map[string]config.BidderInfo{"appNexus": {AliasOf: "rubicon"}},
    74  			expectedErrors: []error{
    75  				errors.New("This feature is currently under development"),
    76  			},
    77  		},
    78  	}
    79  
    80  	cfg := &config.Configuration{}
    81  	for _, test := range testCases {
    82  		bidders, errs := BuildAdapters(client, cfg, test.bidderInfos, metricEngine)
    83  		assert.Equal(t, test.expectedBidders, bidders, test.description+":bidders")
    84  		assert.ElementsMatch(t, test.expectedErrors, errs, test.description+":errors")
    85  	}
    86  }
    87  
    88  func TestBuildBidders(t *testing.T) {
    89  	appnexusBidder := fakeBidder{"a"}
    90  	appnexusBuilder := fakeBuilder{appnexusBidder, nil}.Builder
    91  	appnexusBuilderWithError := fakeBuilder{appnexusBidder, errors.New("anyError")}.Builder
    92  
    93  	rubiconBidder := fakeBidder{"b"}
    94  	rubiconBuilder := fakeBuilder{rubiconBidder, nil}.Builder
    95  
    96  	server := config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}
    97  
    98  	testCases := []struct {
    99  		description     string
   100  		bidderInfos     map[string]config.BidderInfo
   101  		builders        map[openrtb_ext.BidderName]adapters.Builder
   102  		expectedBidders map[openrtb_ext.BidderName]adapters.Bidder
   103  		expectedErrors  []error
   104  	}{
   105  		{
   106  			description: "Invalid - Unknown Bidder",
   107  			bidderInfos: map[string]config.BidderInfo{"unknown": infoEnabled},
   108  			builders:    map[openrtb_ext.BidderName]adapters.Builder{openrtb_ext.BidderAppnexus: appnexusBuilder},
   109  			expectedErrors: []error{
   110  				errors.New("unknown: unknown bidder"),
   111  			},
   112  		},
   113  		{
   114  			description: "Invalid - No Builder",
   115  			bidderInfos: map[string]config.BidderInfo{"appnexus": infoEnabled},
   116  			builders:    map[openrtb_ext.BidderName]adapters.Builder{},
   117  			expectedErrors: []error{
   118  				errors.New("appnexus: builder not registered"),
   119  			},
   120  		},
   121  		{
   122  			description: "Success - Builder Error",
   123  			bidderInfos: map[string]config.BidderInfo{"appnexus": infoEnabled},
   124  			builders:    map[openrtb_ext.BidderName]adapters.Builder{openrtb_ext.BidderAppnexus: appnexusBuilderWithError},
   125  			expectedErrors: []error{
   126  				errors.New("appnexus: anyError"),
   127  			},
   128  		},
   129  		{
   130  			description: "Success - None",
   131  			bidderInfos: map[string]config.BidderInfo{},
   132  			builders:    map[openrtb_ext.BidderName]adapters.Builder{},
   133  		},
   134  		{
   135  			description: "Success - One",
   136  			bidderInfos: map[string]config.BidderInfo{"appnexus": infoEnabled},
   137  			builders:    map[openrtb_ext.BidderName]adapters.Builder{openrtb_ext.BidderAppnexus: appnexusBuilder},
   138  			expectedBidders: map[openrtb_ext.BidderName]adapters.Bidder{
   139  				openrtb_ext.BidderAppnexus: adapters.BuildInfoAwareBidder(appnexusBidder, infoEnabled),
   140  			},
   141  		},
   142  		{
   143  			description: "Success - Many",
   144  			bidderInfos: map[string]config.BidderInfo{"appnexus": infoEnabled, "rubicon": infoEnabled},
   145  			builders:    map[openrtb_ext.BidderName]adapters.Builder{openrtb_ext.BidderAppnexus: appnexusBuilder, openrtb_ext.BidderRubicon: rubiconBuilder},
   146  			expectedBidders: map[openrtb_ext.BidderName]adapters.Bidder{
   147  				openrtb_ext.BidderAppnexus: adapters.BuildInfoAwareBidder(appnexusBidder, infoEnabled),
   148  				openrtb_ext.BidderRubicon:  adapters.BuildInfoAwareBidder(rubiconBidder, infoEnabled),
   149  			},
   150  		},
   151  		{
   152  			description: "Success - Ignores Disabled",
   153  			bidderInfos: map[string]config.BidderInfo{"appnexus": infoDisabled, "rubicon": infoEnabled},
   154  			builders:    map[openrtb_ext.BidderName]adapters.Builder{openrtb_ext.BidderAppnexus: appnexusBuilder, openrtb_ext.BidderRubicon: rubiconBuilder},
   155  			expectedBidders: map[openrtb_ext.BidderName]adapters.Bidder{
   156  				openrtb_ext.BidderRubicon: adapters.BuildInfoAwareBidder(rubiconBidder, infoEnabled),
   157  			},
   158  		},
   159  	}
   160  
   161  	for _, test := range testCases {
   162  		bidders, errs := buildBidders(test.bidderInfos, test.builders, server)
   163  
   164  		// For Test Setup Convenience
   165  		if test.expectedBidders == nil {
   166  			test.expectedBidders = make(map[openrtb_ext.BidderName]adapters.Bidder)
   167  		}
   168  
   169  		assert.Equal(t, test.expectedBidders, bidders, test.description+":bidders")
   170  		assert.ElementsMatch(t, test.expectedErrors, errs, test.description+":errors")
   171  	}
   172  }
   173  
   174  func TestSetAliasBuilder(t *testing.T) {
   175  	rubiconBidder := fakeBidder{"b"}
   176  	ixBidder := fakeBidder{"ix"}
   177  	rubiconBuilder := fakeBuilder{rubiconBidder, nil}.Builder
   178  	ixBuilder := fakeBuilder{ixBidder, nil}.Builder
   179  
   180  	testCases := []struct {
   181  		description      string
   182  		bidderInfo       config.BidderInfo
   183  		builders         map[openrtb_ext.BidderName]adapters.Builder
   184  		bidderName       openrtb_ext.BidderName
   185  		expectedBuilders map[openrtb_ext.BidderName]adapters.Builder
   186  		expectedError    error
   187  	}{
   188  		{
   189  			description:      "Success - Alias 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.BidderRubicon: rubiconBuilder},
   193  			expectedBuilders: map[openrtb_ext.BidderName]adapters.Builder{openrtb_ext.BidderRubicon: rubiconBuilder, openrtb_ext.BidderAppnexus: rubiconBuilder},
   194  		},
   195  		{
   196  			description:   "Failure - Invalid parent bidder builder",
   197  			bidderInfo:    config.BidderInfo{Disabled: false, AliasOf: "rubicon"},
   198  			bidderName:    openrtb_ext.BidderName("appnexus"),
   199  			builders:      map[openrtb_ext.BidderName]adapters.Builder{openrtb_ext.BidderIx: ixBuilder},
   200  			expectedError: errors.New("rubicon: parent builder not registered"),
   201  		},
   202  		{
   203  			description:   "Failure - Invalid parent for alias",
   204  			bidderInfo:    config.BidderInfo{Disabled: false, AliasOf: "unknown"},
   205  			bidderName:    openrtb_ext.BidderName("appnexus"),
   206  			builders:      map[openrtb_ext.BidderName]adapters.Builder{openrtb_ext.BidderIx: ixBuilder},
   207  			expectedError: errors.New("unknown parent bidder: unknown for alias: appnexus"),
   208  		},
   209  	}
   210  
   211  	for _, test := range testCases {
   212  		err := setAliasBuilder(test.bidderInfo, test.builders, test.bidderName)
   213  
   214  		if test.expectedBuilders != nil {
   215  			assert.ObjectsAreEqual(test.builders, test.expectedBuilders)
   216  		}
   217  		if test.expectedError != nil {
   218  			assert.EqualError(t, test.expectedError, err.Error(), test.description+":errors")
   219  		}
   220  	}
   221  }
   222  
   223  func TestGetActiveBidders(t *testing.T) {
   224  	testCases := []struct {
   225  		description string
   226  		bidderInfos map[string]config.BidderInfo
   227  		expected    map[string]openrtb_ext.BidderName
   228  	}{
   229  		{
   230  			description: "None",
   231  			bidderInfos: map[string]config.BidderInfo{},
   232  			expected:    map[string]openrtb_ext.BidderName{},
   233  		},
   234  		{
   235  			description: "Enabled",
   236  			bidderInfos: map[string]config.BidderInfo{"appnexus": infoEnabled},
   237  			expected:    map[string]openrtb_ext.BidderName{"appnexus": openrtb_ext.BidderAppnexus},
   238  		},
   239  		{
   240  			description: "Disabled",
   241  			bidderInfos: map[string]config.BidderInfo{"appnexus": infoDisabled},
   242  			expected:    map[string]openrtb_ext.BidderName{},
   243  		},
   244  		{
   245  			description: "Mixed",
   246  			bidderInfos: map[string]config.BidderInfo{"appnexus": infoDisabled, "openx": infoEnabled},
   247  			expected:    map[string]openrtb_ext.BidderName{"openx": openrtb_ext.BidderOpenx},
   248  		},
   249  	}
   250  
   251  	for _, test := range testCases {
   252  		result := GetActiveBidders(test.bidderInfos)
   253  		assert.Equal(t, test.expected, result, test.description)
   254  	}
   255  }
   256  
   257  func TestGetDisabledBidderWarningMessages(t *testing.T) {
   258  	t.Run("removed", func(t *testing.T) {
   259  		result := GetDisabledBidderWarningMessages(nil)
   260  
   261  		// test proper construction by verifying one expected bidder is in the list
   262  		require.Contains(t, result, "groupm")
   263  		assert.Equal(t, result["groupm"], `Bidder "groupm" is no longer available in Prebid Server. Please update your configuration.`)
   264  	})
   265  
   266  	t.Run("removed-and-disabled", func(t *testing.T) {
   267  		result := GetDisabledBidderWarningMessages(map[string]config.BidderInfo{"bidderA": infoDisabled})
   268  
   269  		// test proper construction by verifying one expected bidder is in the list with the disabled bidder
   270  		require.Contains(t, result, "groupm")
   271  		assert.Equal(t, result["groupm"], `Bidder "groupm" is no longer available in Prebid Server. Please update your configuration.`)
   272  
   273  		require.Contains(t, result, "bidderA")
   274  		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.`)
   275  	})
   276  }
   277  
   278  func TestMergeRemovedAndDisabledBidderWarningMessages(t *testing.T) {
   279  	testCases := []struct {
   280  		name             string
   281  		givenRemoved     map[string]string
   282  		givenBidderInfos map[string]config.BidderInfo
   283  		expected         map[string]string
   284  	}{
   285  		{
   286  			name:             "none",
   287  			givenRemoved:     map[string]string{},
   288  			givenBidderInfos: map[string]config.BidderInfo{},
   289  			expected:         map[string]string{},
   290  		},
   291  		{
   292  			name:             "removed",
   293  			givenRemoved:     map[string]string{"bidderA": `Bidder A Message`},
   294  			givenBidderInfos: map[string]config.BidderInfo{},
   295  			expected:         map[string]string{"bidderA": `Bidder A Message`},
   296  		},
   297  		{
   298  			name:             "enabled",
   299  			givenRemoved:     map[string]string{},
   300  			givenBidderInfos: map[string]config.BidderInfo{"bidderA": infoEnabled},
   301  			expected:         map[string]string{},
   302  		},
   303  		{
   304  			name:             "disabled",
   305  			givenRemoved:     map[string]string{},
   306  			givenBidderInfos: map[string]config.BidderInfo{"bidderA": infoDisabled},
   307  			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.`},
   308  		},
   309  		{
   310  			name:             "mixed",
   311  			givenRemoved:     map[string]string{"bidderA": `Bidder A Message`},
   312  			givenBidderInfos: map[string]config.BidderInfo{"bidderB": infoEnabled, "bidderC": infoDisabled},
   313  			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.`},
   314  		},
   315  	}
   316  
   317  	for _, test := range testCases {
   318  		t.Run(test.name, func(t *testing.T) {
   319  			result := mergeRemovedAndDisabledBidderWarningMessages(test.givenRemoved, test.givenBidderInfos)
   320  			assert.Equal(t, test.expected, result, test.name)
   321  		})
   322  	}
   323  }
   324  
   325  type fakeBidder struct {
   326  	name string
   327  }
   328  
   329  func (fakeBidder) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
   330  	return nil, nil
   331  }
   332  
   333  func (fakeBidder) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) {
   334  	return nil, nil
   335  }
   336  
   337  type fakeBuilder struct {
   338  	bidder adapters.Bidder
   339  	err    error
   340  }
   341  
   342  func (b fakeBuilder) Builder(name openrtb_ext.BidderName, cfg config.Adapter, server config.Server) (adapters.Bidder, error) {
   343  	return b.bidder, b.err
   344  }