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 }