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