diff --git a/endpoints/openrtb2/auction_test.go b/endpoints/openrtb2/auction_test.go index 69ba0da9ad..dfc4f441cf 100644 --- a/endpoints/openrtb2/auction_test.go +++ b/endpoints/openrtb2/auction_test.go @@ -3977,6 +3977,7 @@ func TestParseRequestMergeBidderParams(t *testing.T) { expectedImpExt json.RawMessage expectedReqExt json.RawMessage expectedErrorCount int + expectedErrors []error }{ { name: "add missing bidder-params from req.ext.prebid.bidderparams to imp[].ext.prebid.bidder", @@ -3994,10 +3995,16 @@ func TestParseRequestMergeBidderParams(t *testing.T) { }, { name: "add missing bidder-params from req.ext.prebid.bidderparams to imp[].ext for backward compatibility", - givenRequestBody: validRequest(t, "req-ext-bidder-params-backward-compatible-merge.json"), - expectedImpExt: getObject(t, "req-ext-bidder-params-backward-compatible-merge.json", "expectedImpExt"), - expectedReqExt: getObject(t, "req-ext-bidder-params-backward-compatible-merge.json", "expectedReqExt"), - expectedErrorCount: 0, + givenRequestBody: validRequest(t, "req-ext-bidder-params-promotion.json"), + expectedImpExt: getObject(t, "req-ext-bidder-params-promotion.json", "expectedImpExt"), + expectedReqExt: getObject(t, "req-ext-bidder-params-promotion.json", "expectedReqExt"), + expectedErrorCount: 1, + expectedErrors: []error{ + &errortypes.Warning{ + WarningCode: 0, + Message: "request.imp[0].ext contains unknown bidder: 'arbitraryObject', ignoring", + }, + }, }, } for _, test := range tests { @@ -4054,6 +4061,8 @@ func TestParseRequestMergeBidderParams(t *testing.T) { assert.Equal(t, eReqE, reqE, "req.Ext should match") assert.Len(t, errL, test.expectedErrorCount, "error length should match") + + assert.Equal(t, errL, test.expectedErrors) }) } } @@ -4658,7 +4667,7 @@ func TestValidateStoredResp(t *testing.T) { storedBidResponses: stored_responses.ImpBidderStoredResp{"Some-Imp-ID": {"appnexus": json.RawMessage(`{"test":true}`), "rubicon": json.RawMessage(`{"test":true}`)}}, }, { - description: "One imp with 2 stored bid responses and 1 bidders in imp.ext and 1 in imp.ext.prebid.bidder, expect validate request to throw no errors", + description: "One imp with 1 stored bid response and 1 ignored bidder in imp.ext and 1 included bidder in imp.ext.prebid.bidder, expect validate request to throw no errors", givenRequestWrapper: &openrtb_ext.RequestWrapper{ BidRequest: &openrtb2.BidRequest{ ID: "Some-ID", @@ -4685,7 +4694,7 @@ func TestValidateStoredResp(t *testing.T) { }, expectedErrorList: []error{}, hasStoredAuctionResponses: false, - storedBidResponses: stored_responses.ImpBidderStoredResp{"Some-Imp-ID": {"appnexus": json.RawMessage(`{"test":true}`), "telaria": json.RawMessage(`{"test":true}`)}}, + storedBidResponses: stored_responses.ImpBidderStoredResp{"Some-Imp-ID": {"telaria": json.RawMessage(`{"test":true}`)}}, }, { description: "One imp with 2 stored bid responses and 1 bidders in imp.ext and 1 in imp.ext.prebid.bidder that is not defined in stored bid responses, expect validate request to throw an error", diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/unknown-bidder.json b/endpoints/openrtb2/sample-requests/invalid-whole/imp-ext-prebid-bidder-empty.json similarity index 80% rename from endpoints/openrtb2/sample-requests/invalid-whole/unknown-bidder.json rename to endpoints/openrtb2/sample-requests/invalid-whole/imp-ext-prebid-bidder-empty.json index a907d4d925..d87a6d3326 100644 --- a/endpoints/openrtb2/sample-requests/invalid-whole/unknown-bidder.json +++ b/endpoints/openrtb2/sample-requests/invalid-whole/imp-ext-prebid-bidder-empty.json @@ -21,6 +21,9 @@ ] }, "ext": { + "prebid": { + "bidder": {} + }, "appnexus": { "placementId": 12883451 }, @@ -34,5 +37,5 @@ "tmax": 500 }, "expectedReturnCode": 400, - "expectedErrorMessage": "Invalid request" + "expectedErrorMessage": "Invalid request: request.imp[0].ext.prebid.bidder must contain at least one bidder\n" } diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/imp-ext-unknown-bidder.json b/endpoints/openrtb2/sample-requests/invalid-whole/imp-ext-unknown-bidder.json index 8a7b793217..6b25ee8b03 100644 --- a/endpoints/openrtb2/sample-requests/invalid-whole/imp-ext-unknown-bidder.json +++ b/endpoints/openrtb2/sample-requests/invalid-whole/imp-ext-unknown-bidder.json @@ -22,5 +22,5 @@ } }, "expectedReturnCode": 400, - "expectedErrorMessage": "Invalid request: request.imp[0].ext.prebid.bidder contains unknown bidder: noBidderShouldEverHaveThisName. Did you forget an alias in request.ext.prebid.aliases?\n" + "expectedErrorMessage": "Invalid request: request.imp[0].ext.prebid.bidder must contain at least one bidder" } diff --git a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/req-ext-bidder-params-backward-compatible-merge.json b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/req-ext-bidder-params-promotion.json similarity index 94% rename from endpoints/openrtb2/sample-requests/valid-whole/supplementary/req-ext-bidder-params-backward-compatible-merge.json rename to endpoints/openrtb2/sample-requests/valid-whole/supplementary/req-ext-bidder-params-promotion.json index 9e9fd53811..d1d2040491 100644 --- a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/req-ext-bidder-params-backward-compatible-merge.json +++ b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/req-ext-bidder-params-promotion.json @@ -32,8 +32,8 @@ "profile": 1234 } }, - "prebid": { - "bidder": {} + "arbitraryObject": { + "arbitraryField": 1232 } } } @@ -107,6 +107,9 @@ } } } + }, + "arbitraryObject": { + "arbitraryField": 1232 } }, "expectedReturnCode": 200 diff --git a/exchange/utils.go b/exchange/utils.go index aa2c14ba03..71f7c20f8c 100644 --- a/exchange/utils.go +++ b/exchange/utils.go @@ -718,20 +718,15 @@ func mergeImpFPD(imp *openrtb2.Imp, fpd json.RawMessage, index int) error { return nil } -var allowedImpExtFields = map[string]interface{}{ - openrtb_ext.AuctionEnvironmentKey: struct{}{}, - openrtb_ext.FirstPartyDataExtKey: struct{}{}, - openrtb_ext.FirstPartyDataContextExtKey: struct{}{}, - openrtb_ext.GPIDKey: struct{}{}, - openrtb_ext.SKAdNExtKey: struct{}{}, - openrtb_ext.TIDKey: struct{}{}, -} - var allowedImpExtPrebidFields = map[string]interface{}{ openrtb_ext.IsRewardedInventoryKey: struct{}{}, openrtb_ext.OptionsKey: struct{}{}, } +var deniedImpExtFields = map[string]interface{}{ + openrtb_ext.PrebidExtKey: struct{}{}, +} + func createSanitizedImpExt(impExt, impExtPrebid map[string]json.RawMessage) (map[string]json.RawMessage, error) { sanitizedImpExt := make(map[string]json.RawMessage, 6) sanitizedImpPrebidExt := make(map[string]json.RawMessage, 2) @@ -753,8 +748,8 @@ func createSanitizedImpExt(impExt, impExtPrebid map[string]json.RawMessage) (map } // copy reserved imp[].ext fields known to not be bidder names - for k := range allowedImpExtFields { - if v, exists := impExt[k]; exists { + for k, v := range impExt { + if _, exists := deniedImpExtFields[k]; !exists { sanitizedImpExt[k] = v } } diff --git a/exchange/utils_test.go b/exchange/utils_test.go index a77004217d..64f0973ecf 100644 --- a/exchange/utils_test.go +++ b/exchange/utils_test.go @@ -607,80 +607,83 @@ func TestCreateSanitizedImpExt(t *testing.T) { { description: "imp.ext", givenImpExt: map[string]json.RawMessage{ - "anyBidder": json.RawMessage(`"anyBidderValues"`), - "data": json.RawMessage(`"anyData"`), - "context": json.RawMessage(`"anyContext"`), - "skadn": json.RawMessage(`"anySKAdNetwork"`), - "gpid": json.RawMessage(`"anyGPID"`), - "tid": json.RawMessage(`"anyTID"`), + "arbitraryField": json.RawMessage(`"arbitraryValue"`), + "data": json.RawMessage(`"anyData"`), + "context": json.RawMessage(`"anyContext"`), + "skadn": json.RawMessage(`"anySKAdNetwork"`), + "gpid": json.RawMessage(`"anyGPID"`), + "tid": json.RawMessage(`"anyTID"`), }, givenImpExtPrebid: map[string]json.RawMessage{}, expected: map[string]json.RawMessage{ - "data": json.RawMessage(`"anyData"`), - "context": json.RawMessage(`"anyContext"`), - "skadn": json.RawMessage(`"anySKAdNetwork"`), - "gpid": json.RawMessage(`"anyGPID"`), - "tid": json.RawMessage(`"anyTID"`), + "arbitraryField": json.RawMessage(`"arbitraryValue"`), + "data": json.RawMessage(`"anyData"`), + "context": json.RawMessage(`"anyContext"`), + "skadn": json.RawMessage(`"anySKAdNetwork"`), + "gpid": json.RawMessage(`"anyGPID"`), + "tid": json.RawMessage(`"anyTID"`), }, expectedError: "", }, { description: "imp.ext + imp.ext.prebid - Prebid Bidder Only", givenImpExt: map[string]json.RawMessage{ - "anyBidder": json.RawMessage(`"anyBidderValues"`), - "prebid": json.RawMessage(`"ignoredInFavorOfSeparatelyUnmarshalledImpExtPrebid"`), - "data": json.RawMessage(`"anyData"`), - "context": json.RawMessage(`"anyContext"`), - "skadn": json.RawMessage(`"anySKAdNetwork"`), - "gpid": json.RawMessage(`"anyGPID"`), - "tid": json.RawMessage(`"anyTID"`), + "arbitraryField": json.RawMessage(`"arbitraryValue"`), + "prebid": json.RawMessage(`"ignoredInFavorOfSeparatelyUnmarshalledImpExtPrebid"`), + "data": json.RawMessage(`"anyData"`), + "context": json.RawMessage(`"anyContext"`), + "skadn": json.RawMessage(`"anySKAdNetwork"`), + "gpid": json.RawMessage(`"anyGPID"`), + "tid": json.RawMessage(`"anyTID"`), }, givenImpExtPrebid: map[string]json.RawMessage{ "bidder": json.RawMessage(`"anyBidder"`), }, expected: map[string]json.RawMessage{ - "data": json.RawMessage(`"anyData"`), - "context": json.RawMessage(`"anyContext"`), - "skadn": json.RawMessage(`"anySKAdNetwork"`), - "gpid": json.RawMessage(`"anyGPID"`), - "tid": json.RawMessage(`"anyTID"`), + "arbitraryField": json.RawMessage(`"arbitraryValue"`), + "data": json.RawMessage(`"anyData"`), + "context": json.RawMessage(`"anyContext"`), + "skadn": json.RawMessage(`"anySKAdNetwork"`), + "gpid": json.RawMessage(`"anyGPID"`), + "tid": json.RawMessage(`"anyTID"`), }, expectedError: "", }, { description: "imp.ext + imp.ext.prebid - Prebid Bidder + Other Forbidden Value", givenImpExt: map[string]json.RawMessage{ - "anyBidder": json.RawMessage(`"anyBidderValues"`), - "prebid": json.RawMessage(`"ignoredInFavorOfSeparatelyUnmarshalledImpExtPrebid"`), - "data": json.RawMessage(`"anyData"`), - "context": json.RawMessage(`"anyContext"`), - "skadn": json.RawMessage(`"anySKAdNetwork"`), - "gpid": json.RawMessage(`"anyGPID"`), - "tid": json.RawMessage(`"anyTID"`), + "arbitraryField": json.RawMessage(`"arbitraryValue"`), + "prebid": json.RawMessage(`"ignoredInFavorOfSeparatelyUnmarshalledImpExtPrebid"`), + "data": json.RawMessage(`"anyData"`), + "context": json.RawMessage(`"anyContext"`), + "skadn": json.RawMessage(`"anySKAdNetwork"`), + "gpid": json.RawMessage(`"anyGPID"`), + "tid": json.RawMessage(`"anyTID"`), }, givenImpExtPrebid: map[string]json.RawMessage{ "bidder": json.RawMessage(`"anyBidder"`), "forbidden": json.RawMessage(`"anyValue"`), }, expected: map[string]json.RawMessage{ - "data": json.RawMessage(`"anyData"`), - "context": json.RawMessage(`"anyContext"`), - "skadn": json.RawMessage(`"anySKAdNetwork"`), - "gpid": json.RawMessage(`"anyGPID"`), - "tid": json.RawMessage(`"anyTID"`), + "arbitraryField": json.RawMessage(`"arbitraryValue"`), + "data": json.RawMessage(`"anyData"`), + "context": json.RawMessage(`"anyContext"`), + "skadn": json.RawMessage(`"anySKAdNetwork"`), + "gpid": json.RawMessage(`"anyGPID"`), + "tid": json.RawMessage(`"anyTID"`), }, expectedError: "", }, { description: "imp.ext + imp.ext.prebid - Prebid Bidder + Other Allowed Values", givenImpExt: map[string]json.RawMessage{ - "anyBidder": json.RawMessage(`"anyBidderValues"`), - "prebid": json.RawMessage(`"ignoredInFavorOfSeparatelyUnmarshalledImpExtPrebid"`), - "data": json.RawMessage(`"anyData"`), - "context": json.RawMessage(`"anyContext"`), - "skadn": json.RawMessage(`"anySKAdNetwork"`), - "gpid": json.RawMessage(`"anyGPID"`), - "tid": json.RawMessage(`"anyTID"`), + "arbitraryField": json.RawMessage(`"arbitraryValue"`), + "prebid": json.RawMessage(`"ignoredInFavorOfSeparatelyUnmarshalledImpExtPrebid"`), + "data": json.RawMessage(`"anyData"`), + "context": json.RawMessage(`"anyContext"`), + "skadn": json.RawMessage(`"anySKAdNetwork"`), + "gpid": json.RawMessage(`"anyGPID"`), + "tid": json.RawMessage(`"anyTID"`), }, givenImpExtPrebid: map[string]json.RawMessage{ "bidder": json.RawMessage(`"anyBidder"`), @@ -688,12 +691,13 @@ func TestCreateSanitizedImpExt(t *testing.T) { "options": json.RawMessage(`"anyOptions"`), }, expected: map[string]json.RawMessage{ - "prebid": json.RawMessage(`{"is_rewarded_inventory":"anyIsRewardedInventory","options":"anyOptions"}`), - "data": json.RawMessage(`"anyData"`), - "context": json.RawMessage(`"anyContext"`), - "skadn": json.RawMessage(`"anySKAdNetwork"`), - "gpid": json.RawMessage(`"anyGPID"`), - "tid": json.RawMessage(`"anyTID"`), + "arbitraryField": json.RawMessage(`"arbitraryValue"`), + "prebid": json.RawMessage(`{"is_rewarded_inventory":"anyIsRewardedInventory","options":"anyOptions"}`), + "data": json.RawMessage(`"anyData"`), + "context": json.RawMessage(`"anyContext"`), + "skadn": json.RawMessage(`"anySKAdNetwork"`), + "gpid": json.RawMessage(`"anyGPID"`), + "tid": json.RawMessage(`"anyTID"`), }, expectedError: "", }, diff --git a/ortb/request_validator.go b/ortb/request_validator.go index c7cc0a4ee9..e959caa934 100644 --- a/ortb/request_validator.go +++ b/ortb/request_validator.go @@ -88,22 +88,27 @@ func (srv *standardRequestValidator) validateImpExt(imp *openrtb_ext.ImpWrapper, prebid := impExt.GetOrCreatePrebid() prebidModified := false + bidderPromote := false + if prebid.Bidder == nil { prebid.Bidder = make(map[string]json.RawMessage) + bidderPromote = true } ext := impExt.GetExt() extModified := false // promote imp[].ext.BIDDER to newer imp[].ext.prebid.bidder.BIDDER location, with the later taking precedence - for k, v := range ext { - if openrtb_ext.IsPotentialBidder(k) { - if _, exists := prebid.Bidder[k]; !exists { - prebid.Bidder[k] = v - prebidModified = true + if bidderPromote { + for k, v := range ext { + if openrtb_ext.IsPotentialBidder(k) { + if _, exists := prebid.Bidder[k]; !exists { + prebid.Bidder[k] = v + prebidModified = true + } + delete(ext, k) + extModified = true } - delete(ext, k) - extModified = true } } @@ -117,7 +122,7 @@ func (srv *standardRequestValidator) validateImpExt(imp *openrtb_ext.ImpWrapper, errL := []error{} - for bidder, ext := range prebid.Bidder { + for bidder, val := range prebid.Bidder { coreBidder, _ := openrtb_ext.NormalizeBidderName(bidder) if tmp, isAlias := aliases[bidder]; isAlias { coreBidder = openrtb_ext.BidderName(tmp) @@ -125,7 +130,7 @@ func (srv *standardRequestValidator) validateImpExt(imp *openrtb_ext.ImpWrapper, if coreBidderNormalized, isValid := srv.bidderMap[coreBidder.String()]; isValid { if !cfg.SkipBidderParams { - if err := srv.paramsValidator.Validate(coreBidderNormalized, ext); err != nil { + if err := srv.paramsValidator.Validate(coreBidderNormalized, val); err != nil { return []error{fmt.Errorf("request.imp[%d].ext.prebid.bidder.%s failed validation.\n%v", impIndex, bidder, err)} } } @@ -134,6 +139,11 @@ func (srv *standardRequestValidator) validateImpExt(imp *openrtb_ext.ImpWrapper, errL = append(errL, &errortypes.BidderTemporarilyDisabled{Message: msg}) delete(prebid.Bidder, bidder) prebidModified = true + } else if bidderPromote { + errL = append(errL, &errortypes.Warning{Message: fmt.Sprintf("request.imp[%d].ext contains unknown bidder: '%s', ignoring", impIndex, bidder)}) + ext[bidder] = val + delete(prebid.Bidder, bidder) + prebidModified = true } else { return []error{fmt.Errorf("request.imp[%d].ext.prebid.bidder contains unknown bidder: %s. Did you forget an alias in request.ext.prebid.aliases?", impIndex, bidder)} } diff --git a/ortb/request_validator_test.go b/ortb/request_validator_test.go index abceda31ef..c2b6ea3c7b 100644 --- a/ortb/request_validator_test.go +++ b/ortb/request_validator_test.go @@ -38,11 +38,18 @@ func TestValidateImpExt(t *testing.T) { { "Unknown bidder tests", []testCase{ + { + description: "Unknown Bidder + Empty Prebid Bidder", + impExt: json.RawMessage(`{"prebid":{"bidder":{}}, "unknownbidder":{"placement_id":555}}`), + expectedImpExt: `{"prebid":{"bidder":{}}, "unknownbidder":{"placement_id":555}}`, + expectedErrs: []error{errors.New("request.imp[0].ext.prebid.bidder must contain at least one bidder")}, + }, { description: "Unknown Bidder only", impExt: json.RawMessage(`{"unknownbidder":{"placement_id":555}}`), expectedImpExt: `{"unknownbidder":{"placement_id":555}}`, - expectedErrs: []error{errors.New("request.imp[0].ext.prebid.bidder contains unknown bidder: unknownbidder. Did you forget an alias in request.ext.prebid.aliases?")}, + expectedErrs: []error{&errortypes.Warning{Message: ("request.imp[0].ext contains unknown bidder: 'unknownbidder', ignoring")}, + errors.New("request.imp[0].ext.prebid.bidder must contain at least one bidder")}, }, { description: "Unknown Prebid Ext Bidder only", @@ -60,19 +67,26 @@ func TestValidateImpExt(t *testing.T) { description: "Unknown Bidder + First Party Data Context", impExt: json.RawMessage(`{"unknownbidder":{"placement_id":555} ,"context":{"data":{"keywords":"prebid server example"}}}`), expectedImpExt: `{"unknownbidder":{"placement_id":555},"context":{"data":{"keywords":"prebid server example"}}}`, - expectedErrs: []error{errors.New("request.imp[0].ext.prebid.bidder contains unknown bidder: unknownbidder. Did you forget an alias in request.ext.prebid.aliases?")}, + expectedErrs: []error{&errortypes.Warning{Message: ("request.imp[0].ext contains unknown bidder: 'unknownbidder', ignoring")}, + errors.New("request.imp[0].ext.prebid.bidder must contain at least one bidder"), + }, }, { description: "Unknown Bidder + Disabled Bidder", impExt: json.RawMessage(`{"unknownbidder":{"placement_id":555},"disabledbidder":{"foo":"bar"}}`), expectedImpExt: `{"unknownbidder":{"placement_id":555},"disabledbidder":{"foo":"bar"}}`, - expectedErrs: []error{errors.New("request.imp[0].ext.prebid.bidder contains unknown bidder: unknownbidder. Did you forget an alias in request.ext.prebid.aliases?")}, + expectedErrs: []error{&errortypes.Warning{Message: ("request.imp[0].ext contains unknown bidder: 'unknownbidder', ignoring")}, + &errortypes.BidderTemporarilyDisabled{Message: ("The bidder 'disabledbidder' has been disabled.")}, + errors.New("request.imp[0].ext.prebid.bidder must contain at least one bidder"), + }, }, { description: "Unknown Bidder + Disabled Prebid Ext Bidder", impExt: json.RawMessage(`{"unknownbidder":{"placement_id":555},"prebid":{"bidder":{"disabledbidder":{"foo":"bar"}}}}`), expectedImpExt: `{"unknownbidder":{"placement_id":555},"prebid":{"bidder":{"disabledbidder":{"foo":"bar"}}}}`, - expectedErrs: []error{errors.New("request.imp[0].ext.prebid.bidder contains unknown bidder: unknownbidder. Did you forget an alias in request.ext.prebid.aliases?")}, + expectedErrs: []error{&errortypes.BidderTemporarilyDisabled{Message: ("The bidder 'disabledbidder' has been disabled.")}, + errors.New("request.imp[0].ext.prebid.bidder must contain at least one bidder"), + }, }, }, }, @@ -140,6 +154,15 @@ func TestValidateImpExt(t *testing.T) { expectedImpExt: `{"prebid":{"bidder":{"appnexus":{"placement_id":555}}}}`, expectedErrs: []error{}, }, + { + // Since prebid.bidder object is present - bidders expected to be within it + // So even though appnexus is a valid bidder - it is ignored and considered to be an arbitrary field + // If there was no prebid.bidder then appnexus would have been considered a bidder. + description: "Valid bidder root ext + Empty Prebid Bidder", + impExt: json.RawMessage(`{"prebid":{"bidder":{}}, "appnexus":{"placement_id":555}}`), + expectedImpExt: `{"prebid":{"bidder":{}}, "appnexus":{"placement_id":555}}`, + expectedErrs: []error{errors.New("request.imp[0].ext.prebid.bidder must contain at least one bidder")}, + }, { description: "Valid bidder in prebid field", impExt: json.RawMessage(`{"prebid":{"bidder":{"appnexus":{"placement_id":555}}}}`), @@ -161,8 +184,8 @@ func TestValidateImpExt(t *testing.T) { { description: "Valid Bidder + Unknown Bidder", impExt: json.RawMessage(`{"appnexus":{"placement_id":555},"unknownbidder":{"placement_id":555}}`), - expectedImpExt: `{"appnexus":{"placement_id":555},"unknownbidder":{"placement_id":555}}`, - expectedErrs: []error{errors.New("request.imp[0].ext.prebid.bidder contains unknown bidder: unknownbidder. Did you forget an alias in request.ext.prebid.aliases?")}, + expectedImpExt: `{"prebid":{"bidder":{"appnexus":{"placement_id":555}}}, "unknownbidder":{"placement_id":555}}`, + expectedErrs: []error{&errortypes.Warning{Message: ("request.imp[0].ext contains unknown bidder: 'unknownbidder', ignoring")}}, }, { description: "Valid Bidder + Disabled Bidder", @@ -179,15 +202,23 @@ func TestValidateImpExt(t *testing.T) { { description: "Valid Bidder + Disabled Bidder + Unknown Bidder + First Party Data Context", impExt: json.RawMessage(`{"appnexus":{"placement_id":555},"disabledbidder":{"foo":"bar"},"unknownbidder":{"placement_id":555},"context":{"data":{"keywords":"prebid server example"}}}`), - expectedImpExt: `{"appnexus":{"placement_id":555},"disabledbidder":{"foo":"bar"},"unknownbidder":{"placement_id":555},"context":{"data":{"keywords":"prebid server example"}}}`, - expectedErrs: []error{errors.New("request.imp[0].ext.prebid.bidder contains unknown bidder: unknownbidder. Did you forget an alias in request.ext.prebid.aliases?")}, + expectedImpExt: `{"prebid":{"bidder":{"appnexus":{"placement_id":555}}}, "unknownbidder":{"placement_id":555},"context":{"data":{"keywords":"prebid server example"}}}`, + expectedErrs: []error{&errortypes.Warning{Message: ("request.imp[0].ext contains unknown bidder: 'unknownbidder', ignoring")}, + &errortypes.BidderTemporarilyDisabled{Message: "The bidder 'disabledbidder' has been disabled."}, + }, }, { - description: "Valid Prebid Ext Bidder + Disabled Bidder Ext", + description: "Valid Prebid Ext Bidder + Disabled Prebid Bidder Ext", impExt: json.RawMessage(`{"prebid":{"bidder":{"appnexus":{"placement_id":555},"disabledbidder":{"foo":"bar"}}}}`), expectedImpExt: `{"prebid":{"bidder":{"appnexus":{"placement_id": 555}}}}`, expectedErrs: []error{&errortypes.BidderTemporarilyDisabled{Message: "The bidder 'disabledbidder' has been disabled."}}, }, + { + description: "Valid Prebid Ext Bidder + Arbitrary Key Ext", + impExt: json.RawMessage(`{"prebid":{"bidder":{"appnexus":{"placement_id": 555}}},"arbitraryKey":{"placement_id":555}}`), + expectedImpExt: `{"prebid":{"bidder":{"appnexus":{"placement_id": 555}}},"arbitraryKey":{"placement_id":555}}`, + expectedErrs: []error{}, + }, { description: "Valid Prebid Ext Bidder + Disabled Ext Bidder + First Party Data Context", impExt: json.RawMessage(`{"prebid":{"bidder":{"appnexus":{"placement_id":555},"disabledbidder":{"foo":"bar"}}},"context":{"data":{"keywords":"prebid server example"}}}`), @@ -195,7 +226,7 @@ func TestValidateImpExt(t *testing.T) { expectedErrs: []error{&errortypes.BidderTemporarilyDisabled{Message: "The bidder 'disabledbidder' has been disabled."}}, }, { - description: "Valid Prebid Ext Bidder + Disabled Ext Bidder + Unknown Ext + First Party Data Context", + description: "Valid Prebid Ext Bidder + Disabled Prebid Ext Bidder + Unknown Prebid Ext + First Party Data Context", impExt: json.RawMessage(`{"prebid":{"bidder":{"appnexus":{"placement_id":555},"disabledbidder":{"foo":"bar"},"unknownbidder":{"placement_id":555}}},"context":{"data":{"keywords":"prebid server example"}}}`), expectedImpExt: `{"prebid":{"bidder":{"appnexus":{"placement_id":555},"disabledbidder":{"foo":"bar"},"unknownbidder":{"placement_id":555}}},"context":{"data":{"keywords":"prebid server example"}}}`, expectedErrs: []error{errors.New("request.imp[0].ext.prebid.bidder contains unknown bidder: unknownbidder. Did you forget an alias in request.ext.prebid.aliases?")}, @@ -252,7 +283,7 @@ func TestValidateImpExt(t *testing.T) { } else { assert.Empty(t, imp.Ext, "imp.ext expected to be empty but was: %s. Test: %s. %s\n", string(imp.Ext), group.description, test.description) } - assert.Equal(t, test.expectedErrs, errs, "errs slice does not match expected. Test: %s. %s\n", group.description, test.description) + assert.ElementsMatch(t, test.expectedErrs, errs, "errs slice does not match expected. Test: %s. %s\n", group.description, test.description) }) } }