github.com/prebid/prebid-server@v0.275.0/config/bidderinfo_test.go (about)

     1  package config
     2  
     3  import (
     4  	"errors"
     5  	"strings"
     6  	"testing"
     7  
     8  	"gopkg.in/yaml.v3"
     9  
    10  	"github.com/prebid/prebid-server/openrtb_ext"
    11  	"github.com/stretchr/testify/assert"
    12  )
    13  
    14  const testInfoFilesPathValid = "./test/bidder-info-valid"
    15  const testSimpleYAML = `
    16  maintainer:
    17    email: some-email@domain.com
    18  gvlVendorID: 42
    19  `
    20  const fullBidderYAMLConfig = `
    21  maintainer:
    22    email: some-email@domain.com
    23  capabilities:
    24    app:
    25      mediaTypes:
    26        - banner
    27        - video
    28        - native
    29    site:
    30      mediaTypes:
    31        - banner
    32        - video
    33        - native
    34  modifyingVastXmlAllowed: true
    35  debug:
    36    allow: true
    37  gvlVendorID: 42
    38  experiment:
    39    adsCert:
    40      enabled: true
    41  endpointCompression: GZIP
    42  openrtb:
    43    version: 2.6
    44    gpp-supported: true
    45  endpoint: https://endpoint.com
    46  disabled: false
    47  extra_info: extra-info
    48  app_secret: app-secret
    49  platform_id: 123
    50  usersync_url: user-url
    51  userSync:
    52    key: foo
    53    default: iframe
    54    iframe:
    55      url: https://foo.com/sync?mode=iframe&r={{.RedirectURL}}
    56      redirectUrl: https://redirect/setuid/iframe
    57      externalUrl: https://iframe.host
    58      userMacro: UID
    59  xapi:
    60    username: uname
    61    password: pwd
    62    tracker: tracker
    63  `
    64  const testSimpleAliasYAML = `
    65  aliasOf: bidderA
    66  `
    67  
    68  func TestLoadBidderInfoFromDisk(t *testing.T) {
    69  	// should appear in result in mixed case
    70  	bidder := "stroeerCore"
    71  	trueValue := true
    72  
    73  	adapterConfigs := make(map[string]Adapter)
    74  	adapterConfigs[strings.ToLower(bidder)] = Adapter{}
    75  
    76  	infos, err := LoadBidderInfoFromDisk(testInfoFilesPathValid)
    77  	if err != nil {
    78  		t.Fatal(err)
    79  	}
    80  
    81  	expected := BidderInfos{
    82  		bidder: {
    83  			Disabled: false,
    84  			Maintainer: &MaintainerInfo{
    85  				Email: "some-email@domain.com",
    86  			},
    87  			GVLVendorID: 42,
    88  			Capabilities: &CapabilitiesInfo{
    89  				App: &PlatformInfo{
    90  					MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner, openrtb_ext.BidTypeNative},
    91  				},
    92  				Site: &PlatformInfo{
    93  					MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner, openrtb_ext.BidTypeVideo, openrtb_ext.BidTypeNative},
    94  				},
    95  			},
    96  			Syncer: &Syncer{
    97  				Key: "foo",
    98  				IFrame: &SyncerEndpoint{
    99  					URL:         "https://foo.com/sync?mode=iframe&r={{.RedirectURL}}",
   100  					RedirectURL: "{{.ExternalURL}}/setuid/iframe",
   101  					ExternalURL: "https://iframe.host",
   102  					UserMacro:   "%UID",
   103  				},
   104  				Redirect: &SyncerEndpoint{
   105  					URL:         "https://foo.com/sync?mode=redirect&r={{.RedirectURL}}",
   106  					RedirectURL: "{{.ExternalURL}}/setuid/redirect",
   107  					ExternalURL: "https://redirect.host",
   108  					UserMacro:   "#UID",
   109  				},
   110  				SupportCORS: &trueValue,
   111  			},
   112  		},
   113  	}
   114  	assert.Equal(t, expected, infos)
   115  }
   116  
   117  func TestProcessBidderInfo(t *testing.T) {
   118  	testCases := []struct {
   119  		description         string
   120  		bidderInfos         map[string][]byte
   121  		expectedBidderInfos BidderInfos
   122  		expectError         string
   123  	}{
   124  		{
   125  			description: "Valid bidder info",
   126  			bidderInfos: map[string][]byte{
   127  				"bidderA.yaml": []byte(testSimpleYAML),
   128  			},
   129  			expectedBidderInfos: BidderInfos{
   130  				"bidderA": BidderInfo{
   131  					Maintainer: &MaintainerInfo{
   132  						Email: "some-email@domain.com",
   133  					},
   134  					GVLVendorID: 42,
   135  				},
   136  			},
   137  			expectError: "",
   138  		},
   139  		{
   140  			description: "Bidder doesn't exist in bidder info list",
   141  			bidderInfos: map[string][]byte{
   142  				"unknown.yaml": []byte(testSimpleYAML),
   143  			},
   144  			expectedBidderInfos: nil,
   145  			expectError:         "error parsing config for bidder unknown.yaml",
   146  		},
   147  		{
   148  			description: "Invalid bidder config",
   149  			bidderInfos: map[string][]byte{
   150  				"bidderA.yaml": []byte("invalid bidder config"),
   151  			},
   152  			expectedBidderInfos: nil,
   153  			expectError:         "error parsing config for bidder bidderA.yaml",
   154  		},
   155  		{
   156  			description: "Invalid alias name",
   157  			bidderInfos: map[string][]byte{
   158  				"all.yaml": []byte(testSimpleAliasYAML),
   159  			},
   160  			expectedBidderInfos: nil,
   161  			expectError:         "alias all is a reserved bidder name and cannot be used",
   162  		},
   163  		{
   164  			description: "Valid aliases",
   165  			bidderInfos: map[string][]byte{
   166  				"bidderA.yaml": []byte(fullBidderYAMLConfig),
   167  				"bidderB.yaml": []byte(testSimpleAliasYAML),
   168  			},
   169  			expectedBidderInfos: BidderInfos{
   170  				"bidderA": BidderInfo{
   171  					AppSecret: "app-secret",
   172  					Capabilities: &CapabilitiesInfo{
   173  						App: &PlatformInfo{
   174  							MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner, openrtb_ext.BidTypeVideo, openrtb_ext.BidTypeNative},
   175  						},
   176  						Site: &PlatformInfo{
   177  							MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner, openrtb_ext.BidTypeVideo, openrtb_ext.BidTypeNative},
   178  						},
   179  					},
   180  					Debug: &DebugInfo{
   181  						Allow: true,
   182  					},
   183  					Disabled:            false,
   184  					Endpoint:            "https://endpoint.com",
   185  					EndpointCompression: "GZIP",
   186  					Experiment: BidderInfoExperiment{
   187  						AdsCert: BidderAdsCert{
   188  							Enabled: true,
   189  						},
   190  					},
   191  					ExtraAdapterInfo: "extra-info",
   192  					GVLVendorID:      42,
   193  					Maintainer: &MaintainerInfo{
   194  						Email: "some-email@domain.com",
   195  					},
   196  					ModifyingVastXmlAllowed: true,
   197  					OpenRTB: &OpenRTBInfo{
   198  						GPPSupported: true,
   199  						Version:      "2.6",
   200  					},
   201  					PlatformID: "123",
   202  					Syncer: &Syncer{
   203  						Key: "foo",
   204  						IFrame: &SyncerEndpoint{
   205  							URL:         "https://foo.com/sync?mode=iframe&r={{.RedirectURL}}",
   206  							RedirectURL: "https://redirect/setuid/iframe",
   207  							ExternalURL: "https://iframe.host",
   208  							UserMacro:   "UID",
   209  						},
   210  					},
   211  					UserSyncURL: "user-url",
   212  					XAPI: AdapterXAPI{
   213  						Username: "uname",
   214  						Password: "pwd",
   215  						Tracker:  "tracker",
   216  					},
   217  				},
   218  				"bidderB": BidderInfo{
   219  					AliasOf:   "bidderA",
   220  					AppSecret: "app-secret",
   221  					Capabilities: &CapabilitiesInfo{
   222  						App: &PlatformInfo{
   223  							MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner, openrtb_ext.BidTypeVideo, openrtb_ext.BidTypeNative},
   224  						},
   225  						Site: &PlatformInfo{
   226  							MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner, openrtb_ext.BidTypeVideo, openrtb_ext.BidTypeNative},
   227  						},
   228  					},
   229  					Debug: &DebugInfo{
   230  						Allow: true,
   231  					},
   232  					Disabled:            false,
   233  					Endpoint:            "https://endpoint.com",
   234  					EndpointCompression: "GZIP",
   235  					Experiment: BidderInfoExperiment{
   236  						AdsCert: BidderAdsCert{
   237  							Enabled: true,
   238  						},
   239  					},
   240  					ExtraAdapterInfo: "extra-info",
   241  					GVLVendorID:      42,
   242  					Maintainer: &MaintainerInfo{
   243  						Email: "some-email@domain.com",
   244  					},
   245  					ModifyingVastXmlAllowed: true,
   246  					OpenRTB: &OpenRTBInfo{
   247  						GPPSupported: true,
   248  						Version:      "2.6",
   249  					},
   250  					PlatformID: "123",
   251  					Syncer: &Syncer{
   252  						Key: "foo",
   253  						IFrame: &SyncerEndpoint{
   254  							URL:         "https://foo.com/sync?mode=iframe&r={{.RedirectURL}}",
   255  							RedirectURL: "https://redirect/setuid/iframe",
   256  							ExternalURL: "https://iframe.host",
   257  							UserMacro:   "UID",
   258  						},
   259  					},
   260  					UserSyncURL: "user-url",
   261  					XAPI: AdapterXAPI{
   262  						Username: "uname",
   263  						Password: "pwd",
   264  						Tracker:  "tracker",
   265  					},
   266  				},
   267  			},
   268  		},
   269  	}
   270  	for _, test := range testCases {
   271  		reader := StubInfoReader{test.bidderInfos}
   272  		bidderInfos, err := processBidderInfos(reader, mockNormalizeBidderName)
   273  		if test.expectError != "" {
   274  			assert.ErrorContains(t, err, test.expectError, "")
   275  		} else {
   276  			assert.Equal(t, test.expectedBidderInfos, bidderInfos, "incorrect bidder infos for test case: %s", test.description)
   277  		}
   278  
   279  	}
   280  
   281  }
   282  
   283  func TestProcessAliasBidderInfo(t *testing.T) {
   284  	parentBidderInfo := BidderInfo{
   285  		AppSecret: "app-secret",
   286  		Capabilities: &CapabilitiesInfo{
   287  			App: &PlatformInfo{
   288  				MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner, openrtb_ext.BidTypeVideo, openrtb_ext.BidTypeNative},
   289  			},
   290  			Site: &PlatformInfo{
   291  				MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner, openrtb_ext.BidTypeVideo, openrtb_ext.BidTypeNative},
   292  			},
   293  		},
   294  		Debug: &DebugInfo{
   295  			Allow: true,
   296  		},
   297  		Disabled:            false,
   298  		Endpoint:            "https://endpoint.com",
   299  		EndpointCompression: "GZIP",
   300  		Experiment: BidderInfoExperiment{
   301  			AdsCert: BidderAdsCert{
   302  				Enabled: true,
   303  			},
   304  		},
   305  		ExtraAdapterInfo: "extra-info",
   306  		GVLVendorID:      42,
   307  		Maintainer: &MaintainerInfo{
   308  			Email: "some-email@domain.com",
   309  		},
   310  		ModifyingVastXmlAllowed: true,
   311  		OpenRTB: &OpenRTBInfo{
   312  			GPPSupported: true,
   313  			Version:      "2.6",
   314  		},
   315  		PlatformID: "123",
   316  		Syncer: &Syncer{
   317  			Key: "foo",
   318  			IFrame: &SyncerEndpoint{
   319  				URL:         "https://foo.com/sync?mode=iframe&r={{.RedirectURL}}",
   320  				RedirectURL: "https://redirect/setuid/iframe",
   321  				ExternalURL: "https://iframe.host",
   322  				UserMacro:   "UID",
   323  			},
   324  		},
   325  		UserSyncURL: "user-url",
   326  		XAPI: AdapterXAPI{
   327  			Username: "uname",
   328  			Password: "pwd",
   329  			Tracker:  "tracker",
   330  		},
   331  	}
   332  	aliasBidderInfo := BidderInfo{
   333  		AppSecret: "alias-app-secret",
   334  		Capabilities: &CapabilitiesInfo{
   335  			App: &PlatformInfo{
   336  				MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner},
   337  			},
   338  			Site: &PlatformInfo{
   339  				MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner},
   340  			},
   341  		},
   342  		Debug: &DebugInfo{
   343  			Allow: false,
   344  		},
   345  		Disabled:            true,
   346  		Endpoint:            "https://alias-endpoint.com",
   347  		EndpointCompression: "DEFAULT",
   348  		Experiment: BidderInfoExperiment{
   349  			AdsCert: BidderAdsCert{
   350  				Enabled: false,
   351  			},
   352  		},
   353  		ExtraAdapterInfo: "alias-extra-info",
   354  		GVLVendorID:      43,
   355  		Maintainer: &MaintainerInfo{
   356  			Email: "alias-email@domain.com",
   357  		},
   358  		ModifyingVastXmlAllowed: false,
   359  		OpenRTB: &OpenRTBInfo{
   360  			GPPSupported: false,
   361  			Version:      "2.5",
   362  		},
   363  		PlatformID: "456",
   364  		Syncer: &Syncer{
   365  			Key: "alias",
   366  			IFrame: &SyncerEndpoint{
   367  				URL:         "https://alias.com/sync?mode=iframe&r={{.RedirectURL}}",
   368  				RedirectURL: "https://alias-redirect/setuid/iframe",
   369  				ExternalURL: "https://alias-iframe.host",
   370  				UserMacro:   "alias-UID",
   371  			},
   372  		},
   373  		UserSyncURL: "alias-user-url",
   374  		XAPI: AdapterXAPI{
   375  			Username: "alias-uname",
   376  			Password: "alias-pwd",
   377  			Tracker:  "alias-tracker",
   378  		},
   379  	}
   380  	bidderB := parentBidderInfo
   381  	bidderB.AliasOf = "bidderA"
   382  	testCases := []struct {
   383  		description         string
   384  		aliasInfos          map[string]aliasNillableFields
   385  		bidderInfos         BidderInfos
   386  		expectedBidderInfos BidderInfos
   387  		expectedErr         error
   388  	}{
   389  		{
   390  			description: "inherit all parent info in alias bidder",
   391  			aliasInfos: map[string]aliasNillableFields{
   392  				"bidderB": {
   393  					Disabled:                nil,
   394  					ModifyingVastXmlAllowed: nil,
   395  					Experiment:              nil,
   396  					XAPI:                    nil,
   397  				},
   398  			},
   399  			bidderInfos: BidderInfos{
   400  				"bidderA": parentBidderInfo,
   401  				"bidderB": BidderInfo{
   402  					AliasOf: "bidderA",
   403  					// all other fields should be inherited from parent bidder
   404  				},
   405  			},
   406  			expectedErr:         nil,
   407  			expectedBidderInfos: BidderInfos{"bidderA": parentBidderInfo, "bidderB": bidderB},
   408  		},
   409  		{
   410  			description: "all bidder info specified for alias, do not inherit from parent bidder",
   411  			aliasInfos: map[string]aliasNillableFields{
   412  				"bidderB": {
   413  					Disabled:                &aliasBidderInfo.Disabled,
   414  					ModifyingVastXmlAllowed: &aliasBidderInfo.ModifyingVastXmlAllowed,
   415  					Experiment:              &aliasBidderInfo.Experiment,
   416  					XAPI:                    &aliasBidderInfo.XAPI,
   417  				},
   418  			},
   419  			bidderInfos: BidderInfos{
   420  				"bidderA": parentBidderInfo,
   421  				"bidderB": aliasBidderInfo,
   422  			},
   423  			expectedErr:         nil,
   424  			expectedBidderInfos: BidderInfos{"bidderA": parentBidderInfo, "bidderB": aliasBidderInfo},
   425  		},
   426  		{
   427  			description: "invalid alias",
   428  			aliasInfos: map[string]aliasNillableFields{
   429  				"bidderB": {},
   430  			},
   431  			bidderInfos: BidderInfos{
   432  				"bidderB": BidderInfo{
   433  					AliasOf: "bidderA",
   434  				},
   435  			},
   436  			expectedErr: errors.New("bidder: bidderA not found for an alias: bidderB"),
   437  		},
   438  		{
   439  			description: "bidder info not found for an alias",
   440  			aliasInfos: map[string]aliasNillableFields{
   441  				"bidderB": {},
   442  			},
   443  			expectedErr: errors.New("bidder info not found for an alias: bidderB"),
   444  		},
   445  	}
   446  
   447  	for _, test := range testCases {
   448  		bidderInfos, err := processBidderAliases(test.aliasInfos, test.bidderInfos)
   449  		if test.expectedErr != nil {
   450  			assert.Equal(t, test.expectedErr, err)
   451  		} else {
   452  			assert.Equal(t, test.expectedBidderInfos, bidderInfos)
   453  		}
   454  	}
   455  }
   456  
   457  type StubInfoReader struct {
   458  	mockBidderInfos map[string][]byte
   459  }
   460  
   461  func (r StubInfoReader) Read() (map[string][]byte, error) {
   462  	return r.mockBidderInfos, nil
   463  }
   464  
   465  var testBidderNames = map[string]openrtb_ext.BidderName{
   466  	"biddera": openrtb_ext.BidderName("bidderA"),
   467  	"bidderb": openrtb_ext.BidderName("bidderB"),
   468  	"bidder1": openrtb_ext.BidderName("bidder1"),
   469  	"bidder2": openrtb_ext.BidderName("bidder2"),
   470  	"a":       openrtb_ext.BidderName("a"),
   471  }
   472  
   473  func mockNormalizeBidderName(name string) (openrtb_ext.BidderName, bool) {
   474  	nameLower := strings.ToLower(name)
   475  	bidderName, exists := testBidderNames[nameLower]
   476  	return bidderName, exists
   477  }
   478  
   479  func TestToGVLVendorIDMap(t *testing.T) {
   480  	givenBidderInfos := BidderInfos{
   481  		"bidderA": BidderInfo{Disabled: false, GVLVendorID: 0},
   482  		"bidderB": BidderInfo{Disabled: false, GVLVendorID: 100},
   483  		"bidderC": BidderInfo{Disabled: true, GVLVendorID: 0},
   484  		"bidderD": BidderInfo{Disabled: true, GVLVendorID: 200},
   485  	}
   486  
   487  	expectedGVLVendorIDMap := map[openrtb_ext.BidderName]uint16{
   488  		"bidderB": 100,
   489  	}
   490  
   491  	result := givenBidderInfos.ToGVLVendorIDMap()
   492  	assert.Equal(t, expectedGVLVendorIDMap, result)
   493  }
   494  
   495  const bidderInfoRelativePath = "../static/bidder-info"
   496  
   497  // TestBidderInfoFiles ensures each bidder has a valid static/bidder-info/bidder.yaml file. Validation is performed directly
   498  // against the file system with separate yaml unmarshalling from the LoadBidderInfo func.
   499  func TestBidderInfoFiles(t *testing.T) {
   500  	_, err := LoadBidderInfoFromDisk(bidderInfoRelativePath)
   501  	if err != nil {
   502  		assert.Fail(t, err.Error(), "Errors in bidder info files")
   503  	}
   504  }
   505  
   506  func TestBidderInfoValidationPositive(t *testing.T) {
   507  	bidderInfos := BidderInfos{
   508  		"bidderA": BidderInfo{
   509  			Endpoint:   "http://bidderA.com/openrtb2",
   510  			PlatformID: "A",
   511  			Maintainer: &MaintainerInfo{
   512  				Email: "maintainer@bidderA.com",
   513  			},
   514  			GVLVendorID: 1,
   515  			Capabilities: &CapabilitiesInfo{
   516  				App: &PlatformInfo{
   517  					MediaTypes: []openrtb_ext.BidType{
   518  						openrtb_ext.BidTypeVideo,
   519  						openrtb_ext.BidTypeNative,
   520  						openrtb_ext.BidTypeBanner,
   521  					},
   522  				},
   523  			},
   524  			Syncer: &Syncer{
   525  				Key: "bidderAkey",
   526  				Redirect: &SyncerEndpoint{
   527  					URL:       "http://bidderA.com/usersync",
   528  					UserMacro: "UID",
   529  				},
   530  			},
   531  		},
   532  		"bidderB": BidderInfo{
   533  			Endpoint:   "http://bidderB.com/openrtb2",
   534  			PlatformID: "B",
   535  			Maintainer: &MaintainerInfo{
   536  				Email: "maintainer@bidderA.com",
   537  			},
   538  			GVLVendorID: 2,
   539  			Capabilities: &CapabilitiesInfo{
   540  				Site: &PlatformInfo{
   541  					MediaTypes: []openrtb_ext.BidType{
   542  						openrtb_ext.BidTypeVideo,
   543  						openrtb_ext.BidTypeNative,
   544  						openrtb_ext.BidTypeBanner,
   545  					},
   546  				},
   547  			},
   548  			Syncer: &Syncer{
   549  				Key: "bidderBkey",
   550  				Redirect: &SyncerEndpoint{
   551  					URL:       "http://bidderB.com/usersync",
   552  					UserMacro: "UID",
   553  				},
   554  			},
   555  		},
   556  		"bidderC": BidderInfo{
   557  			Endpoint: "http://bidderB.com/openrtb2",
   558  			Maintainer: &MaintainerInfo{
   559  				Email: "maintainer@bidderA.com",
   560  			},
   561  			Capabilities: &CapabilitiesInfo{
   562  				Site: &PlatformInfo{
   563  					MediaTypes: []openrtb_ext.BidType{
   564  						openrtb_ext.BidTypeVideo,
   565  						openrtb_ext.BidTypeNative,
   566  						openrtb_ext.BidTypeBanner,
   567  					},
   568  				},
   569  			},
   570  			AliasOf: "bidderB",
   571  		},
   572  	}
   573  	errs := bidderInfos.validate(make([]error, 0))
   574  	assert.Len(t, errs, 0, "All bidder infos should be correct")
   575  }
   576  
   577  func TestValidateAliases(t *testing.T) {
   578  	testCase := struct {
   579  		description  string
   580  		bidderInfos  BidderInfos
   581  		expectErrors []error
   582  	}{
   583  		description: "invalid aliases",
   584  		bidderInfos: BidderInfos{
   585  			"bidderA": BidderInfo{
   586  				Endpoint: "http://bidderA.com/openrtb2",
   587  				Maintainer: &MaintainerInfo{
   588  					Email: "maintainer@bidderA.com",
   589  				},
   590  				Capabilities: &CapabilitiesInfo{
   591  					Site: &PlatformInfo{
   592  						MediaTypes: []openrtb_ext.BidType{
   593  							openrtb_ext.BidTypeVideo,
   594  						},
   595  					},
   596  				},
   597  				AliasOf: "bidderB",
   598  			},
   599  			"bidderB": BidderInfo{
   600  				Endpoint: "http://bidderA.com/openrtb2",
   601  				Maintainer: &MaintainerInfo{
   602  					Email: "maintainer@bidderA.com",
   603  				},
   604  				Capabilities: &CapabilitiesInfo{
   605  					Site: &PlatformInfo{
   606  						MediaTypes: []openrtb_ext.BidType{
   607  							openrtb_ext.BidTypeVideo,
   608  						},
   609  					},
   610  				},
   611  				AliasOf: "bidderC",
   612  			},
   613  		},
   614  		expectErrors: []error{
   615  			errors.New("bidder: bidderB cannot be an alias of an alias: bidderA"),
   616  			errors.New("bidder: bidderC not found for an alias: bidderB"),
   617  		},
   618  	}
   619  
   620  	var errs []error
   621  	for bidderName, bidderInfo := range testCase.bidderInfos {
   622  		errs = append(errs, validateAliases(bidderInfo, testCase.bidderInfos, bidderName))
   623  	}
   624  
   625  	assert.ElementsMatch(t, errs, testCase.expectErrors)
   626  }
   627  
   628  func TestBidderInfoValidationNegative(t *testing.T) {
   629  	testCases := []struct {
   630  		description  string
   631  		bidderInfos  BidderInfos
   632  		expectErrors []error
   633  	}{
   634  		{
   635  			"One bidder incorrect url",
   636  			BidderInfos{
   637  				"bidderA": BidderInfo{
   638  					Endpoint: "incorrect",
   639  					Maintainer: &MaintainerInfo{
   640  						Email: "maintainer@bidderA.com",
   641  					},
   642  					Capabilities: &CapabilitiesInfo{
   643  						App: &PlatformInfo{
   644  							MediaTypes: []openrtb_ext.BidType{
   645  								openrtb_ext.BidTypeVideo,
   646  							},
   647  						},
   648  					},
   649  				},
   650  			},
   651  			[]error{
   652  				errors.New("The endpoint: incorrect for bidderA is not a valid URL"),
   653  			},
   654  		},
   655  		{
   656  			"One bidder empty url",
   657  			BidderInfos{
   658  				"bidderA": BidderInfo{
   659  					Endpoint: "",
   660  					Maintainer: &MaintainerInfo{
   661  						Email: "maintainer@bidderA.com",
   662  					},
   663  					Capabilities: &CapabilitiesInfo{
   664  						App: &PlatformInfo{
   665  							MediaTypes: []openrtb_ext.BidType{
   666  								openrtb_ext.BidTypeVideo,
   667  							},
   668  						},
   669  					},
   670  				},
   671  			},
   672  			[]error{
   673  				errors.New("There's no default endpoint available for bidderA. Calls to this bidder/exchange will fail. Please set adapters.bidderA.endpoint in your app config"),
   674  			},
   675  		},
   676  		{
   677  			"One bidder incorrect url template",
   678  			BidderInfos{
   679  				"bidderA": BidderInfo{
   680  					Endpoint: "http://bidderA.com/openrtb2/getuid?{{.incorrect}}",
   681  					Maintainer: &MaintainerInfo{
   682  						Email: "maintainer@bidderA.com",
   683  					},
   684  					Capabilities: &CapabilitiesInfo{
   685  						App: &PlatformInfo{
   686  							MediaTypes: []openrtb_ext.BidType{
   687  								openrtb_ext.BidTypeVideo,
   688  							},
   689  						},
   690  					},
   691  				},
   692  			},
   693  			[]error{
   694  				errors.New("Unable to resolve endpoint: http://bidderA.com/openrtb2/getuid?{{.incorrect}} for adapter: bidderA. template: endpointTemplate:1:37: executing \"endpointTemplate\" at <.incorrect>: can't evaluate field incorrect in type macros.EndpointTemplateParams"),
   695  			},
   696  		},
   697  		{
   698  			"One bidder incorrect url template parameters",
   699  			BidderInfos{
   700  				"bidderA": BidderInfo{
   701  					Endpoint: "http://bidderA.com/openrtb2/getuid?r=[{{.]RedirectURL}}",
   702  					Maintainer: &MaintainerInfo{
   703  						Email: "maintainer@bidderA.com",
   704  					},
   705  					Capabilities: &CapabilitiesInfo{
   706  						App: &PlatformInfo{
   707  							MediaTypes: []openrtb_ext.BidType{
   708  								openrtb_ext.BidTypeVideo,
   709  							},
   710  						},
   711  					},
   712  				},
   713  			},
   714  			[]error{
   715  				errors.New("Invalid endpoint template: http://bidderA.com/openrtb2/getuid?r=[{{.]RedirectURL}} for adapter: bidderA. template: endpointTemplate:1: bad character U+005D ']'"),
   716  			},
   717  		},
   718  		{
   719  			"One bidder no maintainer",
   720  			BidderInfos{
   721  				"bidderA": BidderInfo{
   722  					Endpoint: "http://bidderA.com/openrtb2",
   723  					Capabilities: &CapabilitiesInfo{
   724  						App: &PlatformInfo{
   725  							MediaTypes: []openrtb_ext.BidType{
   726  								openrtb_ext.BidTypeVideo,
   727  							},
   728  						},
   729  					},
   730  				},
   731  			},
   732  			[]error{
   733  				errors.New("missing required field: maintainer.email for adapter: bidderA"),
   734  			},
   735  		},
   736  		{
   737  			"One bidder missing maintainer email",
   738  			BidderInfos{
   739  				"bidderA": BidderInfo{
   740  					Endpoint: "http://bidderA.com/openrtb2",
   741  					Maintainer: &MaintainerInfo{
   742  						Email: "",
   743  					},
   744  					Capabilities: &CapabilitiesInfo{
   745  						App: &PlatformInfo{
   746  							MediaTypes: []openrtb_ext.BidType{
   747  								openrtb_ext.BidTypeVideo,
   748  							},
   749  						},
   750  					},
   751  				},
   752  			},
   753  			[]error{
   754  				errors.New("missing required field: maintainer.email for adapter: bidderA"),
   755  			},
   756  		},
   757  		{
   758  			"One bidder missing capabilities",
   759  			BidderInfos{
   760  				"bidderA": BidderInfo{
   761  					Endpoint: "http://bidderA.com/openrtb2",
   762  					Maintainer: &MaintainerInfo{
   763  						Email: "maintainer@bidderA.com",
   764  					},
   765  				},
   766  			},
   767  			[]error{
   768  				errors.New("missing required field: capabilities for adapter: bidderA"),
   769  			},
   770  		},
   771  		{
   772  			"One bidder missing capabilities site and app",
   773  			BidderInfos{
   774  				"bidderA": BidderInfo{
   775  					Endpoint: "http://bidderA.com/openrtb2",
   776  					Maintainer: &MaintainerInfo{
   777  						Email: "maintainer@bidderA.com",
   778  					},
   779  					Capabilities: &CapabilitiesInfo{},
   780  				},
   781  			},
   782  			[]error{
   783  				errors.New("at least one of capabilities.site or capabilities.app must exist for adapter: bidderA"),
   784  			},
   785  		},
   786  		{
   787  			"One bidder incorrect capabilities for app",
   788  			BidderInfos{
   789  				"bidderA": BidderInfo{
   790  					Endpoint: "http://bidderA.com/openrtb2",
   791  					Maintainer: &MaintainerInfo{
   792  						Email: "maintainer@bidderA.com",
   793  					},
   794  					Capabilities: &CapabilitiesInfo{
   795  						App: &PlatformInfo{
   796  							MediaTypes: []openrtb_ext.BidType{
   797  								"incorrect",
   798  							},
   799  						},
   800  					},
   801  				},
   802  			},
   803  			[]error{
   804  				errors.New("capabilities.app failed validation: unrecognized media type at index 0: incorrect for adapter: bidderA"),
   805  			},
   806  		},
   807  		{
   808  			"One bidder nil capabilities",
   809  			BidderInfos{
   810  				"bidderA": BidderInfo{
   811  					Endpoint: "http://bidderA.com/openrtb2",
   812  					Maintainer: &MaintainerInfo{
   813  						Email: "maintainer@bidderA.com",
   814  					},
   815  					Capabilities: nil,
   816  				},
   817  			},
   818  			[]error{
   819  				errors.New("missing required field: capabilities for adapter: bidderA"),
   820  			},
   821  		},
   822  		{
   823  			"One bidder invalid syncer",
   824  			BidderInfos{
   825  				"bidderA": BidderInfo{
   826  					Endpoint: "http://bidderA.com/openrtb2",
   827  					Maintainer: &MaintainerInfo{
   828  						Email: "maintainer@bidderA.com",
   829  					},
   830  					Capabilities: &CapabilitiesInfo{
   831  						Site: &PlatformInfo{
   832  							MediaTypes: []openrtb_ext.BidType{
   833  								openrtb_ext.BidTypeVideo,
   834  							},
   835  						},
   836  					},
   837  					Syncer: &Syncer{
   838  						Supports: []string{"incorrect"},
   839  					},
   840  				},
   841  			},
   842  			[]error{
   843  				errors.New("syncer could not be created, invalid supported endpoint: incorrect"),
   844  			},
   845  		},
   846  		{
   847  			"Two bidders, one with incorrect url",
   848  			BidderInfos{
   849  				"bidderA": BidderInfo{
   850  					Endpoint: "incorrect",
   851  					Maintainer: &MaintainerInfo{
   852  						Email: "maintainer@bidderA.com",
   853  					},
   854  					Capabilities: &CapabilitiesInfo{
   855  						App: &PlatformInfo{
   856  							MediaTypes: []openrtb_ext.BidType{
   857  								openrtb_ext.BidTypeVideo,
   858  							},
   859  						},
   860  					},
   861  				},
   862  				"bidderB": BidderInfo{
   863  					Endpoint: "http://bidderB.com/openrtb2",
   864  					Maintainer: &MaintainerInfo{
   865  						Email: "maintainer@bidderB.com",
   866  					},
   867  					Capabilities: &CapabilitiesInfo{
   868  						App: &PlatformInfo{
   869  							MediaTypes: []openrtb_ext.BidType{
   870  								openrtb_ext.BidTypeVideo,
   871  							},
   872  						},
   873  					},
   874  				},
   875  			},
   876  			[]error{
   877  				errors.New("The endpoint: incorrect for bidderA is not a valid URL"),
   878  			},
   879  		},
   880  		{
   881  			"Two bidders, both with incorrect url",
   882  			BidderInfos{
   883  				"bidderA": BidderInfo{
   884  					Endpoint: "incorrect",
   885  					Maintainer: &MaintainerInfo{
   886  						Email: "maintainer@bidderA.com",
   887  					},
   888  					Capabilities: &CapabilitiesInfo{
   889  						App: &PlatformInfo{
   890  							MediaTypes: []openrtb_ext.BidType{
   891  								openrtb_ext.BidTypeVideo,
   892  							},
   893  						},
   894  					},
   895  				},
   896  				"bidderB": BidderInfo{
   897  					Endpoint: "incorrect",
   898  					Maintainer: &MaintainerInfo{
   899  						Email: "maintainer@bidderB.com",
   900  					},
   901  					Capabilities: &CapabilitiesInfo{
   902  						App: &PlatformInfo{
   903  							MediaTypes: []openrtb_ext.BidType{
   904  								openrtb_ext.BidTypeVideo,
   905  							},
   906  						},
   907  					},
   908  				},
   909  			},
   910  			[]error{
   911  				errors.New("The endpoint: incorrect for bidderA is not a valid URL"),
   912  				errors.New("The endpoint: incorrect for bidderB is not a valid URL"),
   913  			},
   914  		},
   915  		{
   916  			"Invalid alias Site capabilities",
   917  			BidderInfos{
   918  				"bidderA": BidderInfo{
   919  					Endpoint: "http://bidderA.com/openrtb2",
   920  					Maintainer: &MaintainerInfo{
   921  						Email: "maintainer@bidderA.com",
   922  					},
   923  					Capabilities: &CapabilitiesInfo{
   924  						Site: &PlatformInfo{
   925  							MediaTypes: []openrtb_ext.BidType{
   926  								openrtb_ext.BidTypeVideo,
   927  							},
   928  						},
   929  					},
   930  				},
   931  				"bidderB": BidderInfo{
   932  					Endpoint: "http://bidderA.com/openrtb2",
   933  					Maintainer: &MaintainerInfo{
   934  						Email: "maintainer@bidderA.com",
   935  					},
   936  					Capabilities: &CapabilitiesInfo{
   937  						App: &PlatformInfo{
   938  							MediaTypes: []openrtb_ext.BidType{
   939  								openrtb_ext.BidTypeVideo,
   940  							},
   941  						},
   942  					},
   943  					AliasOf: "bidderA",
   944  				},
   945  			},
   946  			[]error{
   947  				errors.New("capabilities for alias: bidderB should be a subset of capabilities for parent bidder: bidderA"),
   948  			},
   949  		},
   950  		{
   951  			"Invalid alias App capabilities",
   952  			BidderInfos{
   953  				"bidderA": BidderInfo{
   954  					Endpoint: "http://bidderA.com/openrtb2",
   955  					Maintainer: &MaintainerInfo{
   956  						Email: "maintainer@bidderA.com",
   957  					},
   958  					Capabilities: &CapabilitiesInfo{
   959  						App: &PlatformInfo{
   960  							MediaTypes: []openrtb_ext.BidType{
   961  								openrtb_ext.BidTypeVideo,
   962  							},
   963  						},
   964  					},
   965  				},
   966  				"bidderB": BidderInfo{
   967  					Endpoint: "http://bidderA.com/openrtb2",
   968  					Maintainer: &MaintainerInfo{
   969  						Email: "maintainer@bidderA.com",
   970  					},
   971  					Capabilities: &CapabilitiesInfo{
   972  						Site: &PlatformInfo{
   973  							MediaTypes: []openrtb_ext.BidType{
   974  								openrtb_ext.BidTypeVideo,
   975  							},
   976  						},
   977  					},
   978  					AliasOf: "bidderA",
   979  				},
   980  			},
   981  			[]error{
   982  				errors.New("capabilities for alias: bidderB should be a subset of capabilities for parent bidder: bidderA"),
   983  			},
   984  		},
   985  		{
   986  			"Invalid alias capabilities",
   987  			BidderInfos{
   988  				"bidderA": BidderInfo{
   989  					Endpoint: "http://bidderA.com/openrtb2",
   990  					Maintainer: &MaintainerInfo{
   991  						Email: "maintainer@bidderA.com",
   992  					},
   993  					Capabilities: &CapabilitiesInfo{},
   994  				},
   995  				"bidderB": BidderInfo{
   996  					Endpoint: "http://bidderA.com/openrtb2",
   997  					Maintainer: &MaintainerInfo{
   998  						Email: "maintainer@bidderA.com",
   999  					},
  1000  					Capabilities: &CapabilitiesInfo{
  1001  						App: &PlatformInfo{
  1002  							MediaTypes: []openrtb_ext.BidType{
  1003  								openrtb_ext.BidTypeVideo,
  1004  							},
  1005  						},
  1006  					},
  1007  					AliasOf: "bidderA",
  1008  				},
  1009  			},
  1010  			[]error{
  1011  				errors.New("at least one of capabilities.site or capabilities.app must exist for adapter: bidderA"),
  1012  				errors.New("capabilities for alias: bidderB should be a subset of capabilities for parent bidder: bidderA"),
  1013  			},
  1014  		},
  1015  		{
  1016  			"Invalid alias MediaTypes for site",
  1017  			BidderInfos{
  1018  				"bidderA": BidderInfo{
  1019  					Endpoint: "http://bidderA.com/openrtb2",
  1020  					Maintainer: &MaintainerInfo{
  1021  						Email: "maintainer@bidderA.com",
  1022  					},
  1023  					Capabilities: &CapabilitiesInfo{
  1024  						Site: &PlatformInfo{
  1025  							MediaTypes: []openrtb_ext.BidType{
  1026  								openrtb_ext.BidTypeVideo,
  1027  							},
  1028  						},
  1029  					},
  1030  				},
  1031  				"bidderB": BidderInfo{
  1032  					Endpoint: "http://bidderA.com/openrtb2",
  1033  					Maintainer: &MaintainerInfo{
  1034  						Email: "maintainer@bidderA.com",
  1035  					},
  1036  					Capabilities: &CapabilitiesInfo{
  1037  						Site: &PlatformInfo{
  1038  							MediaTypes: []openrtb_ext.BidType{
  1039  								openrtb_ext.BidTypeBanner,
  1040  								openrtb_ext.BidTypeNative,
  1041  							},
  1042  						},
  1043  					},
  1044  					AliasOf: "bidderA",
  1045  				},
  1046  			},
  1047  			[]error{
  1048  				errors.New("mediaTypes for alias: bidderB should be a subset of MediaTypes for parent bidder: bidderA"),
  1049  			},
  1050  		},
  1051  		{
  1052  			"Invalid alias MediaTypes for app",
  1053  			BidderInfos{
  1054  				"bidderA": BidderInfo{
  1055  					Endpoint: "http://bidderA.com/openrtb2",
  1056  					Maintainer: &MaintainerInfo{
  1057  						Email: "maintainer@bidderA.com",
  1058  					},
  1059  					Capabilities: &CapabilitiesInfo{
  1060  						App: &PlatformInfo{
  1061  							MediaTypes: []openrtb_ext.BidType{
  1062  								openrtb_ext.BidTypeVideo,
  1063  							},
  1064  						},
  1065  					},
  1066  				},
  1067  				"bidderB": BidderInfo{
  1068  					Endpoint: "http://bidderA.com/openrtb2",
  1069  					Maintainer: &MaintainerInfo{
  1070  						Email: "maintainer@bidderA.com",
  1071  					},
  1072  					Capabilities: &CapabilitiesInfo{
  1073  						App: &PlatformInfo{
  1074  							MediaTypes: []openrtb_ext.BidType{
  1075  								openrtb_ext.BidTypeBanner,
  1076  								openrtb_ext.BidTypeNative,
  1077  							},
  1078  						},
  1079  					},
  1080  					AliasOf: "bidderA",
  1081  				},
  1082  			},
  1083  			[]error{
  1084  				errors.New("mediaTypes for alias: bidderB should be a subset of MediaTypes for parent bidder: bidderA"),
  1085  			},
  1086  		},
  1087  		{
  1088  			"Invalid parent bidder capabilities",
  1089  			BidderInfos{
  1090  				"bidderA": BidderInfo{
  1091  					Endpoint: "http://bidderA.com/openrtb2",
  1092  					Maintainer: &MaintainerInfo{
  1093  						Email: "maintainer@bidderA.com",
  1094  					},
  1095  				},
  1096  				"bidderB": BidderInfo{
  1097  					Endpoint: "http://bidderA.com/openrtb2",
  1098  					Maintainer: &MaintainerInfo{
  1099  						Email: "maintainer@bidderA.com",
  1100  					},
  1101  					Capabilities: &CapabilitiesInfo{
  1102  						App: &PlatformInfo{
  1103  							MediaTypes: []openrtb_ext.BidType{
  1104  								openrtb_ext.BidTypeBanner,
  1105  							},
  1106  						},
  1107  					},
  1108  					AliasOf: "bidderA",
  1109  				},
  1110  			},
  1111  			[]error{
  1112  				errors.New("missing required field: capabilities for adapter: bidderA"),
  1113  				errors.New("capabilities for alias: bidderB should be a subset of capabilities for parent bidder: bidderA"),
  1114  			},
  1115  		},
  1116  		{
  1117  			"Invalid site alias capabilities with both site and app",
  1118  			BidderInfos{
  1119  				"bidderA": BidderInfo{
  1120  					Endpoint: "http://bidderA.com/openrtb2",
  1121  					Maintainer: &MaintainerInfo{
  1122  						Email: "maintainer@bidderA.com",
  1123  					},
  1124  					Capabilities: &CapabilitiesInfo{
  1125  						App: &PlatformInfo{
  1126  							MediaTypes: []openrtb_ext.BidType{
  1127  								openrtb_ext.BidTypeBanner,
  1128  								openrtb_ext.BidTypeNative,
  1129  							},
  1130  						},
  1131  						Site: &PlatformInfo{
  1132  							MediaTypes: []openrtb_ext.BidType{
  1133  								openrtb_ext.BidTypeNative,
  1134  							},
  1135  						},
  1136  					},
  1137  				},
  1138  				"bidderB": BidderInfo{
  1139  					Endpoint: "http://bidderA.com/openrtb2",
  1140  					Maintainer: &MaintainerInfo{
  1141  						Email: "maintainer@bidderA.com",
  1142  					},
  1143  					Capabilities: &CapabilitiesInfo{
  1144  						App: &PlatformInfo{
  1145  							MediaTypes: []openrtb_ext.BidType{
  1146  								openrtb_ext.BidTypeBanner,
  1147  								openrtb_ext.BidTypeNative,
  1148  							},
  1149  						},
  1150  						Site: &PlatformInfo{
  1151  							MediaTypes: []openrtb_ext.BidType{
  1152  								openrtb_ext.BidTypeBanner,
  1153  								openrtb_ext.BidTypeNative,
  1154  							},
  1155  						},
  1156  					},
  1157  					AliasOf: "bidderA",
  1158  				},
  1159  			},
  1160  			[]error{
  1161  				errors.New("mediaTypes for alias: bidderB should be a subset of MediaTypes for parent bidder: bidderA"),
  1162  			},
  1163  		},
  1164  		{
  1165  			"Invalid app alias capabilities with both site and app",
  1166  			BidderInfos{
  1167  				"bidderA": BidderInfo{
  1168  					Endpoint: "http://bidderA.com/openrtb2",
  1169  					Maintainer: &MaintainerInfo{
  1170  						Email: "maintainer@bidderA.com",
  1171  					},
  1172  					Capabilities: &CapabilitiesInfo{
  1173  						App: &PlatformInfo{
  1174  							MediaTypes: []openrtb_ext.BidType{
  1175  								openrtb_ext.BidTypeBanner,
  1176  								openrtb_ext.BidTypeNative,
  1177  							},
  1178  						},
  1179  						Site: &PlatformInfo{
  1180  							MediaTypes: []openrtb_ext.BidType{
  1181  								openrtb_ext.BidTypeNative,
  1182  							},
  1183  						},
  1184  					},
  1185  				},
  1186  				"bidderB": BidderInfo{
  1187  					Endpoint: "http://bidderA.com/openrtb2",
  1188  					Maintainer: &MaintainerInfo{
  1189  						Email: "maintainer@bidderA.com",
  1190  					},
  1191  					Capabilities: &CapabilitiesInfo{
  1192  						App: &PlatformInfo{
  1193  							MediaTypes: []openrtb_ext.BidType{
  1194  								openrtb_ext.BidTypeBanner,
  1195  								openrtb_ext.BidTypeNative,
  1196  							},
  1197  						},
  1198  						Site: &PlatformInfo{
  1199  							MediaTypes: []openrtb_ext.BidType{
  1200  								openrtb_ext.BidTypeBanner,
  1201  								openrtb_ext.BidTypeNative,
  1202  							},
  1203  						},
  1204  					},
  1205  					AliasOf: "bidderA",
  1206  				},
  1207  			},
  1208  			[]error{
  1209  				errors.New("mediaTypes for alias: bidderB should be a subset of MediaTypes for parent bidder: bidderA"),
  1210  			},
  1211  		},
  1212  		{
  1213  			"Invalid parent bidder for alias",
  1214  			BidderInfos{
  1215  				"bidderB": BidderInfo{
  1216  					Endpoint: "http://bidderA.com/openrtb2",
  1217  					Maintainer: &MaintainerInfo{
  1218  						Email: "maintainer@bidderA.com",
  1219  					},
  1220  					Capabilities: &CapabilitiesInfo{
  1221  						App: &PlatformInfo{
  1222  							MediaTypes: []openrtb_ext.BidType{
  1223  								openrtb_ext.BidTypeBanner,
  1224  								openrtb_ext.BidTypeNative,
  1225  							},
  1226  						},
  1227  						Site: &PlatformInfo{
  1228  							MediaTypes: []openrtb_ext.BidType{
  1229  								openrtb_ext.BidTypeBanner,
  1230  								openrtb_ext.BidTypeNative,
  1231  							},
  1232  						},
  1233  					},
  1234  					AliasOf: "bidderC",
  1235  				},
  1236  			},
  1237  			[]error{
  1238  				errors.New("parent bidder: bidderC not found for an alias: bidderB"),
  1239  			},
  1240  		},
  1241  	}
  1242  
  1243  	for _, test := range testCases {
  1244  		errs := test.bidderInfos.validate(make([]error, 0))
  1245  		assert.ElementsMatch(t, errs, test.expectErrors, "incorrect errors returned for test: %s", test.description)
  1246  	}
  1247  }
  1248  
  1249  func TestSyncerOverride(t *testing.T) {
  1250  	var (
  1251  		trueValue  = true
  1252  		falseValue = false
  1253  	)
  1254  
  1255  	testCases := []struct {
  1256  		description   string
  1257  		givenOriginal *Syncer
  1258  		givenOverride *Syncer
  1259  		expected      *Syncer
  1260  	}{
  1261  		{
  1262  			description:   "Nil",
  1263  			givenOriginal: nil,
  1264  			givenOverride: nil,
  1265  			expected:      nil,
  1266  		},
  1267  		{
  1268  			description:   "Original Nil",
  1269  			givenOriginal: nil,
  1270  			givenOverride: &Syncer{Key: "anyKey"},
  1271  			expected:      &Syncer{Key: "anyKey"},
  1272  		},
  1273  		{
  1274  			description:   "Original Empty",
  1275  			givenOriginal: &Syncer{},
  1276  			givenOverride: &Syncer{Key: "anyKey"},
  1277  			expected:      &Syncer{Key: "anyKey"},
  1278  		},
  1279  		{
  1280  			description:   "Override Nil",
  1281  			givenOriginal: &Syncer{Key: "anyKey"},
  1282  			givenOverride: nil,
  1283  			expected:      &Syncer{Key: "anyKey"},
  1284  		},
  1285  		{
  1286  			description:   "Override Empty",
  1287  			givenOriginal: &Syncer{Key: "anyKey"},
  1288  			givenOverride: &Syncer{},
  1289  			expected:      &Syncer{Key: "anyKey"},
  1290  		},
  1291  		{
  1292  			description:   "Override Key",
  1293  			givenOriginal: &Syncer{Key: "original"},
  1294  			givenOverride: &Syncer{Key: "override"},
  1295  			expected:      &Syncer{Key: "override"},
  1296  		},
  1297  		{
  1298  			description:   "Override IFrame",
  1299  			givenOriginal: &Syncer{IFrame: &SyncerEndpoint{URL: "original"}},
  1300  			givenOverride: &Syncer{IFrame: &SyncerEndpoint{URL: "override"}},
  1301  			expected:      &Syncer{IFrame: &SyncerEndpoint{URL: "override"}},
  1302  		},
  1303  		{
  1304  			description:   "Override Redirect",
  1305  			givenOriginal: &Syncer{Redirect: &SyncerEndpoint{URL: "original"}},
  1306  			givenOverride: &Syncer{Redirect: &SyncerEndpoint{URL: "override"}},
  1307  			expected:      &Syncer{Redirect: &SyncerEndpoint{URL: "override"}},
  1308  		},
  1309  		{
  1310  			description:   "Override ExternalURL",
  1311  			givenOriginal: &Syncer{ExternalURL: "original"},
  1312  			givenOverride: &Syncer{ExternalURL: "override"},
  1313  			expected:      &Syncer{ExternalURL: "override"},
  1314  		},
  1315  		{
  1316  			description:   "Override SupportCORS",
  1317  			givenOriginal: &Syncer{SupportCORS: &trueValue},
  1318  			givenOverride: &Syncer{SupportCORS: &falseValue},
  1319  			expected:      &Syncer{SupportCORS: &falseValue},
  1320  		},
  1321  		{
  1322  			description:   "Override Partial - Other Fields Untouched",
  1323  			givenOriginal: &Syncer{Key: "originalKey", ExternalURL: "originalExternalURL"},
  1324  			givenOverride: &Syncer{ExternalURL: "overrideExternalURL"},
  1325  			expected:      &Syncer{Key: "originalKey", ExternalURL: "overrideExternalURL"},
  1326  		},
  1327  	}
  1328  
  1329  	for _, test := range testCases {
  1330  		result := test.givenOverride.Override(test.givenOriginal)
  1331  		assert.Equal(t, test.expected, result, test.description)
  1332  	}
  1333  }
  1334  
  1335  func TestSyncerEndpointOverride(t *testing.T) {
  1336  	testCases := []struct {
  1337  		description   string
  1338  		givenOriginal *SyncerEndpoint
  1339  		givenOverride *SyncerEndpoint
  1340  		expected      *SyncerEndpoint
  1341  	}{
  1342  		{
  1343  			description:   "Nil",
  1344  			givenOriginal: nil,
  1345  			givenOverride: nil,
  1346  			expected:      nil,
  1347  		},
  1348  		{
  1349  			description:   "Original Nil",
  1350  			givenOriginal: nil,
  1351  			givenOverride: &SyncerEndpoint{URL: "anyURL"},
  1352  			expected:      &SyncerEndpoint{URL: "anyURL"},
  1353  		},
  1354  		{
  1355  			description:   "Original Empty",
  1356  			givenOriginal: &SyncerEndpoint{},
  1357  			givenOverride: &SyncerEndpoint{URL: "anyURL"},
  1358  			expected:      &SyncerEndpoint{URL: "anyURL"},
  1359  		},
  1360  		{
  1361  			description:   "Override Nil",
  1362  			givenOriginal: &SyncerEndpoint{URL: "anyURL"},
  1363  			givenOverride: nil,
  1364  			expected:      &SyncerEndpoint{URL: "anyURL"},
  1365  		},
  1366  		{
  1367  			description:   "Override Empty",
  1368  			givenOriginal: &SyncerEndpoint{URL: "anyURL"},
  1369  			givenOverride: &SyncerEndpoint{},
  1370  			expected:      &SyncerEndpoint{URL: "anyURL"},
  1371  		},
  1372  		{
  1373  			description:   "Override URL",
  1374  			givenOriginal: &SyncerEndpoint{URL: "original"},
  1375  			givenOverride: &SyncerEndpoint{URL: "override"},
  1376  			expected:      &SyncerEndpoint{URL: "override"},
  1377  		},
  1378  		{
  1379  			description:   "Override RedirectURL",
  1380  			givenOriginal: &SyncerEndpoint{RedirectURL: "original"},
  1381  			givenOverride: &SyncerEndpoint{RedirectURL: "override"},
  1382  			expected:      &SyncerEndpoint{RedirectURL: "override"},
  1383  		},
  1384  		{
  1385  			description:   "Override ExternalURL",
  1386  			givenOriginal: &SyncerEndpoint{ExternalURL: "original"},
  1387  			givenOverride: &SyncerEndpoint{ExternalURL: "override"},
  1388  			expected:      &SyncerEndpoint{ExternalURL: "override"},
  1389  		},
  1390  		{
  1391  			description:   "Override UserMacro",
  1392  			givenOriginal: &SyncerEndpoint{UserMacro: "original"},
  1393  			givenOverride: &SyncerEndpoint{UserMacro: "override"},
  1394  			expected:      &SyncerEndpoint{UserMacro: "override"},
  1395  		},
  1396  		{
  1397  			description:   "Override",
  1398  			givenOriginal: &SyncerEndpoint{URL: "originalURL", RedirectURL: "originalRedirectURL", ExternalURL: "originalExternalURL", UserMacro: "originalUserMacro"},
  1399  			givenOverride: &SyncerEndpoint{URL: "overideURL", RedirectURL: "overideRedirectURL", ExternalURL: "overideExternalURL", UserMacro: "overideUserMacro"},
  1400  			expected:      &SyncerEndpoint{URL: "overideURL", RedirectURL: "overideRedirectURL", ExternalURL: "overideExternalURL", UserMacro: "overideUserMacro"},
  1401  		},
  1402  	}
  1403  
  1404  	for _, test := range testCases {
  1405  		result := test.givenOverride.Override(test.givenOriginal)
  1406  		assert.Equal(t, test.expected, result, test.description)
  1407  	}
  1408  }
  1409  
  1410  func TestApplyBidderInfoConfigSyncerOverrides(t *testing.T) {
  1411  	var testCases = []struct {
  1412  		description            string
  1413  		givenFsBidderInfos     BidderInfos
  1414  		givenConfigBidderInfos BidderInfos
  1415  		expectedError          string
  1416  		expectedBidderInfos    BidderInfos
  1417  	}{
  1418  		{
  1419  			description:            "Syncer Override",
  1420  			givenFsBidderInfos:     BidderInfos{"a": {Syncer: &Syncer{Key: "original"}}},
  1421  			givenConfigBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}},
  1422  			expectedBidderInfos:    BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}},
  1423  		},
  1424  		{
  1425  			description:            "UserSyncURL Override IFrame",
  1426  			givenFsBidderInfos:     BidderInfos{"a": {Syncer: &Syncer{IFrame: &SyncerEndpoint{URL: "original"}}}},
  1427  			givenConfigBidderInfos: BidderInfos{"a": {UserSyncURL: "override"}},
  1428  			expectedBidderInfos:    BidderInfos{"a": {UserSyncURL: "override", Syncer: &Syncer{IFrame: &SyncerEndpoint{URL: "override"}}}},
  1429  		},
  1430  		{
  1431  			description:            "UserSyncURL Supports IFrame",
  1432  			givenFsBidderInfos:     BidderInfos{"a": {Syncer: &Syncer{Supports: []string{"iframe"}}}},
  1433  			givenConfigBidderInfos: BidderInfos{"a": {UserSyncURL: "override"}},
  1434  			expectedBidderInfos:    BidderInfos{"a": {UserSyncURL: "override", Syncer: &Syncer{Supports: []string{"iframe"}, IFrame: &SyncerEndpoint{URL: "override"}}}},
  1435  		},
  1436  		{
  1437  			description:            "UserSyncURL Override Redirect",
  1438  			givenFsBidderInfos:     BidderInfos{"a": {Syncer: &Syncer{Supports: []string{"redirect"}}}},
  1439  			givenConfigBidderInfos: BidderInfos{"a": {UserSyncURL: "override"}},
  1440  			expectedBidderInfos:    BidderInfos{"a": {UserSyncURL: "override", Syncer: &Syncer{Supports: []string{"redirect"}, Redirect: &SyncerEndpoint{URL: "override"}}}},
  1441  		},
  1442  		{
  1443  			description:            "UserSyncURL Supports Redirect",
  1444  			givenFsBidderInfos:     BidderInfos{"a": {Syncer: &Syncer{Redirect: &SyncerEndpoint{URL: "original"}}}},
  1445  			givenConfigBidderInfos: BidderInfos{"a": {UserSyncURL: "override"}},
  1446  			expectedBidderInfos:    BidderInfos{"a": {UserSyncURL: "override", Syncer: &Syncer{Redirect: &SyncerEndpoint{URL: "override"}}}},
  1447  		},
  1448  		{
  1449  			description:            "UserSyncURL Override Syncer Not Defined",
  1450  			givenFsBidderInfos:     BidderInfos{"a": {}},
  1451  			givenConfigBidderInfos: BidderInfos{"a": {UserSyncURL: "override"}},
  1452  			expectedError:          "adapters.a.usersync_url cannot be applied, bidder does not define a user sync",
  1453  		},
  1454  		{
  1455  			description:            "UserSyncURL Override Syncer Endpoints Not Defined",
  1456  			givenFsBidderInfos:     BidderInfos{"a": {Syncer: &Syncer{}}},
  1457  			givenConfigBidderInfos: BidderInfos{"a": {UserSyncURL: "override"}},
  1458  			expectedError:          "adapters.a.usersync_url cannot be applied, bidder does not define user sync endpoints and does not define supported endpoints",
  1459  		},
  1460  		{
  1461  			description:            "UserSyncURL Override Ambiguous",
  1462  			givenFsBidderInfos:     BidderInfos{"a": {Syncer: &Syncer{IFrame: &SyncerEndpoint{URL: "originalIFrame"}, Redirect: &SyncerEndpoint{URL: "originalRedirect"}}}},
  1463  			givenConfigBidderInfos: BidderInfos{"a": {UserSyncURL: "override"}},
  1464  			expectedError:          "adapters.a.usersync_url cannot be applied, bidder defines multiple user sync endpoints or supports multiple endpoints",
  1465  		},
  1466  		{
  1467  			description:            "UserSyncURL Supports Ambiguous",
  1468  			givenFsBidderInfos:     BidderInfos{"a": {Syncer: &Syncer{Supports: []string{"iframe", "redirect"}}}},
  1469  			givenConfigBidderInfos: BidderInfos{"a": {UserSyncURL: "override"}},
  1470  			expectedError:          "adapters.a.usersync_url cannot be applied, bidder defines multiple user sync endpoints or supports multiple endpoints",
  1471  		},
  1472  	}
  1473  
  1474  	for _, test := range testCases {
  1475  		bidderInfos, resultErr := applyBidderInfoConfigOverrides(test.givenConfigBidderInfos, test.givenFsBidderInfos, mockNormalizeBidderName)
  1476  		if test.expectedError == "" {
  1477  			assert.NoError(t, resultErr, test.description+":err")
  1478  			assert.Equal(t, test.expectedBidderInfos, bidderInfos, test.description+":result")
  1479  		} else {
  1480  			assert.EqualError(t, resultErr, test.expectedError, test.description+":err")
  1481  		}
  1482  	}
  1483  }
  1484  
  1485  func TestApplyBidderInfoConfigOverrides(t *testing.T) {
  1486  	var testCases = []struct {
  1487  		description            string
  1488  		givenFsBidderInfos     BidderInfos
  1489  		givenConfigBidderInfos BidderInfos
  1490  		expectedError          string
  1491  		expectedBidderInfos    BidderInfos
  1492  	}{
  1493  		{
  1494  			description:            "Don't override endpoint",
  1495  			givenFsBidderInfos:     BidderInfos{"a": {Endpoint: "original"}},
  1496  			givenConfigBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}},
  1497  			expectedBidderInfos:    BidderInfos{"a": {Endpoint: "original", Syncer: &Syncer{Key: "override"}}},
  1498  		},
  1499  		{
  1500  			description:            "Override endpoint",
  1501  			givenFsBidderInfos:     BidderInfos{"a": {Endpoint: "original"}},
  1502  			givenConfigBidderInfos: BidderInfos{"a": {Endpoint: "override", Syncer: &Syncer{Key: "override"}}},
  1503  			expectedBidderInfos:    BidderInfos{"a": {Endpoint: "override", Syncer: &Syncer{Key: "override"}}},
  1504  		},
  1505  		{
  1506  			description:            "Don't override ExtraAdapterInfo",
  1507  			givenFsBidderInfos:     BidderInfos{"a": {ExtraAdapterInfo: "original"}},
  1508  			givenConfigBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}},
  1509  			expectedBidderInfos:    BidderInfos{"a": {ExtraAdapterInfo: "original", Syncer: &Syncer{Key: "override"}}},
  1510  		},
  1511  		{
  1512  			description:            "Override ExtraAdapterInfo",
  1513  			givenFsBidderInfos:     BidderInfos{"a": {ExtraAdapterInfo: "original"}},
  1514  			givenConfigBidderInfos: BidderInfos{"a": {ExtraAdapterInfo: "override", Syncer: &Syncer{Key: "override"}}},
  1515  			expectedBidderInfos:    BidderInfos{"a": {ExtraAdapterInfo: "override", Syncer: &Syncer{Key: "override"}}},
  1516  		},
  1517  		{
  1518  			description:            "Don't override Maintainer",
  1519  			givenFsBidderInfos:     BidderInfos{"a": {Maintainer: &MaintainerInfo{Email: "original"}}},
  1520  			givenConfigBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}},
  1521  			expectedBidderInfos:    BidderInfos{"a": {Maintainer: &MaintainerInfo{Email: "original"}, Syncer: &Syncer{Key: "override"}}},
  1522  		},
  1523  		{
  1524  			description:            "Override maintainer",
  1525  			givenFsBidderInfos:     BidderInfos{"a": {Maintainer: &MaintainerInfo{Email: "original"}}},
  1526  			givenConfigBidderInfos: BidderInfos{"a": {Maintainer: &MaintainerInfo{Email: "override"}, Syncer: &Syncer{Key: "override"}}},
  1527  			expectedBidderInfos:    BidderInfos{"a": {Maintainer: &MaintainerInfo{Email: "override"}, Syncer: &Syncer{Key: "override"}}},
  1528  		},
  1529  		{
  1530  			description: "Don't override Capabilities",
  1531  			givenFsBidderInfos: BidderInfos{"a": {
  1532  				Capabilities: &CapabilitiesInfo{App: &PlatformInfo{MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeVideo}}},
  1533  			}},
  1534  			givenConfigBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}},
  1535  			expectedBidderInfos: BidderInfos{"a": {
  1536  				Syncer:       &Syncer{Key: "override"},
  1537  				Capabilities: &CapabilitiesInfo{App: &PlatformInfo{MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeVideo}}},
  1538  			}},
  1539  		},
  1540  		{
  1541  			description: "Override Capabilities",
  1542  			givenFsBidderInfos: BidderInfos{"a": {
  1543  				Capabilities: &CapabilitiesInfo{App: &PlatformInfo{MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeVideo}}},
  1544  			}},
  1545  			givenConfigBidderInfos: BidderInfos{"a": {
  1546  				Syncer:       &Syncer{Key: "override"},
  1547  				Capabilities: &CapabilitiesInfo{App: &PlatformInfo{MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner}}},
  1548  			}},
  1549  			expectedBidderInfos: BidderInfos{"a": {
  1550  				Syncer:       &Syncer{Key: "override"},
  1551  				Capabilities: &CapabilitiesInfo{App: &PlatformInfo{MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner}}},
  1552  			}},
  1553  		},
  1554  		{
  1555  			description:            "Don't override Debug",
  1556  			givenFsBidderInfos:     BidderInfos{"a": {Debug: &DebugInfo{Allow: true}}},
  1557  			givenConfigBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}},
  1558  			expectedBidderInfos:    BidderInfos{"a": {Debug: &DebugInfo{Allow: true}, Syncer: &Syncer{Key: "override"}}},
  1559  		},
  1560  		{
  1561  			description:            "Override Debug",
  1562  			givenFsBidderInfos:     BidderInfos{"a": {Debug: &DebugInfo{Allow: true}}},
  1563  			givenConfigBidderInfos: BidderInfos{"a": {Debug: &DebugInfo{Allow: false}, Syncer: &Syncer{Key: "override"}}},
  1564  			expectedBidderInfos:    BidderInfos{"a": {Debug: &DebugInfo{Allow: false}, Syncer: &Syncer{Key: "override"}}},
  1565  		},
  1566  		{
  1567  			description:            "Don't override GVLVendorID",
  1568  			givenFsBidderInfos:     BidderInfos{"a": {GVLVendorID: 5}},
  1569  			givenConfigBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}},
  1570  			expectedBidderInfos:    BidderInfos{"a": {GVLVendorID: 5, Syncer: &Syncer{Key: "override"}}},
  1571  		},
  1572  		{
  1573  			description:            "Override GVLVendorID",
  1574  			givenFsBidderInfos:     BidderInfos{"a": {}},
  1575  			givenConfigBidderInfos: BidderInfos{"a": {GVLVendorID: 5, Syncer: &Syncer{Key: "override"}}},
  1576  			expectedBidderInfos:    BidderInfos{"a": {GVLVendorID: 5, Syncer: &Syncer{Key: "override"}}},
  1577  		},
  1578  		{
  1579  			description: "Don't override XAPI",
  1580  			givenFsBidderInfos: BidderInfos{"a": {
  1581  				XAPI: AdapterXAPI{Username: "username1", Password: "password2", Tracker: "tracker3"},
  1582  			}},
  1583  			givenConfigBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}},
  1584  			expectedBidderInfos: BidderInfos{"a": {
  1585  				XAPI:   AdapterXAPI{Username: "username1", Password: "password2", Tracker: "tracker3"},
  1586  				Syncer: &Syncer{Key: "override"}}},
  1587  		},
  1588  		{
  1589  			description: "Override XAPI",
  1590  			givenFsBidderInfos: BidderInfos{"a": {
  1591  				XAPI: AdapterXAPI{Username: "username", Password: "password", Tracker: "tracker"}}},
  1592  			givenConfigBidderInfos: BidderInfos{"a": {
  1593  				XAPI:   AdapterXAPI{Username: "username1", Password: "password2", Tracker: "tracker3"},
  1594  				Syncer: &Syncer{Key: "override"}}},
  1595  			expectedBidderInfos: BidderInfos{"a": {
  1596  				XAPI:   AdapterXAPI{Username: "username1", Password: "password2", Tracker: "tracker3"},
  1597  				Syncer: &Syncer{Key: "override"}}},
  1598  		},
  1599  		{
  1600  			description:            "Don't override PlatformID",
  1601  			givenFsBidderInfos:     BidderInfos{"a": {PlatformID: "PlatformID"}},
  1602  			givenConfigBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}},
  1603  			expectedBidderInfos:    BidderInfos{"a": {PlatformID: "PlatformID", Syncer: &Syncer{Key: "override"}}},
  1604  		},
  1605  		{
  1606  			description:            "Override PlatformID",
  1607  			givenFsBidderInfos:     BidderInfos{"a": {PlatformID: "PlatformID1"}},
  1608  			givenConfigBidderInfos: BidderInfos{"a": {PlatformID: "PlatformID2", Syncer: &Syncer{Key: "override"}}},
  1609  			expectedBidderInfos:    BidderInfos{"a": {PlatformID: "PlatformID2", Syncer: &Syncer{Key: "override"}}},
  1610  		},
  1611  		{
  1612  			description:            "Don't override AppSecret",
  1613  			givenFsBidderInfos:     BidderInfos{"a": {AppSecret: "AppSecret"}},
  1614  			givenConfigBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}},
  1615  			expectedBidderInfos:    BidderInfos{"a": {AppSecret: "AppSecret", Syncer: &Syncer{Key: "override"}}},
  1616  		},
  1617  		{
  1618  			description:            "Override AppSecret",
  1619  			givenFsBidderInfos:     BidderInfos{"a": {AppSecret: "AppSecret1"}},
  1620  			givenConfigBidderInfos: BidderInfos{"a": {AppSecret: "AppSecret2", Syncer: &Syncer{Key: "override"}}},
  1621  			expectedBidderInfos:    BidderInfos{"a": {AppSecret: "AppSecret2", Syncer: &Syncer{Key: "override"}}},
  1622  		},
  1623  		{
  1624  			description:            "Don't override EndpointCompression",
  1625  			givenFsBidderInfos:     BidderInfos{"a": {EndpointCompression: "GZIP"}},
  1626  			givenConfigBidderInfos: BidderInfos{"a": {Syncer: &Syncer{Key: "override"}}},
  1627  			expectedBidderInfos:    BidderInfos{"a": {EndpointCompression: "GZIP", Syncer: &Syncer{Key: "override"}}},
  1628  		},
  1629  		{
  1630  			description:            "Override EndpointCompression",
  1631  			givenFsBidderInfos:     BidderInfos{"a": {EndpointCompression: "GZIP"}},
  1632  			givenConfigBidderInfos: BidderInfos{"a": {EndpointCompression: "LZ77", Syncer: &Syncer{Key: "override"}}},
  1633  			expectedBidderInfos:    BidderInfos{"a": {EndpointCompression: "LZ77", Syncer: &Syncer{Key: "override"}}},
  1634  		},
  1635  	}
  1636  	for _, test := range testCases {
  1637  		bidderInfos, resultErr := applyBidderInfoConfigOverrides(test.givenConfigBidderInfos, test.givenFsBidderInfos, mockNormalizeBidderName)
  1638  		assert.NoError(t, resultErr, test.description+":err")
  1639  		assert.Equal(t, test.expectedBidderInfos, bidderInfos, test.description+":result")
  1640  	}
  1641  }
  1642  
  1643  func TestApplyBidderInfoConfigOverridesInvalid(t *testing.T) {
  1644  	var testCases = []struct {
  1645  		description            string
  1646  		givenFsBidderInfos     BidderInfos
  1647  		givenConfigBidderInfos BidderInfos
  1648  		expectedError          string
  1649  		expectedBidderInfos    BidderInfos
  1650  	}{
  1651  		{
  1652  			description:            "Bidder doesn't exists in bidder list",
  1653  			givenConfigBidderInfos: BidderInfos{"unknown": {Syncer: &Syncer{Key: "override"}}},
  1654  			expectedError:          "error setting configuration for bidder unknown: unknown bidder",
  1655  		},
  1656  		{
  1657  			description:            "Bidder doesn't exists in file system",
  1658  			givenFsBidderInfos:     BidderInfos{"unknown": {Endpoint: "original"}},
  1659  			givenConfigBidderInfos: BidderInfos{"bidderA": {Syncer: &Syncer{Key: "override"}}},
  1660  			expectedError:          "error finding configuration for bidder bidderA: unknown bidder",
  1661  		},
  1662  	}
  1663  	for _, test := range testCases {
  1664  		_, err := applyBidderInfoConfigOverrides(test.givenConfigBidderInfos, test.givenFsBidderInfos, mockNormalizeBidderName)
  1665  		assert.ErrorContains(t, err, test.expectedError, test.description+":err")
  1666  	}
  1667  }
  1668  
  1669  func TestReadFullYamlBidderConfig(t *testing.T) {
  1670  	bidder := "bidderA"
  1671  	bidderInf := BidderInfo{}
  1672  	err := yaml.Unmarshal([]byte(fullBidderYAMLConfig), &bidderInf)
  1673  	actualBidderInfo, err := applyBidderInfoConfigOverrides(BidderInfos{bidder: bidderInf}, BidderInfos{bidder: {Syncer: &Syncer{Supports: []string{"iframe"}}}}, mockNormalizeBidderName)
  1674  
  1675  	assert.NoError(t, err, "Error wasn't expected")
  1676  
  1677  	expectedBidderInfo := BidderInfos{
  1678  		bidder: {
  1679  			Maintainer: &MaintainerInfo{
  1680  				Email: "some-email@domain.com",
  1681  			},
  1682  			GVLVendorID: 42,
  1683  			Capabilities: &CapabilitiesInfo{
  1684  				App: &PlatformInfo{
  1685  					MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner, openrtb_ext.BidTypeVideo, openrtb_ext.BidTypeNative},
  1686  				},
  1687  				Site: &PlatformInfo{
  1688  					MediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner, openrtb_ext.BidTypeVideo, openrtb_ext.BidTypeNative},
  1689  				},
  1690  			},
  1691  			ModifyingVastXmlAllowed: true,
  1692  			Debug: &DebugInfo{
  1693  				Allow: true,
  1694  			},
  1695  			Experiment: BidderInfoExperiment{
  1696  				AdsCert: BidderAdsCert{
  1697  					Enabled: true,
  1698  				},
  1699  			},
  1700  			EndpointCompression: "GZIP",
  1701  			OpenRTB: &OpenRTBInfo{
  1702  				GPPSupported: true,
  1703  				Version:      "2.6",
  1704  			},
  1705  			Disabled:         false,
  1706  			ExtraAdapterInfo: "extra-info",
  1707  			AppSecret:        "app-secret",
  1708  			PlatformID:       "123",
  1709  			UserSyncURL:      "user-url",
  1710  			Syncer: &Syncer{
  1711  				Key: "foo",
  1712  				IFrame: &SyncerEndpoint{
  1713  					URL:         "user-url",
  1714  					RedirectURL: "https://redirect/setuid/iframe",
  1715  					ExternalURL: "https://iframe.host",
  1716  					UserMacro:   "UID",
  1717  				},
  1718  				Supports: []string{"iframe"},
  1719  			},
  1720  			XAPI: AdapterXAPI{
  1721  				Username: "uname",
  1722  				Password: "pwd",
  1723  				Tracker:  "tracker",
  1724  			},
  1725  			Endpoint: "https://endpoint.com",
  1726  		},
  1727  	}
  1728  	assert.Equalf(t, expectedBidderInfo, actualBidderInfo, "Bidder info objects aren't matching")
  1729  }