Repository: prebid/prebid-server
Pull request #3197 (2023-10-10 00:14:28)

Adapter Name Case Insensitive: Stored Bid Responses
To support case insensitive bidder names in stored bid responses we need to remember that it is possible to specify `req.imp[].ext` like this:
```json
"ext": {
                "APPnexus": {
                    "placementId": 12883451
                },
                "aPPnexuS": {
                    "placementId": 12883451
                },
}
```
For request with one imp and ext like this(without stored bid responses), "appnexus" code will be executed twice and 2 http calls will be added to debug info: 
```json
  "ext": {
        "debug": {
            "httpcalls": {
                "APPnexus": [ ... ],
                "aPPnexuS": [ ... ]
            }
        }
}
``` 
Stored bid responses should support this case. Because bidder name in stored bid responses should be case insensitive, then we can specify "appnexus" only one time in "storedbidresponse" and same bid response config will be applied for both   "APPnexus" and "aPPnexuS":
```json
"prebid": {
                 
                    "storedbidresponse": [
                        {
                            "bidder": "appnexus",
                            "id": "some_id"
                        }
                    ]
}
```
In order to handle this case properly, we need to keep track of bidder names specified in imp.ext. 
Http calls also have bidder names in the same casing specified in imp.ext, same as it works with imps without stored responses


Patch:
diff --git a/adapters/definemedia/definemedia.go b/adapters/definemedia/definemedia.go
new file mode 100644
index 00000000..3e014e3c
--- /dev/null
+++ b/adapters/definemedia/definemedia.go
@@ -0,0 +1,109 @@
+package definemedia
+
+import (
+	"encoding/json"
+	"fmt"
+	"net/http"
+
+	"github.com/prebid/openrtb/v19/openrtb2"
+	"github.com/prebid/prebid-server/adapters"
+	"github.com/prebid/prebid-server/config"
+	"github.com/prebid/prebid-server/errortypes"
+	"github.com/prebid/prebid-server/openrtb_ext"
+)
+
+type adapter struct {
+	endpoint string
+}
+
+// Builder builds a new instance of the Foo adapter for the given bidder with the given config.
+func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) {
+	bidder := &adapter{
+		endpoint: config.Endpoint,
+	}
+	return bidder, nil
+}
+
+// MakeRequests makes the HTTP requests which should be made to fetch bids.
+func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
+	var errors []error
+	requestJSON, err := json.Marshal(request)
+	if err != nil {
+		errors = append(errors, err)
+		return nil, errors
+	}
+
+	requestData := &adapters.RequestData{
+		Method: "POST",
+		Uri:    a.endpoint,
+		Body:   requestJSON,
+	}
+
+	return []*adapters.RequestData{requestData}, errors
+
+}
+
+func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) {
+	if response.StatusCode == http.StatusNoContent {
+		return nil, nil
+	}
+
+	if response.StatusCode == http.StatusBadRequest {
+		return nil, []error{&errortypes.BadInput{
+			Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode),
+		}}
+	}
+
+	if response.StatusCode != http.StatusOK {
+		return nil, []error{&errortypes.BadServerResponse{
+			Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode),
+		}}
+	}
+
+	var bidResp openrtb2.BidResponse
+	if err := json.Unmarshal(response.Body, &bidResp); err != nil {
+		return nil, []error{err}
+	}
+
+	bidsCapacity := 1
+	if len(bidResp.SeatBid) > 0 {
+		bidsCapacity = len(bidResp.SeatBid[0].Bid)
+	}
+	bidResponse := adapters.NewBidderResponseWithBidsCapacity(bidsCapacity)
+	var errors []error
+	for _, sb := range bidResp.SeatBid {
+		for i, bid := range sb.Bid {
+			bidType, err := getMediaTypeForBid(bid)
+			if err != nil {
+				errors = append(errors, err)
+				continue
+			}
+			bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{
+				Bid:     &sb.Bid[i],
+				BidType: bidType,
+			})
+
+		}
+	}
+
+	return bidResponse, errors
+}
+
+func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) {
+	if bid.Ext != nil {
+		var bidExt openrtb_ext.ExtBid
+		err := json.Unmarshal(bid.Ext, &bidExt)
+		if err == nil && bidExt.Prebid != nil {
+			if (bidExt.Prebid.Type == openrtb_ext.BidTypeBanner) || (bidExt.Prebid.Type == openrtb_ext.BidTypeNative) {
+				return openrtb_ext.ParseBidType(string(bidExt.Prebid.Type))
+			}
+			return "", &errortypes.BadServerResponse{
+				Message: fmt.Sprintf("Invalid mediatype in the impression"),
+			}
+		}
+	}
+
+	return "", &errortypes.BadServerResponse{
+		Message: fmt.Sprintf("Failed to parse impression \"%s\" mediatype", bid.ImpID),
+	}
+}
diff --git a/endpoints/openrtb2/amp_auction.go b/endpoints/openrtb2/amp_auction.go
index 76b0e83c..099f5d66 100644
--- a/endpoints/openrtb2/amp_auction.go
+++ b/endpoints/openrtb2/amp_auction.go
@@ -530,7 +530,7 @@ func (deps *endpointDeps) loadRequestJSONForAmp(httpRequest *http.Request) (req
 		return
 	}
 
-	storedAuctionResponses, storedBidResponses, bidderImpReplaceImp, errs = stored_responses.ProcessStoredResponses(ctx, requestJSON, deps.storedRespFetcher, deps.bidderMap)
+	storedAuctionResponses, storedBidResponses, bidderImpReplaceImp, errs = stored_responses.ProcessStoredResponses(ctx, &openrtb_ext.RequestWrapper{BidRequest: req}, deps.storedRespFetcher)
 	if err != nil {
 		errs = []error{err}
 		return
diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go
index 2cad7a24..e6c9fe1f 100644
--- a/endpoints/openrtb2/auction.go
+++ b/endpoints/openrtb2/auction.go
@@ -517,12 +517,6 @@ func (deps *endpointDeps) parseRequest(httpRequest *http.Request, labels *metric
 		return
 	}
 
-	//Stored auction responses should be processed after stored requests due to possible impression modification
-	storedAuctionResponses, storedBidResponses, bidderImpReplaceImpId, errs = stored_responses.ProcessStoredResponses(ctx, requestJson, deps.storedRespFetcher, deps.bidderMap)
-	if len(errs) > 0 {
-		return nil, nil, nil, nil, nil, nil, errs
-	}
-
 	if err := jsonutil.UnmarshalValid(requestJson, req.BidRequest); err != nil {
 		errs = []error{err}
 		return
@@ -548,6 +542,12 @@ func (deps *endpointDeps) parseRequest(httpRequest *http.Request, labels *metric
 
 	lmt.ModifyForIOS(req.BidRequest)
 
+	//Stored auction responses should be processed after stored requests due to possible impression modification
+	storedAuctionResponses, storedBidResponses, bidderImpReplaceImpId, errs = stored_responses.ProcessStoredResponses(ctx, req, deps.storedRespFetcher)
+	if len(errs) > 0 {
+		return nil, nil, nil, nil, nil, nil, errs
+	}
+
 	hasStoredResponses := len(storedAuctionResponses) > 0
 	errL := deps.validateRequest(req, false, hasStoredResponses, storedBidResponses, hasStoredBidRequest)
 	if len(errL) > 0 {
@@ -1532,10 +1532,8 @@ func (deps *endpointDeps) validateImpExt(imp *openrtb_ext.ImpWrapper, aliases ma
 		return []error{fmt.Errorf("request validation failed. The StoredAuctionResponse.ID field must be completely present with, or completely absent from, all impressions in request. No StoredAuctionResponse data found for request.imp[%d].ext.prebid \n", impIndex)}
 	}
 
-	if len(storedBidResp) > 0 {
-		if err := validateStoredBidRespAndImpExtBidders(prebid.Bidder, storedBidResp, imp.ID); err != nil {
-			return []error{err}
-		}
+	if err := deps.validateStoredBidRespAndImpExtBidders(prebid, storedBidResp, imp.ID); err != nil {
+		return []error{err}
 	}
 
 	errL := []error{}
@@ -2502,19 +2500,24 @@ func checkIfAppRequest(request []byte) (bool, error) {
 	return false, nil
 }
 
-func validateStoredBidRespAndImpExtBidders(bidderExts map[string]json.RawMessage, storedBidResp stored_responses.ImpBidderStoredResp, impId string) error {
+func (deps *endpointDeps) validateStoredBidRespAndImpExtBidders(prebid *openrtb_ext.ExtImpPrebid, storedBidResp stored_responses.ImpBidderStoredResp, impId string) error {
+	if storedBidResp == nil && len(prebid.StoredBidResponse) == 0 {
+		return nil
+	}
+
+	if storedBidResp == nil {
+		return generateStoredBidResponseValidationError(impId)
+	}
 	if bidResponses, ok := storedBidResp[impId]; ok {
-		if len(bidResponses) != len(bidderExts) {
+		if len(bidResponses) != len(prebid.Bidder) {
 			return generateStoredBidResponseValidationError(impId)
 		}
 
 		for bidderName := range bidResponses {
-			bidder := bidderName
-			normalizedCoreBidder, ok := openrtb_ext.NormalizeBidderName(bidder)
-			if ok {
-				bidder = normalizedCoreBidder.String()
+			if _, bidderNameOk := deps.normalizeBidderName(bidderName); !bidderNameOk {
+				return fmt.Errorf(`unrecognized bidder "%v"`, bidderName)
 			}
-			if _, present := bidderExts[bidder]; !present {
+			if _, present := prebid.Bidder[bidderName]; !present {
 				return generateStoredBidResponseValidationError(impId)
 			}
 		}
diff --git a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/imp-with-stored-bid-resp-case-matching-bidder-name.json b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/imp-with-stored-bid-resp-case-matching-bidder-name.json
new file mode 100644
index 00000000..49576023
--- /dev/null
+++ b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/imp-with-stored-bid-resp-case-matching-bidder-name.json
@@ -0,0 +1,39 @@
+{
+  "description": "request with impression with stored bid response with case matching bidder name",
+  "mockBidRequest": {
+    "id": "request-with-stored-resp",
+    "site": {
+      "page": "test.somepage.com"
+    },
+    "imp": [
+      {
+        "id": "imp-id3",
+        "banner": {
+          "format": [
+            {
+              "w": 300,
+              "h": 600
+            }
+          ]
+        },
+        "ext": {
+          "appnexus": {
+            "placementId": 12883451
+          },
+          "prebid": {
+            "storedbidresponse": [
+              {
+                "bidder": "appnexus",
+                "id": "bidResponseId3"
+              }
+            ]
+          }
+        }
+      }
+    ],
+    "user": {
+      "yob": 1989
+    }
+  },
+  "expectedReturnCode": 200
+}
\ No newline at end of file
diff --git a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/imp-with-stored-bid-resp-insensitive-bidder-name.json b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/imp-with-stored-bid-resp-case-not-matching-bidder-name.json
similarity index 94%
rename from endpoints/openrtb2/sample-requests/valid-whole/supplementary/imp-with-stored-bid-resp-insensitive-bidder-name.json
rename to endpoints/openrtb2/sample-requests/valid-whole/supplementary/imp-with-stored-bid-resp-case-not-matching-bidder-name.json
index e7b688d4..bcebe814 100644
--- a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/imp-with-stored-bid-resp-insensitive-bidder-name.json
+++ b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/imp-with-stored-bid-resp-case-not-matching-bidder-name.json
@@ -1,5 +1,5 @@
 {
-  "description": "request with impression with stored bid response with sensitive bidder name",
+  "description": "request with impression with stored bid response with case not matching bidder name",
   "mockBidRequest": {
     "id": "request-with-stored-resp",
     "site": {
diff --git a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/imp-with-stored-bid-resp-non-existing-bidder-name.json b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/imp-with-stored-bid-resp-non-existing-bidder-name.json
new file mode 100644
index 00000000..d8685307
--- /dev/null
+++ b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/imp-with-stored-bid-resp-non-existing-bidder-name.json
@@ -0,0 +1,34 @@
+{
+  "description": "request with impression with stored bid response",
+  "mockBidRequest": {
+    "id": "request-with-stored-resp",
+    "site": {
+      "page": "test.somepage.com"
+    },
+    "imp": [
+      {
+        "id": "imp-id1",
+        "banner": {
+          "format": [
+            {
+              "w": 300,
+              "h": 600
+            }
+          ]
+        },
+        "ext": {
+          "bidderABC": {},
+          "prebid": {
+            "storedbidresponse": [
+              {"bidder":"bidderABC", "id": "bidResponseId1"}
+            ]
+          }
+        }
+      }
+    ],
+    "user": {
+      "yob": 1989
+    }
+  },
+  "expectedReturnCode": 200
+}
diff --git a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/imp-with-stored-bid-resp.json b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/imp-with-stored-bid-resp.json
index e72cce49..692a34c4 100644
--- a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/imp-with-stored-bid-resp.json
+++ b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/imp-with-stored-bid-resp.json
@@ -17,12 +17,10 @@
           ]
         },
         "ext": {
-          "appnexus": {
-            "placementId": 12883451
-          },
+          "telaria": {},
           "prebid": {
             "storedbidresponse": [
-              {"bidder":"testBidder1", "id": "bidResponseId1"}
+              {"bidder":"telaria", "id": "bidResponseId1"}
             ]
           }
         }
diff --git a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/req-two-imps-stored-bid-responses.json b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/req-two-imps-stored-bid-responses.json
index 5906eb91..09b4bc57 100644
--- a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/req-two-imps-stored-bid-responses.json
+++ b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/req-two-imps-stored-bid-responses.json
@@ -17,12 +17,12 @@
           ]
         },
         "ext": {
-          "appnexus": {
+          "telaria": {
             "placementId": 12883451
           },
           "prebid": {
             "storedbidresponse": [
-              {"bidder":"testBidder1", "id": "bidResponseId1"}
+              {"bidder":"telaria", "id": "bidResponseId1"}
             ]
           }
         }
@@ -38,12 +38,10 @@
           ]
         },
         "ext": {
-          "appnexus": {
-            "placementId": 12883451
-          },
+          "amx": {},
           "prebid": {
             "storedbidresponse": [
-              {"bidder":"testBidder2", "id": "bidResponseId2"}
+              {"bidder":"amx", "id": "bidResponseId2"}
             ]
           }
         }
diff --git a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/req-two-imps-with-and-without-stored-bid-responses.json b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/req-two-imps-with-and-without-stored-bid-responses.json
index 6122e4df..5387a9d6 100644
--- a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/req-two-imps-with-and-without-stored-bid-responses.json
+++ b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/req-two-imps-with-and-without-stored-bid-responses.json
@@ -33,12 +33,12 @@
           ]
         },
         "ext": {
-          "appnexus": {
+          "amx": {
             "placementId": 12883451
           },
           "prebid": {
             "storedbidresponse": [
-              {"bidder":"testBidder2", "id": "bidResponseId2"}
+              {"bidder":"amx", "id": "bidResponseId2"}
             ]
           }
         }
diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go
index 6ab0dccf..fd1a99ae 100755
--- a/exchange/adapter_builders.go
+++ b/exchange/adapter_builders.go
@@ -71,6 +71,7 @@ import (
 	"github.com/prebid/prebid-server/adapters/datablocks"
 	"github.com/prebid/prebid-server/adapters/decenterads"
 	"github.com/prebid/prebid-server/adapters/deepintent"
+	"github.com/prebid/prebid-server/adapters/definemedia"
 	"github.com/prebid/prebid-server/adapters/dianomi"
 	"github.com/prebid/prebid-server/adapters/dmx"
 	"github.com/prebid/prebid-server/adapters/dxkulture"
@@ -264,6 +265,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder {
 		openrtb_ext.BidderDatablocks:        datablocks.Builder,
 		openrtb_ext.BidderDecenterAds:       decenterads.Builder,
 		openrtb_ext.BidderDeepintent:        deepintent.Builder,
+		openrtb_ext.BidderDefinemedia:       definemedia.Builder,
 		openrtb_ext.BidderDianomi:           dianomi.Builder,
 		openrtb_ext.BidderEdge226:           edge226.Builder,
 		openrtb_ext.BidderDmx:               dmx.Builder,
diff --git a/exchange/adapter_util.go b/exchange/adapter_util.go
index a5a232bb..89d58d06 100644
--- a/exchange/adapter_util.go
+++ b/exchange/adapter_util.go
@@ -117,7 +117,6 @@ func GetDisabledBidderWarningMessages(infos config.BidderInfos) map[string]strin
 		"engagebdr":       `Bidder "engagebdr" is no longer available in Prebid Server. Please update your configuration.`,
 		"ninthdecimal":    `Bidder "ninthdecimal" is no longer available in Prebid Server. Please update your configuration.`,
 		"kubient":         `Bidder "kubient" is no longer available in Prebid Server. Please update your configuration.`,
-		"definemedia":     `Bidder "definemedia" is no longer available in Prebid Server. Please update your configuration.`,
 		"applogy":         `Bidder "applogy" is no longer available in Prebid Server. Please update your configuration.`,
 		"rhythmone":       `Bidder "rhythmone" is no longer available in Prebid Server. Please update your configuration.`,
 		"nanointeractive": `Bidder "nanointeractive" is no longer available in Prebid Server. Please update your configuration.`,
diff --git a/exchange/utils.go b/exchange/utils.go
index c7acfaef..ea6b317d 100644
--- a/exchange/utils.go
+++ b/exchange/utils.go
@@ -958,7 +958,7 @@ func buildBidResponseRequest(req *openrtb2.BidRequest,
 			BidderCoreName:        resolvedBidder,
 			BidderName:            bidderName,
 			BidderStoredResponses: impResps,
-			ImpReplaceImpId:       bidderImpReplaceImpID[string(resolvedBidder)],
+			ImpReplaceImpId:       bidderImpReplaceImpID[string(bidderName)],
 			IsRequestAlias:        isRequestAlias,
 			BidderLabels:          metrics.AdapterLabels{Adapter: resolvedBidder},
 		}
diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go
index 22a915b7..fbd5bb9f 100644
--- a/openrtb_ext/bidders.go
+++ b/openrtb_ext/bidders.go
@@ -87,6 +87,7 @@ var coreBidderNames []BidderName = []BidderName{
 	BidderDatablocks,
 	BidderDecenterAds,
 	BidderDeepintent,
+	BidderDefinemedia,
 	BidderDianomi,
 	BidderEdge226,
 	BidderDmx,
@@ -368,6 +369,7 @@ const (
 	BidderDatablocks        BidderName = "datablocks"
 	BidderDecenterAds       BidderName = "decenterads"
 	BidderDeepintent        BidderName = "deepintent"
+	BidderDefinemedia       BidderName = "definemedia"
 	BidderDianomi           BidderName = "dianomi"
 	BidderEdge226           BidderName = "edge226"
 	BidderDmx               BidderName = "dmx"
diff --git a/openrtb_ext/imp_definemedia.go b/openrtb_ext/imp_definemedia.go
new file mode 100644
index 00000000..aa94bf5d
--- /dev/null
+++ b/openrtb_ext/imp_definemedia.go
@@ -0,0 +1,6 @@
+package openrtb_ext
+
+type ImpExtDefinemedia struct {
+	MandantID int64 `json:"mandantId"`
+	AdslotID  int64 `json:"adslotId"`
+}
diff --git a/static/bidder-info/adform.yaml b/static/bidder-info/adform.yaml
index 4aa6e70f..2ad89278 100644
--- a/static/bidder-info/adform.yaml
+++ b/static/bidder-info/adform.yaml
@@ -1,1 +1,5 @@
 aliasOf: adf
+userSync:
+  redirect:
+    url: "https://cm.adform.net/cookie?redirect_url={{.RedirectURL}}"
+    userMacro: "$UID"
diff --git a/static/bidder-info/definemedia.yaml b/static/bidder-info/definemedia.yaml
new file mode 100644
index 00000000..a7be6fb9
--- /dev/null
+++ b/static/bidder-info/definemedia.yaml
@@ -0,0 +1,10 @@
+endpoint: "https://rtb.conative.network/openrtb2/auction"
+maintainer:
+  email: "development@definemedia.de"
+  gvlVendorID: 440  # GDPR vendor list ID
+capabilities:
+
+  site:
+    mediaTypes:
+      - banner
+      - native
diff --git a/static/bidder-info/quantumdex.yaml b/static/bidder-info/quantumdex.yaml
index 32043ad6..fae2a987 100644
--- a/static/bidder-info/quantumdex.yaml
+++ b/static/bidder-info/quantumdex.yaml
@@ -1,1 +1,8 @@
-aliasOf: "apacdex"
\ No newline at end of file
+aliasOf: "apacdex"
+userSync:
+  iframe:
+    url: https://sync.quantumdex.io/usersync/pbs?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r={{.RedirectURL}}
+    userMacro: "[UID]"
+  redirect:
+    url: "https://sync.quantumdex.io/getuid?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r={{.RedirectURL}}"
+    userMacro: "[UID]"
diff --git a/static/bidder-info/valueimpression.yaml b/static/bidder-info/valueimpression.yaml
index 32043ad6..fae2a987 100644
--- a/static/bidder-info/valueimpression.yaml
+++ b/static/bidder-info/valueimpression.yaml
@@ -1,1 +1,8 @@
-aliasOf: "apacdex"
\ No newline at end of file
+aliasOf: "apacdex"
+userSync:
+  iframe:
+    url: https://sync.quantumdex.io/usersync/pbs?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r={{.RedirectURL}}
+    userMacro: "[UID]"
+  redirect:
+    url: "https://sync.quantumdex.io/getuid?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&r={{.RedirectURL}}"
+    userMacro: "[UID]"
diff --git a/static/bidder-params/definemedia.json b/static/bidder-params/definemedia.json
new file mode 100644
index 00000000..bf5566b4
--- /dev/null
+++ b/static/bidder-params/definemedia.json
@@ -0,0 +1,19 @@
+{
+    "$schema": "http://json-schema.org/draft-04/schema#",
+    "title": "Define Media Adapter Params",
+    "description": "A schema which validates params accepted by the DM adapter",
+    "type": "object",
+  
+    "properties": {
+      "mandantId": {
+        "type": "integer",
+        "description": "The DEFINE-MEDIA mandant id. This is a unique identifier for your account. Please contact your account manager for more information."
+      },
+
+      "adslotId":{
+        "type": "integer",
+        "description": "The adslot id. This is a unique identifier for your adslot and may change on subparts on a website. Please contact your account manager for more information."
+      }
+    },
+    "required": ["mandantId"]
+  }
\ No newline at end of file
diff --git a/stored_responses/stored_responses.go b/stored_responses/stored_responses.go
index ef8fe506..d6944a6f 100644
--- a/stored_responses/stored_responses.go
+++ b/stored_responses/stored_responses.go
@@ -4,12 +4,11 @@ import (
 	"context"
 	"encoding/json"
 	"fmt"
+	"strings"
 
-	"github.com/buger/jsonparser"
 	"github.com/prebid/openrtb/v19/openrtb2"
 	"github.com/prebid/prebid-server/openrtb_ext"
 	"github.com/prebid/prebid-server/stored_requests"
-	"github.com/prebid/prebid-server/util/jsonutil"
 )
 
 type ImpsWithAuctionResponseIDs map[string]string
@@ -57,8 +56,7 @@ func buildStoredResp(storedBidResponses ImpBidderStoredResp) BidderImpsWithBidRe
 	return bidderToImpToResponses
 }
 
-func extractStoredResponsesIds(impInfo []ImpExtPrebidData,
-	bidderMap map[string]openrtb_ext.BidderName) (
+func extractStoredResponsesIds(impInfo []*openrtb_ext.ImpWrapper) (
 	StoredResponseIDs,
 	ImpBiddersWithBidResponseIDs,
 	ImpsWithAuctionResponseIDs,
@@ -76,53 +74,62 @@ func extractStoredResponsesIds(impInfo []ImpExtPrebidData,
 	impBidderReplaceImp := ImpBidderReplaceImpID{}
 
 	for index, impData := range impInfo {
-		impId, err := jsonparser.GetString(impData.Imp, "id")
+		impId := impData.ID
+		impExt, err := impData.GetImpExt()
 		if err != nil {
-			return nil, nil, nil, nil, fmt.Errorf("request.imp[%d] missing required field: \"id\"", index)
+			return nil, nil, nil, nil, err
+		}
+		impExtPrebid := impExt.GetPrebid()
+		if impExtPrebid == nil {
+			continue
 		}
 
-		if impData.ImpExtPrebid.StoredAuctionResponse != nil {
-			if len(impData.ImpExtPrebid.StoredAuctionResponse.ID) == 0 {
+		if impExtPrebid.StoredAuctionResponse != nil {
+			if len(impExtPrebid.StoredAuctionResponse.ID) == 0 {
 				return nil, nil, nil, nil, fmt.Errorf("request.imp[%d] has ext.prebid.storedauctionresponse specified, but \"id\" field is missing ", index)
 			}
-			allStoredResponseIDs = append(allStoredResponseIDs, impData.ImpExtPrebid.StoredAuctionResponse.ID)
+			allStoredResponseIDs = append(allStoredResponseIDs, impExtPrebid.StoredAuctionResponse.ID)
 
-			impAuctionResponseIDs[impId] = impData.ImpExtPrebid.StoredAuctionResponse.ID
+			impAuctionResponseIDs[impId] = impExtPrebid.StoredAuctionResponse.ID
 
 		}
-		if len(impData.ImpExtPrebid.StoredBidResponse) > 0 {
+		if len(impExtPrebid.StoredBidResponse) > 0 {
+
+			// bidders can be specified in imp.ext and in imp.ext.prebid.bidders
+			allBidderNames := make([]string, 0)
+			for bidderName := range impExtPrebid.Bidder {
+				allBidderNames = append(allBidderNames, bidderName)
+			}
+			for extData := range impExt.GetExt() {
+				// no bidders will not be processed
+				allBidderNames = append(allBidderNames, extData)
+			}
 
 			bidderStoredRespId := make(map[string]string)
 			bidderReplaceImpId := make(map[string]bool)
-			for _, bidderResp := range impData.ImpExtPrebid.StoredBidResponse {
+			for _, bidderResp := range impExtPrebid.StoredBidResponse {
 				if len(bidderResp.ID) == 0 || len(bidderResp.Bidder) == 0 {
 					return nil, nil, nil, nil, fmt.Errorf("request.imp[%d] has ext.prebid.storedbidresponse specified, but \"id\" or/and \"bidder\" fields are missing ", index)
 				}
-				bidderName := bidderResp.Bidder
-				normalizedCoreBidder, ok := openrtb_ext.NormalizeBidderName(bidderResp.Bidder)
-				if ok {
-					bidderName = normalizedCoreBidder.String()
-				}
-				//check if bidder is valid/exists
-				if _, isValid := bidderMap[bidderName]; !isValid {
-					return nil, nil, nil, nil, fmt.Errorf("request.imp[impId: %s].ext.prebid.bidder contains unknown bidder: %s. Did you forget an alias in request.ext.prebid.aliases?", impId, bidderResp.Bidder)
-				}
-				// bidder is unique per one bid stored response
-				// if more than one bidder specified the last defined bidder id will take precedence
-				bidderStoredRespId[bidderResp.Bidder] = bidderResp.ID
-				impBiddersWithBidResponseIDs[impId] = bidderStoredRespId
-
-				// stored response config can specify if imp id should be replaced with imp id from request
-				replaceImpId := true
-				if bidderResp.ReplaceImpId != nil {
-					// replaceimpid is true if not specified
-					replaceImpId = *bidderResp.ReplaceImpId
-				}
-				bidderReplaceImpId[bidderResp.Bidder] = replaceImpId
-				impBidderReplaceImp[impId] = bidderReplaceImpId
 
-				//storedAuctionResponseIds are not unique, but fetch will return single data for repeated ids
-				allStoredResponseIDs = append(allStoredResponseIDs, bidderResp.ID)
+				for _, bidderName := range allBidderNames {
+					if _, found := bidderStoredRespId[bidderName]; !found && strings.EqualFold(bidderName, bidderResp.Bidder) {
+						bidderStoredRespId[bidderName] = bidderResp.ID
+						impBiddersWithBidResponseIDs[impId] = bidderStoredRespId
+
+						// stored response config can specify if imp id should be replaced with imp id from request
+						replaceImpId := true
+						if bidderResp.ReplaceImpId != nil {
+							// replaceimpid is true if not specified
+							replaceImpId = *bidderResp.ReplaceImpId
+						}
+						bidderReplaceImpId[bidderName] = replaceImpId
+						impBidderReplaceImp[impId] = bidderReplaceImpId
+
+						//storedAuctionResponseIds are not unique, but fetch will return single data for repeated ids
+						allStoredResponseIDs = append(allStoredResponseIDs, bidderResp.ID)
+					}
+				}
 			}
 		}
 	}
@@ -135,14 +142,11 @@ func extractStoredResponsesIds(impInfo []ImpExtPrebidData,
 // Note that processStoredResponses must be called after processStoredRequests
 // because stored imps and stored requests can contain stored auction responses and stored bid responses
 // so the stored requests/imps have to be merged into the incoming request prior to processing stored auction responses.
-func ProcessStoredResponses(ctx context.Context, requestJson []byte, storedRespFetcher stored_requests.Fetcher, bidderMap map[string]openrtb_ext.BidderName) (ImpsWithBidResponses, ImpBidderStoredResp, BidderImpReplaceImpID, []error) {
-	impInfo, errs := parseImpInfo(requestJson)
-	if len(errs) > 0 {
-		return nil, nil, nil, errs
-	}
-	storedResponsesIds, impBidderToStoredBidResponseId, impIdToRespId, impBidderReplaceImp, err := extractStoredResponsesIds(impInfo, bidderMap)
+func ProcessStoredResponses(ctx context.Context, requestWrapper *openrtb_ext.RequestWrapper, storedRespFetcher stored_requests.Fetcher) (ImpsWithBidResponses, ImpBidderStoredResp, BidderImpReplaceImpID, []error) {
+
+	storedResponsesIds, impBidderToStoredBidResponseId, impIdToRespId, impBidderReplaceImp, err := extractStoredResponsesIds(requestWrapper.GetImp())
 	if err != nil {
-		return nil, nil, nil, append(errs, err)
+		return nil, nil, nil, []error{err}
 	}
 
 	if len(storedResponsesIds) > 0 {
@@ -201,28 +205,3 @@ func buildStoredResponsesMaps(storedResponses StoredResponseIdToStoredResponse,
 	}
 	return impIdToStoredResp, impBidderToStoredBidResponse, errs
 }
-
-// parseImpInfo parses the request JSON and returns the impressions with their unmarshalled imp.ext.prebid
-// copied from exchange to isolate stored responses code from auction dependencies
-func parseImpInfo(requestJson []byte) (impData []ImpExtPrebidData, errs []error) {
-
-	if impArray, dataType, _, err := jsonparser.Get(requestJson, "imp"); err == nil && dataType == jsonparser.Array {
-		_, err = jsonparser.ArrayEach(impArray, func(imp []byte, _ jsonparser.ValueType, _ int, err error) {
-			impExtData, _, _, err := jsonparser.Get(imp, "ext", "prebid")
-			var impExtPrebid openrtb_ext.ExtImpPrebid
-			if impExtData != nil {
-				if err := jsonutil.Unmarshal(impExtData, &impExtPrebid); err != nil {
-					errs = append(errs, err)
-				}
-			}
-			newImpData := ImpExtPrebidData{imp, impExtPrebid}
-			impData = append(impData, newImpData)
-		})
-	}
-	return
-}
-
-type ImpExtPrebidData struct {
-	Imp          json.RawMessage
-	ImpExtPrebid openrtb_ext.ExtImpPrebid
-}


Test patch:
diff --git a/adapters/definemedia/definemedia_test.go b/adapters/definemedia/definemedia_test.go
new file mode 100644
index 00000000..3ed0cb93
--- /dev/null
+++ b/adapters/definemedia/definemedia_test.go
@@ -0,0 +1,21 @@
+package definemedia
+
+import (
+	"testing"
+
+	"github.com/prebid/prebid-server/adapters/adapterstest"
+	"github.com/prebid/prebid-server/config"
+	"github.com/prebid/prebid-server/openrtb_ext"
+)
+
+func TestJsonSamples(t *testing.T) {
+	bidder, buildErr := Builder(openrtb_ext.BidderDefinemedia, config.Adapter{
+		Endpoint: "https://rtb.conative.network/openrtb2/auction"},
+		config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"})
+
+	if buildErr != nil {
+		t.Fatalf("Builder returned unexpected error %v", buildErr)
+	}
+
+	adapterstest.RunJSONBidderTest(t, "definemediatest", bidder)
+}
diff --git a/adapters/definemedia/definemediatest/exemplary/sample-conative-banner.json b/adapters/definemedia/definemediatest/exemplary/sample-conative-banner.json
new file mode 100644
index 00000000..a7d7e411
--- /dev/null
+++ b/adapters/definemedia/definemediatest/exemplary/sample-conative-banner.json
@@ -0,0 +1,270 @@
+{
+  "mockBidRequest": {
+    "imp": [
+      {
+        "ext": {
+          "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9",
+          "prebid": {
+            "bidder": {
+              "definemedia": {
+                "mandantId": 12
+              }
+            }
+          }
+        },
+        "id": "div-gpt-ad-1460505748561-0",
+        "banner": {
+          "topframe": 1,
+          "format": [
+            {
+              "w": 300,
+              "h": 250
+            }
+          ]
+        }
+      }
+    ],
+    "site": {
+      "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true",
+      "domain": "localhost:8080",
+      "publisher": {
+        "domain": "localhost:8080",
+        "id": "1"
+      }
+    },
+    "device": {
+      "w": 1098,
+      "h": 1169,
+      "dnt": 0,
+      "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36",
+      "language": "de",
+      "sua": {
+        "source": 2,
+        "platform": {
+          "brand": "macOS",
+          "version": [
+            "12",
+            "3",
+            "1"
+          ]
+        },
+        "browsers": [
+          {
+            "brand": "Not?A_Brand",
+            "version": [
+              "8",
+              "0",
+              "0",
+              "0"
+            ]
+          },
+          {
+            "brand": "Chromium",
+            "version": [
+              "108",
+              "0",
+              "5359",
+              "124"
+            ]
+          },
+          {
+            "brand": "Google Chrome",
+            "version": [
+              "108",
+              "0",
+              "5359",
+              "124"
+            ]
+          }
+        ],
+        "mobile": 0,
+        "model": "",
+        "bitness": "64",
+        "architecture": "x86"
+      }
+    },
+    "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf",
+    "test": 0,
+    "source": {
+      "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf"
+    },
+    "ext": {
+      "prebid": {
+        "auctiontimestamp": 1671449004622,
+        "targeting": {
+          "includewinners": true,
+          "includebidderkeys": false
+        },
+        "debug": true,
+        "channel": {
+          "name": "pbjs",
+          "version": "v7.28.0"
+        }
+      }
+    },
+    "tmax": 1000
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://rtb.conative.network/openrtb2/auction",
+        "body": {
+          "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf",
+          "imp": [
+            {
+              "id": "div-gpt-ad-1460505748561-0",
+              "banner": {
+                "format": [
+                  {
+                    "w": 300,
+                    "h": 250
+                  }
+                ],
+                "topframe": 1
+              },
+              "ext": {
+                "prebid": {
+                  "bidder": {
+                    "definemedia": {
+                      "mandantId": 12
+                    }
+                  }
+                },
+                "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9"
+              }
+            }
+          ],
+          "site": {
+            "domain": "localhost:8080",
+            "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true",
+            "publisher": {
+              "id": "1",
+              "domain": "localhost:8080"
+            }
+          },
+          "device": {
+            "dnt": 0,
+            "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36",
+            "sua": {
+              "browsers": [
+                {
+                  "brand": "Not?A_Brand",
+                  "version": [
+                    "8",
+                    "0",
+                    "0",
+                    "0"
+                  ]
+                },
+                {
+                  "brand": "Chromium",
+                  "version": [
+                    "108",
+                    "0",
+                    "5359",
+                    "124"
+                  ]
+                },
+                {
+                  "brand": "Google Chrome",
+                  "version": [
+                    "108",
+                    "0",
+                    "5359",
+                    "124"
+                  ]
+                }
+              ],
+              "platform": {
+                "brand": "macOS",
+                "version": [
+                  "12",
+                  "3",
+                  "1"
+                ]
+              },
+              "mobile": 0,
+              "architecture": "x86",
+              "bitness": "64",
+              "source": 2
+            },
+            "h": 1169,
+            "w": 1098,
+            "language": "de"
+          },
+          "tmax": 1000,
+          "source": {
+            "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf"
+          },
+          "ext": {
+            "prebid": {
+              "auctiontimestamp": 1.671449004622e+12,
+              "channel": {
+                "name": "pbjs",
+                "version": "v7.28.0"
+              },
+              "debug": true,
+              "targeting": {
+                "includebidderkeys": false,
+                "includewinners": true
+              }
+            }
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "test-request-id",
+          "seatbid": [
+            {
+              "bid": [
+                {
+                  "id": "46189656-7e2e-477d-b7f2-e05de224bb89",
+                  "impid": "div-gpt-ad-1460505748561-0",
+                  "price": 100,
+                  "adm": "{banner html}",
+                  "adomain": [
+                    "test.com"
+                  ],
+                  "crid": "test-creative-id",
+                  "ext": {
+                    "prebid": {
+                      "type": "banner"
+                    }
+                  }
+                }
+              ]
+            }
+          ],
+          "cur": "USD"
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": [
+        {
+          "bid": {
+            "id": "46189656-7e2e-477d-b7f2-e05de224bb89",
+            "impid": "div-gpt-ad-1460505748561-0",
+            "price": 100,
+            "adm": "{banner html}",
+            "crid": "test-creative-id",
+            "adomain": [
+              "test.com"
+            ],
+            "ext": {
+              "prebid": {
+                "type": "banner"
+              }
+            }
+          },
+          "type": "banner"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/adapters/definemedia/definemediatest/exemplary/sample-conative-native.json b/adapters/definemedia/definemediatest/exemplary/sample-conative-native.json
new file mode 100644
index 00000000..4fe56a4c
--- /dev/null
+++ b/adapters/definemedia/definemediatest/exemplary/sample-conative-native.json
@@ -0,0 +1,257 @@
+{
+  "mockBidRequest": {
+    "imp": [
+      {
+        "ext": {
+          "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9",
+          "prebid": {
+            "bidder": {
+              "definemedia": {
+                "mandantId": 12
+              }
+            }
+          }
+        },
+        "id": "div-gpt-ad-1460505748561-0",
+        "native": {}
+      }
+    ],
+    "site": {
+      "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true",
+      "domain": "localhost:8080",
+      "publisher": {
+        "domain": "localhost:8080",
+        "id": "1"
+      }
+    },
+    "device": {
+      "w": 1098,
+      "h": 1169,
+      "dnt": 0,
+      "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36",
+      "language": "de",
+      "sua": {
+        "source": 2,
+        "platform": {
+          "brand": "macOS",
+          "version": [
+            "12",
+            "3",
+            "1"
+          ]
+        },
+        "browsers": [
+          {
+            "brand": "Not?A_Brand",
+            "version": [
+              "8",
+              "0",
+              "0",
+              "0"
+            ]
+          },
+          {
+            "brand": "Chromium",
+            "version": [
+              "108",
+              "0",
+              "5359",
+              "124"
+            ]
+          },
+          {
+            "brand": "Google Chrome",
+            "version": [
+              "108",
+              "0",
+              "5359",
+              "124"
+            ]
+          }
+        ],
+        "mobile": 0,
+        "model": "",
+        "bitness": "64",
+        "architecture": "x86"
+      }
+    },
+    "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf",
+    "test": 0,
+    "source": {
+      "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf"
+    },
+    "ext": {
+      "prebid": {
+        "auctiontimestamp": 1671449004622,
+        "targeting": {
+          "includewinners": true,
+          "includebidderkeys": false
+        },
+        "debug": true,
+        "channel": {
+          "name": "pbjs",
+          "version": "v7.28.0"
+        }
+      }
+    },
+    "tmax": 1000
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://rtb.conative.network/openrtb2/auction",
+        "body": {
+          "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf",
+          "imp": [
+            {
+              "id": "div-gpt-ad-1460505748561-0",
+              "native": {
+                "request": ""
+              },
+              "ext": {
+                "prebid": {
+                  "bidder": {
+                    "definemedia": {
+                      "mandantId": 12
+                    }
+                  }
+                },
+                "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9"
+              }
+            }
+          ],
+          "site": {
+            "domain": "localhost:8080",
+            "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true",
+            "publisher": {
+              "id": "1",
+              "domain": "localhost:8080"
+            }
+          },
+          "device": {
+            "dnt": 0,
+            "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36",
+            "sua": {
+              "browsers": [
+                {
+                  "brand": "Not?A_Brand",
+                  "version": [
+                    "8",
+                    "0",
+                    "0",
+                    "0"
+                  ]
+                },
+                {
+                  "brand": "Chromium",
+                  "version": [
+                    "108",
+                    "0",
+                    "5359",
+                    "124"
+                  ]
+                },
+                {
+                  "brand": "Google Chrome",
+                  "version": [
+                    "108",
+                    "0",
+                    "5359",
+                    "124"
+                  ]
+                }
+              ],
+              "platform": {
+                "brand": "macOS",
+                "version": [
+                  "12",
+                  "3",
+                  "1"
+                ]
+              },
+              "mobile": 0,
+              "architecture": "x86",
+              "bitness": "64",
+              "source": 2
+            },
+            "h": 1169,
+            "w": 1098,
+            "language": "de"
+          },
+          "tmax": 1000,
+          "source": {
+            "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf"
+          },
+          "ext": {
+            "prebid": {
+              "auctiontimestamp": 1.671449004622e+12,
+              "channel": {
+                "name": "pbjs",
+                "version": "v7.28.0"
+              },
+              "debug": true,
+              "targeting": {
+                "includebidderkeys": false,
+                "includewinners": true
+              }
+            }
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "test-request-id",
+          "seatbid": [
+            {
+              "bid": [
+                {
+                  "id": "46189656-7e2e-477d-b7f2-e05de224bb89",
+                  "impid": "div-gpt-ad-1460505748561-0",
+                  "price": 100,
+                  "adm": "{\n \"ver\": \"1.1\",\n \"imptrackers\": [\"http://imptracker.com\"],\n \"jstracker\": \"\u003cscript\u003etrack()\u003c/script\u003e\",\n \"link\": {\n  \"url\": \"http://i.am.a/URL\"\n },\n \"assets\": [\n  {\n   \"id\": 123,\n   \"required\": 1,\n   \"title\": {\n    \"text\": \"Learn about this awesome thing\"\n   }\n  },\n  {\n   \"id\": 124,\n   \"required\": 1,\n   \"img\": {\n    \"url\": \"http://www.myads.com/thumbnail1.png\"\n   }\n  },\n  {\n   \"id\": 128,\n   \"required\": 1,\n   \"img\": {\n    \"url\": \"http://www.myads.com/largethumb1.png\"\n   }\n  },\n  {\n   \"id\": 126,\n   \"required\": 1,\n   \"data\": {\n    \"value\": \"My Brand\"\n   }\n  },\n  {\n   \"id\": 127,\n   \"required\": 1,\n   \"data\": {\n    \"value\": \"Learn all about this awesome story of someone using my product.\"\n   }\n  },\n  {\n   \"id\": 4,\n   \"video\": {\n    \"vasttag\": \"\u003cVAST version=\\\"2.0\\\"\u003e\u003c/VAST\u003e\"\n   }\n  },\n  {\n   \"id\": 5,\n   \"link\": {\n    \"url\": \"http://landing.com\",\n    \"clicktrackers\": [\"http://tracker.com\"],\n    \"fallback\": \"http://fallback.com\"\n   }\n  }\n ]\n}",
+                  "adomain": [
+                    "test.com"
+                  ],
+                  "crid": "test-creative-id",
+                  "ext": {
+                    "prebid": {
+                      "type": "native"
+                    }
+                  }
+                }
+              ]
+            }
+          ],
+          "cur": "USD"
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": [
+        {
+          "bid": {
+            "id": "46189656-7e2e-477d-b7f2-e05de224bb89",
+            "impid": "div-gpt-ad-1460505748561-0",
+            "price": 100,
+
+            "adm": "{\n \"ver\": \"1.1\",\n \"imptrackers\": [\"http://imptracker.com\"],\n \"jstracker\": \"\u003cscript\u003etrack()\u003c/script\u003e\",\n \"link\": {\n  \"url\": \"http://i.am.a/URL\"\n },\n \"assets\": [\n  {\n   \"id\": 123,\n   \"required\": 1,\n   \"title\": {\n    \"text\": \"Learn about this awesome thing\"\n   }\n  },\n  {\n   \"id\": 124,\n   \"required\": 1,\n   \"img\": {\n    \"url\": \"http://www.myads.com/thumbnail1.png\"\n   }\n  },\n  {\n   \"id\": 128,\n   \"required\": 1,\n   \"img\": {\n    \"url\": \"http://www.myads.com/largethumb1.png\"\n   }\n  },\n  {\n   \"id\": 126,\n   \"required\": 1,\n   \"data\": {\n    \"value\": \"My Brand\"\n   }\n  },\n  {\n   \"id\": 127,\n   \"required\": 1,\n   \"data\": {\n    \"value\": \"Learn all about this awesome story of someone using my product.\"\n   }\n  },\n  {\n   \"id\": 4,\n   \"video\": {\n    \"vasttag\": \"\u003cVAST version=\\\"2.0\\\"\u003e\u003c/VAST\u003e\"\n   }\n  },\n  {\n   \"id\": 5,\n   \"link\": {\n    \"url\": \"http://landing.com\",\n    \"clicktrackers\": [\"http://tracker.com\"],\n    \"fallback\": \"http://fallback.com\"\n   }\n  }\n ]\n}",
+            "crid": "test-creative-id",
+            "adomain": [
+              "test.com"
+            ],
+            "ext": {
+              "prebid": {
+                "type": "native"
+              }
+            }
+          },
+          "type": "native"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/adapters/definemedia/definemediatest/supplemental/nobid-response.json b/adapters/definemedia/definemediatest/supplemental/nobid-response.json
new file mode 100644
index 00000000..aaa942da
--- /dev/null
+++ b/adapters/definemedia/definemediatest/supplemental/nobid-response.json
@@ -0,0 +1,222 @@
+{
+    "mockBidRequest": {
+      "imp": [
+        {
+          "ext": {
+            "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9",
+            "prebid": {
+              "bidder": {
+                "definemedia": {}
+              }
+            }
+          },
+          "id": "div-gpt-ad-1460505748561-0",
+          "banner": {
+            "topframe": 1,
+            "format": [
+              {
+                "w": 300,
+                "h": 250
+              }
+            ]
+          }
+        }
+      ],
+      "site": {
+        "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true",
+        "domain": "localhost:8080",
+        "publisher": {
+          "domain": "localhost:8080",
+          "id": "1"
+        }
+      },
+      "device": {
+        "w": 1098,
+        "h": 1169,
+        "dnt": 0,
+        "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36",
+        "language": "de",
+        "sua": {
+          "source": 2,
+          "platform": {
+            "brand": "macOS",
+            "version": [
+              "12",
+              "3",
+              "1"
+            ]
+          },
+          "browsers": [
+            {
+              "brand": "Not?A_Brand",
+              "version": [
+                "8",
+                "0",
+                "0",
+                "0"
+              ]
+            },
+            {
+              "brand": "Chromium",
+              "version": [
+                "108",
+                "0",
+                "5359",
+                "124"
+              ]
+            },
+            {
+              "brand": "Google Chrome",
+              "version": [
+                "108",
+                "0",
+                "5359",
+                "124"
+              ]
+            }
+          ],
+          "mobile": 0,
+          "model": "",
+          "bitness": "64",
+          "architecture": "x86"
+        }
+      },
+      "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf",
+      "test": 0,
+      "source": {
+        "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf"
+      },
+      "ext": {
+        "prebid": {
+          "auctiontimestamp": 1671449004622,
+          "targeting": {
+            "includewinners": true,
+            "includebidderkeys": false
+          },
+          "debug": true,
+          "channel": {
+            "name": "pbjs",
+            "version": "v7.28.0"
+          }
+        }
+      },
+      "tmax": 1000
+    },
+    "httpCalls": [
+      {
+        "expectedRequest": {
+          "uri": "https://rtb.conative.network/openrtb2/auction",
+          "body": {
+            "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf",
+            "imp": [
+              {
+                "id": "div-gpt-ad-1460505748561-0",
+                "banner": {
+                  "format": [
+                    {
+                      "w": 300,
+                      "h": 250
+                    }
+                  ],
+                  "topframe": 1
+                },
+                "ext": {
+                  "prebid": {
+                    "bidder": {
+                      "definemedia": {}
+                    }
+                  },
+                  "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9"
+                }
+              }
+            ],
+            "site": {
+              "domain": "localhost:8080",
+              "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true",
+              "publisher": {
+                "id": "1",
+                "domain": "localhost:8080"
+              }
+            },
+            "device": {
+              "dnt": 0,
+              "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36",
+              "sua": {
+                "browsers": [
+                  {
+                    "brand": "Not?A_Brand",
+                    "version": [
+                      "8",
+                      "0",
+                      "0",
+                      "0"
+                    ]
+                  },
+                  {
+                    "brand": "Chromium",
+                    "version": [
+                      "108",
+                      "0",
+                      "5359",
+                      "124"
+                    ]
+                  },
+                  {
+                    "brand": "Google Chrome",
+                    "version": [
+                      "108",
+                      "0",
+                      "5359",
+                      "124"
+                    ]
+                  }
+                ],
+                "platform": {
+                  "brand": "macOS",
+                  "version": [
+                    "12",
+                    "3",
+                    "1"
+                  ]
+                },
+                "mobile": 0,
+                "architecture": "x86",
+                "bitness": "64",
+                "source": 2
+              },
+              "h": 1169,
+              "w": 1098,
+              "language": "de"
+            },
+            "tmax": 1000,
+            "source": {
+              "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf"
+            },
+            "ext": {
+              "prebid": {
+                "auctiontimestamp": 1.671449004622e+12,
+                "channel": {
+                  "name": "pbjs",
+                  "version": "v7.28.0"
+                },
+                "debug": true,
+                "targeting": {
+                  "includebidderkeys": false,
+                  "includewinners": true
+                }
+              }
+            }
+          }
+        },
+        "mockResponse": {
+          "status": 200,
+          "body": {
+            "id": "test-request-id",
+            "seatbid": null,
+            "cur": null
+          }
+        }
+      }
+    ],
+    "expectedBidResponses": [{"currency":"USD","bids":[]}]
+  }
diff --git a/adapters/definemedia/definemediatest/supplemental/nocontent-response.json b/adapters/definemedia/definemediatest/supplemental/nocontent-response.json
new file mode 100644
index 00000000..147d2185
--- /dev/null
+++ b/adapters/definemedia/definemediatest/supplemental/nocontent-response.json
@@ -0,0 +1,219 @@
+{
+    "mockBidRequest": {
+      "imp": [
+        {
+          "ext": {
+            "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9",
+            "prebid": {
+              "bidder": {
+                "definemedia": {}
+              }
+            }
+          },
+          "id": "div-gpt-ad-1460505748561-0",
+          "banner": {
+            "topframe": 1,
+            "format": [
+              {
+                "w": 300,
+                "h": 250
+              }
+            ]
+          }
+        }
+      ],
+      "site": {
+        "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true",
+        "domain": "localhost:8080",
+        "publisher": {
+          "domain": "localhost:8080",
+          "id": "1"
+        }
+      },
+      "device": {
+        "w": 1098,
+        "h": 1169,
+        "dnt": 0,
+        "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36",
+        "language": "de",
+        "sua": {
+          "source": 2,
+          "platform": {
+            "brand": "macOS",
+            "version": [
+              "12",
+              "3",
+              "1"
+            ]
+          },
+          "browsers": [
+            {
+              "brand": "Not?A_Brand",
+              "version": [
+                "8",
+                "0",
+                "0",
+                "0"
+              ]
+            },
+            {
+              "brand": "Chromium",
+              "version": [
+                "108",
+                "0",
+                "5359",
+                "124"
+              ]
+            },
+            {
+              "brand": "Google Chrome",
+              "version": [
+                "108",
+                "0",
+                "5359",
+                "124"
+              ]
+            }
+          ],
+          "mobile": 0,
+          "model": "",
+          "bitness": "64",
+          "architecture": "x86"
+        }
+      },
+      "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf",
+      "test": 0,
+      "source": {
+        "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf"
+      },
+      "ext": {
+        "prebid": {
+          "auctiontimestamp": 1671449004622,
+          "targeting": {
+            "includewinners": true,
+            "includebidderkeys": false
+          },
+          "debug": true,
+          "channel": {
+            "name": "pbjs",
+            "version": "v7.28.0"
+          }
+        }
+      },
+      "tmax": 1000
+    },
+    "httpCalls": [
+      {
+        "expectedRequest": {
+          "uri": "https://rtb.conative.network/openrtb2/auction",
+          "body": {
+            "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf",
+            "imp": [
+              {
+                "id": "div-gpt-ad-1460505748561-0",
+                "banner": {
+                  "format": [
+                    {
+                      "w": 300,
+                      "h": 250
+                    }
+                  ],
+                  "topframe": 1
+                },
+                "ext": {
+                  "prebid": {
+                    "bidder": {
+                      "definemedia": {}
+                    }
+                  },
+                  "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9"
+                }
+              }
+            ],
+            "site": {
+              "domain": "localhost:8080",
+              "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true",
+              "publisher": {
+                "id": "1",
+                "domain": "localhost:8080"
+              }
+            },
+            "device": {
+              "dnt": 0,
+              "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36",
+              "sua": {
+                "browsers": [
+                  {
+                    "brand": "Not?A_Brand",
+                    "version": [
+                      "8",
+                      "0",
+                      "0",
+                      "0"
+                    ]
+                  },
+                  {
+                    "brand": "Chromium",
+                    "version": [
+                      "108",
+                      "0",
+                      "5359",
+                      "124"
+                    ]
+                  },
+                  {
+                    "brand": "Google Chrome",
+                    "version": [
+                      "108",
+                      "0",
+                      "5359",
+                      "124"
+                    ]
+                  }
+                ],
+                "platform": {
+                  "brand": "macOS",
+                  "version": [
+                    "12",
+                    "3",
+                    "1"
+                  ]
+                },
+                "mobile": 0,
+                "architecture": "x86",
+                "bitness": "64",
+                "source": 2
+              },
+              "h": 1169,
+              "w": 1098,
+              "language": "de"
+            },
+            "tmax": 1000,
+            "source": {
+              "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf"
+            },
+            "ext": {
+              "prebid": {
+                "auctiontimestamp": 1.671449004622e+12,
+                "channel": {
+                  "name": "pbjs",
+                  "version": "v7.28.0"
+                },
+                "debug": true,
+                "targeting": {
+                  "includebidderkeys": false,
+                  "includewinners": true
+                }
+              }
+            }
+          }
+        },
+        "mockResponse": {
+          "status": 204,
+          "body": {}
+        }
+      }
+    ],
+    "expectedBidResponses": [],
+    "expectedMakeBidsErrors": []
+  }
\ No newline at end of file
diff --git a/adapters/definemedia/definemediatest/supplemental/status_400.json b/adapters/definemedia/definemediatest/supplemental/status_400.json
new file mode 100644
index 00000000..ec772bf8
--- /dev/null
+++ b/adapters/definemedia/definemediatest/supplemental/status_400.json
@@ -0,0 +1,224 @@
+{
+    "mockBidRequest": {
+      "imp": [
+        {
+          "ext": {
+            "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9",
+            "prebid": {
+              "bidder": {
+                "definemedia": {}
+              }
+            }
+          },
+          "id": "div-gpt-ad-1460505748561-0",
+          "banner": {
+            "topframe": 1,
+            "format": [
+              {
+                "w": 300,
+                "h": 250
+              }
+            ]
+          }
+        }
+      ],
+      "site": {
+        "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true",
+        "domain": "localhost:8080",
+        "publisher": {
+          "domain": "localhost:8080",
+          "id": "1"
+        }
+      },
+      "device": {
+        "w": 1098,
+        "h": 1169,
+        "dnt": 0,
+        "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36",
+        "language": "de",
+        "sua": {
+          "source": 2,
+          "platform": {
+            "brand": "macOS",
+            "version": [
+              "12",
+              "3",
+              "1"
+            ]
+          },
+          "browsers": [
+            {
+              "brand": "Not?A_Brand",
+              "version": [
+                "8",
+                "0",
+                "0",
+                "0"
+              ]
+            },
+            {
+              "brand": "Chromium",
+              "version": [
+                "108",
+                "0",
+                "5359",
+                "124"
+              ]
+            },
+            {
+              "brand": "Google Chrome",
+              "version": [
+                "108",
+                "0",
+                "5359",
+                "124"
+              ]
+            }
+          ],
+          "mobile": 0,
+          "model": "",
+          "bitness": "64",
+          "architecture": "x86"
+        }
+      },
+      "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf",
+      "test": 0,
+      "source": {
+        "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf"
+      },
+      "ext": {
+        "prebid": {
+          "auctiontimestamp": 1671449004622,
+          "targeting": {
+            "includewinners": true,
+            "includebidderkeys": false
+          },
+          "debug": true,
+          "channel": {
+            "name": "pbjs",
+            "version": "v7.28.0"
+          }
+        }
+      },
+      "tmax": 1000
+    },
+    "httpCalls": [
+      {
+        "expectedRequest": {
+          "uri": "https://rtb.conative.network/openrtb2/auction",
+          "body": {
+            "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf",
+            "imp": [
+              {
+                "id": "div-gpt-ad-1460505748561-0",
+                "banner": {
+                  "format": [
+                    {
+                      "w": 300,
+                      "h": 250
+                    }
+                  ],
+                  "topframe": 1
+                },
+                "ext": {
+                  "prebid": {
+                    "bidder": {
+                      "definemedia": {}
+                    }
+                  },
+                  "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9"
+                }
+              }
+            ],
+            "site": {
+              "domain": "localhost:8080",
+              "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true",
+              "publisher": {
+                "id": "1",
+                "domain": "localhost:8080"
+              }
+            },
+            "device": {
+              "dnt": 0,
+              "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36",
+              "sua": {
+                "browsers": [
+                  {
+                    "brand": "Not?A_Brand",
+                    "version": [
+                      "8",
+                      "0",
+                      "0",
+                      "0"
+                    ]
+                  },
+                  {
+                    "brand": "Chromium",
+                    "version": [
+                      "108",
+                      "0",
+                      "5359",
+                      "124"
+                    ]
+                  },
+                  {
+                    "brand": "Google Chrome",
+                    "version": [
+                      "108",
+                      "0",
+                      "5359",
+                      "124"
+                    ]
+                  }
+                ],
+                "platform": {
+                  "brand": "macOS",
+                  "version": [
+                    "12",
+                    "3",
+                    "1"
+                  ]
+                },
+                "mobile": 0,
+                "architecture": "x86",
+                "bitness": "64",
+                "source": 2
+              },
+              "h": 1169,
+              "w": 1098,
+              "language": "de"
+            },
+            "tmax": 1000,
+            "source": {
+              "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf"
+            },
+            "ext": {
+              "prebid": {
+                "auctiontimestamp": 1.671449004622e+12,
+                "channel": {
+                  "name": "pbjs",
+                  "version": "v7.28.0"
+                },
+                "debug": true,
+                "targeting": {
+                  "includebidderkeys": false,
+                  "includewinners": true
+                }
+              }
+            }
+          }
+        },
+        "mockResponse": {
+          "status": 400,
+          "body": {}
+        }
+      }
+    ],
+    "expectedBidResponses": [],
+    "expectedMakeBidsErrors": [
+        {
+          "value": "Unexpected status code: 400. Run with request.debug = 1 for more info",
+          "comparison": "literal"
+        }
+      ]
+  }
\ No newline at end of file
diff --git a/adapters/definemedia/definemediatest/supplemental/status_418.json b/adapters/definemedia/definemediatest/supplemental/status_418.json
new file mode 100644
index 00000000..6e82f904
--- /dev/null
+++ b/adapters/definemedia/definemediatest/supplemental/status_418.json
@@ -0,0 +1,224 @@
+{
+    "mockBidRequest": {
+      "imp": [
+        {
+          "ext": {
+            "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9",
+            "prebid": {
+              "bidder": {
+                "definemedia": {}
+              }
+            }
+          },
+          "id": "div-gpt-ad-1460505748561-0",
+          "banner": {
+            "topframe": 1,
+            "format": [
+              {
+                "w": 300,
+                "h": 250
+              }
+            ]
+          }
+        }
+      ],
+      "site": {
+        "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true",
+        "domain": "localhost:8080",
+        "publisher": {
+          "domain": "localhost:8080",
+          "id": "1"
+        }
+      },
+      "device": {
+        "w": 1098,
+        "h": 1169,
+        "dnt": 0,
+        "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36",
+        "language": "de",
+        "sua": {
+          "source": 2,
+          "platform": {
+            "brand": "macOS",
+            "version": [
+              "12",
+              "3",
+              "1"
+            ]
+          },
+          "browsers": [
+            {
+              "brand": "Not?A_Brand",
+              "version": [
+                "8",
+                "0",
+                "0",
+                "0"
+              ]
+            },
+            {
+              "brand": "Chromium",
+              "version": [
+                "108",
+                "0",
+                "5359",
+                "124"
+              ]
+            },
+            {
+              "brand": "Google Chrome",
+              "version": [
+                "108",
+                "0",
+                "5359",
+                "124"
+              ]
+            }
+          ],
+          "mobile": 0,
+          "model": "",
+          "bitness": "64",
+          "architecture": "x86"
+        }
+      },
+      "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf",
+      "test": 0,
+      "source": {
+        "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf"
+      },
+      "ext": {
+        "prebid": {
+          "auctiontimestamp": 1671449004622,
+          "targeting": {
+            "includewinners": true,
+            "includebidderkeys": false
+          },
+          "debug": true,
+          "channel": {
+            "name": "pbjs",
+            "version": "v7.28.0"
+          }
+        }
+      },
+      "tmax": 1000
+    },
+    "httpCalls": [
+      {
+        "expectedRequest": {
+          "uri": "https://rtb.conative.network/openrtb2/auction",
+          "body": {
+            "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf",
+            "imp": [
+              {
+                "id": "div-gpt-ad-1460505748561-0",
+                "banner": {
+                  "format": [
+                    {
+                      "w": 300,
+                      "h": 250
+                    }
+                  ],
+                  "topframe": 1
+                },
+                "ext": {
+                  "prebid": {
+                    "bidder": {
+                      "definemedia": {}
+                    }
+                  },
+                  "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9"
+                }
+              }
+            ],
+            "site": {
+              "domain": "localhost:8080",
+              "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true",
+              "publisher": {
+                "id": "1",
+                "domain": "localhost:8080"
+              }
+            },
+            "device": {
+              "dnt": 0,
+              "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36",
+              "sua": {
+                "browsers": [
+                  {
+                    "brand": "Not?A_Brand",
+                    "version": [
+                      "8",
+                      "0",
+                      "0",
+                      "0"
+                    ]
+                  },
+                  {
+                    "brand": "Chromium",
+                    "version": [
+                      "108",
+                      "0",
+                      "5359",
+                      "124"
+                    ]
+                  },
+                  {
+                    "brand": "Google Chrome",
+                    "version": [
+                      "108",
+                      "0",
+                      "5359",
+                      "124"
+                    ]
+                  }
+                ],
+                "platform": {
+                  "brand": "macOS",
+                  "version": [
+                    "12",
+                    "3",
+                    "1"
+                  ]
+                },
+                "mobile": 0,
+                "architecture": "x86",
+                "bitness": "64",
+                "source": 2
+              },
+              "h": 1169,
+              "w": 1098,
+              "language": "de"
+            },
+            "tmax": 1000,
+            "source": {
+              "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf"
+            },
+            "ext": {
+              "prebid": {
+                "auctiontimestamp": 1.671449004622e+12,
+                "channel": {
+                  "name": "pbjs",
+                  "version": "v7.28.0"
+                },
+                "debug": true,
+                "targeting": {
+                  "includebidderkeys": false,
+                  "includewinners": true
+                }
+              }
+            }
+          }
+        },
+        "mockResponse": {
+          "status": 418,
+          "body": {}
+        }
+      }
+    ],
+    "expectedBidResponses": [],
+    "expectedMakeBidsErrors": [
+        {
+          "value": "Unexpected status code: 418. Run with request.debug = 1 for more info",
+          "comparison": "literal"
+        }
+      ]
+  }
\ No newline at end of file
diff --git a/adapters/definemedia/definemediatest/supplemental/unmarshal-error.json b/adapters/definemedia/definemediatest/supplemental/unmarshal-error.json
new file mode 100644
index 00000000..396d6821
--- /dev/null
+++ b/adapters/definemedia/definemediatest/supplemental/unmarshal-error.json
@@ -0,0 +1,224 @@
+{
+    "mockBidRequest": {
+      "imp": [
+        {
+          "ext": {
+            "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9",
+            "prebid": {
+              "bidder": {
+                "definemedia": {}
+              }
+            }
+          },
+          "id": "div-gpt-ad-1460505748561-0",
+          "banner": {
+            "topframe": 1,
+            "format": [
+              {
+                "w": 300,
+                "h": 250
+              }
+            ]
+          }
+        }
+      ],
+      "site": {
+        "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true",
+        "domain": "localhost:8080",
+        "publisher": {
+          "domain": "localhost:8080",
+          "id": "1"
+        }
+      },
+      "device": {
+        "w": 1098,
+        "h": 1169,
+        "dnt": 0,
+        "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36",
+        "language": "de",
+        "sua": {
+          "source": 2,
+          "platform": {
+            "brand": "macOS",
+            "version": [
+              "12",
+              "3",
+              "1"
+            ]
+          },
+          "browsers": [
+            {
+              "brand": "Not?A_Brand",
+              "version": [
+                "8",
+                "0",
+                "0",
+                "0"
+              ]
+            },
+            {
+              "brand": "Chromium",
+              "version": [
+                "108",
+                "0",
+                "5359",
+                "124"
+              ]
+            },
+            {
+              "brand": "Google Chrome",
+              "version": [
+                "108",
+                "0",
+                "5359",
+                "124"
+              ]
+            }
+          ],
+          "mobile": 0,
+          "model": "",
+          "bitness": "64",
+          "architecture": "x86"
+        }
+      },
+      "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf",
+      "test": 0,
+      "source": {
+        "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf"
+      },
+      "ext": {
+        "prebid": {
+          "auctiontimestamp": 1671449004622,
+          "targeting": {
+            "includewinners": true,
+            "includebidderkeys": false
+          },
+          "debug": true,
+          "channel": {
+            "name": "pbjs",
+            "version": "v7.28.0"
+          }
+        }
+      },
+      "tmax": 1000
+    },
+    "httpCalls": [
+      {
+        "expectedRequest": {
+          "uri": "https://rtb.conative.network/openrtb2/auction",
+          "body": {
+            "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf",
+            "imp": [
+              {
+                "id": "div-gpt-ad-1460505748561-0",
+                "banner": {
+                  "format": [
+                    {
+                      "w": 300,
+                      "h": 250
+                    }
+                  ],
+                  "topframe": 1
+                },
+                "ext": {
+                  "prebid": {
+                    "bidder": {
+                      "definemedia": {}
+                    }
+                  },
+                  "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9"
+                }
+              }
+            ],
+            "site": {
+              "domain": "localhost:8080",
+              "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true",
+              "publisher": {
+                "id": "1",
+                "domain": "localhost:8080"
+              }
+            },
+            "device": {
+              "dnt": 0,
+              "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36",
+              "sua": {
+                "browsers": [
+                  {
+                    "brand": "Not?A_Brand",
+                    "version": [
+                      "8",
+                      "0",
+                      "0",
+                      "0"
+                    ]
+                  },
+                  {
+                    "brand": "Chromium",
+                    "version": [
+                      "108",
+                      "0",
+                      "5359",
+                      "124"
+                    ]
+                  },
+                  {
+                    "brand": "Google Chrome",
+                    "version": [
+                      "108",
+                      "0",
+                      "5359",
+                      "124"
+                    ]
+                  }
+                ],
+                "platform": {
+                  "brand": "macOS",
+                  "version": [
+                    "12",
+                    "3",
+                    "1"
+                  ]
+                },
+                "mobile": 0,
+                "architecture": "x86",
+                "bitness": "64",
+                "source": 2
+              },
+              "h": 1169,
+              "w": 1098,
+              "language": "de"
+            },
+            "tmax": 1000,
+            "source": {
+              "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf"
+            },
+            "ext": {
+              "prebid": {
+                "auctiontimestamp": 1.671449004622e+12,
+                "channel": {
+                  "name": "pbjs",
+                  "version": "v7.28.0"
+                },
+                "debug": true,
+                "targeting": {
+                  "includebidderkeys": false,
+                  "includewinners": true
+                }
+              }
+            }
+          }
+        },
+        "mockResponse": {
+          "status": 200,
+          "body": "fail for unmarshall"
+        }
+      }
+    ],
+    "expectedBidResponses": [],
+    "expectedMakeBidsErrors": [
+        {
+            "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse",
+            "comparison": "literal"
+        }
+    ]
+  }
\ No newline at end of file
diff --git a/adapters/definemedia/definemediatest/supplemental/unsupported-type.json b/adapters/definemedia/definemediatest/supplemental/unsupported-type.json
new file mode 100644
index 00000000..91bfbc41
--- /dev/null
+++ b/adapters/definemedia/definemediatest/supplemental/unsupported-type.json
@@ -0,0 +1,250 @@
+{
+  "mockBidRequest": {
+    "imp": [
+      {
+        "ext": {
+          "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9",
+          "prebid": {
+            "bidder": {
+              "definemedia": {}
+            }
+          }
+        },
+        "id": "div-gpt-ad-1460505748561-0",
+        "video": {
+          "w": 300,
+          "h": 250,
+          "maxduration": 60,
+          "minduration": 1,
+          "api": [1, 2, 5, 6, 7],
+          "mimes": ["video/mp4"],
+          "placement": 4,
+          "protocols": [2]
+        }
+      }
+    ],
+    "site": {
+      "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true",
+      "domain": "localhost:8080",
+      "publisher": {
+        "domain": "localhost:8080",
+        "id": "1"
+      }
+    },
+    "device": {
+      "w": 1098,
+      "h": 1169,
+      "dnt": 0,
+      "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36",
+      "language": "de",
+      "sua": {
+        "source": 2,
+        "platform": {
+          "brand": "macOS",
+          "version": [
+            "12",
+            "3",
+            "1"
+          ]
+        },
+        "browsers": [
+          {
+            "brand": "Not?A_Brand",
+            "version": [
+              "8",
+              "0",
+              "0",
+              "0"
+            ]
+          },
+          {
+            "brand": "Chromium",
+            "version": [
+              "108",
+              "0",
+              "5359",
+              "124"
+            ]
+          },
+          {
+            "brand": "Google Chrome",
+            "version": [
+              "108",
+              "0",
+              "5359",
+              "124"
+            ]
+          }
+        ],
+        "mobile": 0,
+        "model": "",
+        "bitness": "64",
+        "architecture": "x86"
+      }
+    },
+    "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf",
+    "test": 0,
+    "source": {
+      "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf"
+    },
+    "ext": {
+      "prebid": {
+        "auctiontimestamp": 1671449004622,
+        "targeting": {
+          "includewinners": true,
+          "includebidderkeys": false
+        },
+        "debug": true,
+        "channel": {
+          "name": "pbjs",
+          "version": "v7.28.0"
+        }
+      }
+    },
+    "tmax": 1000
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://rtb.conative.network/openrtb2/auction",
+        "body": {
+          "id": "ceb63773-4280-45f2-a684-94cf6a3b8fcf",
+          "imp": [
+            {
+              "id": "div-gpt-ad-1460505748561-0",
+              "video": {
+                "w": 300,
+                "h": 250,
+                "maxduration": 60,
+                "minduration": 1,
+                "api": [1, 2, 5, 6, 7],
+                "mimes": ["video/mp4"],
+                "placement": 4,
+                "protocols": [2]
+              },
+              "ext": {
+                "prebid": {
+                  "bidder": {
+                    "definemedia": {}
+                  }
+                },
+                "tid": "397962d3-47a1-4634-9cb7-78597b01d9a9"
+              }
+            }
+          ],
+          "site": {
+            "domain": "localhost:8080",
+            "page": "http://localhost:8080/prebidServer_example.html?pbjs_debug=true",
+            "publisher": {
+              "id": "1",
+              "domain": "localhost:8080"
+            }
+          },
+          "device": {
+            "dnt": 0,
+            "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36",
+            "sua": {
+              "browsers": [
+                {
+                  "brand": "Not?A_Brand",
+                  "version": [
+                    "8",
+                    "0",
+                    "0",
+                    "0"
+                  ]
+                },
+                {
+                  "brand": "Chromium",
+                  "version": [
+                    "108",
+                    "0",
+                    "5359",
+                    "124"
+                  ]
+                },
+                {
+                  "brand": "Google Chrome",
+                  "version": [
+                    "108",
+                    "0",
+                    "5359",
+                    "124"
+                  ]
+                }
+              ],
+              "platform": {
+                "brand": "macOS",
+                "version": [
+                  "12",
+                  "3",
+                  "1"
+                ]
+              },
+              "mobile": 0,
+              "architecture": "x86",
+              "bitness": "64",
+              "source": 2
+            },
+            "h": 1169,
+            "w": 1098,
+            "language": "de"
+          },
+          "tmax": 1000,
+          "source": {
+            "tid": "ceb63773-4280-45f2-a684-94cf6a3b8fcf"
+          },
+          "ext": {
+            "prebid": {
+              "auctiontimestamp": 1.671449004622e+12,
+              "channel": {
+                "name": "pbjs",
+                "version": "v7.28.0"
+              },
+              "debug": true,
+              "targeting": {
+                "includebidderkeys": false,
+                "includewinners": true
+              }
+            }
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "test-request-id",
+          "seatbid": [
+            {
+              "bid": [
+                {
+                  "id": "46189656-7e2e-477d-b7f2-e05de224bb89",
+                  "impid": "div-gpt-ad-1460505748561-0",
+                  "price": 100,
+                  "adm": "{banner html}",
+                  "adomain": [
+                    "test.com"
+                  ],
+                  "crid": "test-creative-id",
+                  "ext": {
+                    "prebid": {
+                      "type": "video"
+                    }
+                  }
+                }
+              ]
+            }
+          ],
+          "cur": "USD"
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [{"currency":"USD","bids":[]}],
+  "expectedMakeBidsErrors": [
+      {
+        "value": "Invalid mediatype in the impression",
+        "comparison": "literal"
+      }
+    ]
+}
diff --git a/adapters/definemedia/params_test.go b/adapters/definemedia/params_test.go
new file mode 100644
index 00000000..63ef5272
--- /dev/null
+++ b/adapters/definemedia/params_test.go
@@ -0,0 +1,48 @@
+package definemedia
+
+import (
+	"encoding/json"
+	"testing"
+
+	"github.com/prebid/prebid-server/openrtb_ext"
+)
+
+func TestValidParams(t *testing.T) {
+	validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params")
+	if err != nil {
+		t.Fatalf("Failed to fetch the json schema. %v", err)
+	}
+
+	for _, p := range validParams {
+		if err := validator.Validate(openrtb_ext.BidderDefinemedia, json.RawMessage(p)); err != nil {
+			t.Errorf("Schema rejected valid params: %s", p)
+		}
+	}
+}
+
+func TestInvalidParams(t *testing.T) {
+	validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params")
+	if err != nil {
+		t.Fatalf("Failed to fetch the json schema. %v", err)
+	}
+
+	for _, p := range invalidParams {
+		if err := validator.Validate(openrtb_ext.BidderDefinemedia, json.RawMessage(p)); err == nil {
+			t.Errorf("Schema allowed invalid params: %s", p)
+		}
+	}
+}
+
+var validParams = []string{
+	`{"mandantId":123}`,
+	`{"mandantId":123, "adslotId":456}`,
+}
+
+var invalidParams = []string{
+	`{"mandantId": "42"}`,
+	`{"MandantId": "42"}`,
+	`{"mandantId":123, "adslotId":"456"}`,
+	`{"adslotId":456}`,
+	`{"adslotId":"456"}`,
+	`{}`,
+}
diff --git a/endpoints/openrtb2/auction_test.go b/endpoints/openrtb2/auction_test.go
index 530d197e..bab25261 100644
--- a/endpoints/openrtb2/auction_test.go
+++ b/endpoints/openrtb2/auction_test.go
@@ -4991,8 +4991,8 @@ func TestParseRequestStoredResponses(t *testing.T) {
 }
 
 func TestParseRequestStoredBidResponses(t *testing.T) {
-	bidRespId1 := json.RawMessage(`{"id": "resp_id1", "seatbid": [{"bid": [{"id": "bid_id1"}], "seat": "testBidder1"}], "bidid": "123", "cur": "USD"}`)
-	bidRespId2 := json.RawMessage(`{"id": "resp_id2", "seatbid": [{"bid": [{"id": "bid_id2"}], "seat": "testBidder2"}], "bidid": "124", "cur": "USD"}`)
+	bidRespId1 := json.RawMessage(`{"id": "resp_id1", "seatbid": [{"bid": [{"id": "bid_id1"}], "seat": "telaria"}], "bidid": "123", "cur": "USD"}`)
+	bidRespId2 := json.RawMessage(`{"id": "resp_id2", "seatbid": [{"bid": [{"id": "bid_id2"}], "seat": "amx"}], "bidid": "124", "cur": "USD"}`)
 	bidRespId3 := json.RawMessage(`{"id": "resp_id3", "seatbid": [{"bid": [{"id": "bid_id3"}], "seat": "APPNEXUS"}], "bidid": "125", "cur": "USD"}`)
 	mockStoredBidResponses := map[string]json.RawMessage{
 		"bidResponseId1": bidRespId1,
@@ -5011,15 +5011,23 @@ func TestParseRequestStoredBidResponses(t *testing.T) {
 			name:             "req imp has valid stored bid response",
 			givenRequestBody: validRequest(t, "imp-with-stored-bid-resp.json"),
 			expectedStoredBidResponses: map[string]map[string]json.RawMessage{
-				"imp-id1": {"testBidder1": bidRespId1},
+				"imp-id1": {"telaria": bidRespId1},
 			},
 			expectedErrorCount: 0,
 		},
 		{
-			name:             "req imp has valid stored bid response with case insensitive bidder name",
-			givenRequestBody: validRequest(t, "imp-with-stored-bid-resp-insensitive-bidder-name.json"),
+			name:             "req imp has valid stored bid response with case not-matching bidder name",
+			givenRequestBody: validRequest(t, "imp-with-stored-bid-resp-case-not-matching-bidder-name.json"),
 			expectedStoredBidResponses: map[string]map[string]json.RawMessage{
-				"imp-id3": {"APPNEXUS": bidRespId3},
+				"imp-id3": {"appnexus": bidRespId3},
+			},
+			expectedErrorCount: 0,
+		},
+		{
+			name:             "req imp has valid stored bid response with case matching bidder name",
+			givenRequestBody: validRequest(t, "imp-with-stored-bid-resp-case-matching-bidder-name.json"),
+			expectedStoredBidResponses: map[string]map[string]json.RawMessage{
+				"imp-id3": {"appnexus": bidRespId3},
 			},
 			expectedErrorCount: 0,
 		},
@@ -5027,8 +5035,8 @@ func TestParseRequestStoredBidResponses(t *testing.T) {
 			name:             "req has two imps with valid stored bid responses",
 			givenRequestBody: validRequest(t, "req-two-imps-stored-bid-responses.json"),
 			expectedStoredBidResponses: map[string]map[string]json.RawMessage{
-				"imp-id1": {"testBidder1": bidRespId1},
-				"imp-id2": {"testBidder2": bidRespId2},
+				"imp-id1": {"telaria": bidRespId1},
+				"imp-id2": {"amx": bidRespId2},
 			},
 			expectedErrorCount: 0,
 		},
@@ -5036,7 +5044,7 @@ func TestParseRequestStoredBidResponses(t *testing.T) {
 			name:             "req has two imps one with valid stored bid responses and another one without stored bid responses",
 			givenRequestBody: validRequest(t, "req-two-imps-with-and-without-stored-bid-responses.json"),
 			expectedStoredBidResponses: map[string]map[string]json.RawMessage{
-				"imp-id2": {"testBidder2": bidRespId2},
+				"imp-id2": {"amx": bidRespId2},
 			},
 			expectedErrorCount: 0,
 		},
@@ -5044,7 +5052,13 @@ func TestParseRequestStoredBidResponses(t *testing.T) {
 			name:                       "req has two imps with missing stored bid responses",
 			givenRequestBody:           validRequest(t, "req-two-imps-missing-stored-bid-response.json"),
 			expectedStoredBidResponses: nil,
-			expectedErrorCount:         2,
+			expectedErrorCount:         1,
+		},
+		{
+			name:                       "req imp has valid stored bid response with non existing bidder name",
+			givenRequestBody:           validRequest(t, "imp-with-stored-bid-resp-non-existing-bidder-name.json"),
+			expectedStoredBidResponses: nil,
+			expectedErrorCount:         1,
 		},
 	}
 	for _, test := range tests {
@@ -5063,7 +5077,7 @@ func TestParseRequestStoredBidResponses(t *testing.T) {
 				map[string]string{},
 				false,
 				[]byte{},
-				map[string]openrtb_ext.BidderName{"testBidder1": "testBidder1", "testBidder2": "testBidder2", "appnexus": "appnexus"},
+				map[string]openrtb_ext.BidderName{"telaria": "telaria", "amx": "amx", "appnexus": "appnexus"},
 				nil,
 				nil,
 				hardcodedResponseIPValidator{response: true},
@@ -5078,6 +5092,7 @@ func TestParseRequestStoredBidResponses(t *testing.T) {
 			req := httptest.NewRequest("POST", "/openrtb2/auction", strings.NewReader(test.givenRequestBody))
 			_, _, _, storedBidResponses, _, _, errL := deps.parseRequest(req, &metrics.Labels{}, hookExecutor)
 			if test.expectedErrorCount == 0 {
+				assert.Empty(t, errL)
 				assert.Equal(t, test.expectedStoredBidResponses, storedBidResponses, "stored responses should match")
 			} else {
 				assert.Contains(t, errL[0].Error(), test.expectedError, "error should match")
@@ -5653,8 +5668,10 @@ func TestValidateStoredResp(t *testing.T) {
 	}
 
 	for _, test := range testCases {
-		errorList := deps.validateRequest(test.givenRequestWrapper, false, test.hasStoredAuctionResponses, test.storedBidResponses, false)
-		assert.Equalf(t, test.expectedErrorList, errorList, "Error doesn't match: %s\n", test.description)
+		t.Run(test.description, func(t *testing.T) {
+			errorList := deps.validateRequest(test.givenRequestWrapper, false, test.hasStoredAuctionResponses, test.storedBidResponses, false)
+			assert.Equalf(t, test.expectedErrorList, errorList, "Error doesn't match: %s\n", test.description)
+		})
 	}
 }
 
diff --git a/exchange/utils_test.go b/exchange/utils_test.go
index b413a6b2..3c28a43c 100644
--- a/exchange/utils_test.go
+++ b/exchange/utils_test.go
@@ -5,6 +5,7 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
+	"github.com/prebid/prebid-server/stored_responses"
 	"sort"
 	"testing"
 
@@ -4754,3 +4755,25 @@ func TestApplyBidAdjustmentToFloor(t *testing.T) {
 		})
 	}
 }
+
+func TestBuildBidResponseRequestBidderName(t *testing.T) {
+	bidderImpResponses := stored_responses.BidderImpsWithBidResponses{
+		openrtb_ext.BidderName("appnexus"): {"impId1": json.RawMessage(`{}`), "impId2": json.RawMessage(`{}`)},
+		openrtb_ext.BidderName("appneXUS"): {"impId3": json.RawMessage(`{}`), "impId4": json.RawMessage(`{}`)},
+	}
+
+	bidderImpReplaceImpID := stored_responses.BidderImpReplaceImpID{
+		"appnexus": {"impId1": true, "impId2": false},
+		"appneXUS": {"impId3": true, "impId4": false},
+	}
+	result := buildBidResponseRequest(nil, bidderImpResponses, nil, bidderImpReplaceImpID)
+
+	resultAppnexus := result["appnexus"]
+	assert.Equal(t, resultAppnexus.BidderName, openrtb_ext.BidderName("appnexus"))
+	assert.Equal(t, resultAppnexus.ImpReplaceImpId, map[string]bool{"impId1": true, "impId2": false})
+
+	resultAppneXUS := result["appneXUS"]
+	assert.Equal(t, resultAppneXUS.BidderName, openrtb_ext.BidderName("appneXUS"))
+	assert.Equal(t, resultAppneXUS.ImpReplaceImpId, map[string]bool{"impId3": true, "impId4": false})
+
+}
diff --git a/stored_responses/stored_responses_test.go b/stored_responses/stored_responses_test.go
index c4ddea27..209b34a6 100644
--- a/stored_responses/stored_responses_test.go
+++ b/stored_responses/stored_responses_test.go
@@ -163,136 +163,109 @@ func TestBuildStoredBidResponses(t *testing.T) {
 }
 
 func TestProcessStoredAuctionAndBidResponsesErrors(t *testing.T) {
-	bidderMap := map[string]openrtb_ext.BidderName{"testBidder": "testBidder"}
-
 	testCases := []struct {
 		description       string
-		requestJson       []byte
+		request           openrtb2.BidRequest
 		expectedErrorList []error
 	}{
 		{
 			description: "Invalid stored auction response format: empty stored Auction Response Id",
-			requestJson: []byte(`{"imp": [
-    			  {
-    			    "id": "imp-id1",
-    			    "ext": {
+			request: openrtb2.BidRequest{
+				Imp: []openrtb2.Imp{
+					{ID: "imp-id1",
+						Ext: json.RawMessage(`{
     			      "prebid": {
-    			        "storedauctionresponse": {
-    			        }
-    			      }
-    			    }
-    			  }
-    			]}`),
+    			        "storedauctionresponse": {}
+    			      }}`)},
+				},
+			},
 			expectedErrorList: []error{errors.New("request.imp[0] has ext.prebid.storedauctionresponse specified, but \"id\" field is missing ")},
 		},
 		{
 			description: "Invalid stored bid response format: empty storedbidresponse.bidder",
-			requestJson: []byte(`{"imp": [
-    			  {
-    			    "id": "imp-id1",
-    			    "ext": {
+			request: openrtb2.BidRequest{
+				Imp: []openrtb2.Imp{
+					{ID: "imp-id1",
+						Ext: json.RawMessage(`{
     			      "prebid": {
     			        "storedbidresponse": [
 							{ "id": "123abc"}]
-    			      }
-    			    }
-    			  }
-    			]}`),
+    			      }}`)},
+				},
+			},
 			expectedErrorList: []error{errors.New("request.imp[0] has ext.prebid.storedbidresponse specified, but \"id\" or/and \"bidder\" fields are missing ")},
 		},
 		{
 			description: "Invalid stored bid response format: empty storedbidresponse.id",
-			requestJson: []byte(`{"imp": [
-    			  {
-    			    "id": "imp-id1",
-    			    "ext": {
+			request: openrtb2.BidRequest{
+				Imp: []openrtb2.Imp{
+					{ID: "imp-id1",
+						Ext: json.RawMessage(`{
     			      "prebid": {
     			        "storedbidresponse": [
 							{ "bidder": "testbidder"}]
-    			      }
-    			    }
-    			  }
-    			]}`),
+    			      }}`)},
+				},
+			},
 			expectedErrorList: []error{errors.New("request.imp[0] has ext.prebid.storedbidresponse specified, but \"id\" or/and \"bidder\" fields are missing ")},
 		},
-		{
-			description: "Invalid stored bid response: storedbidresponse.bidder not found",
-			requestJson: []byte(`{"imp": [
-    			  {
-    			    "id": "imp-id1",
-    			    "ext": {
-    			      "prebid": {
-    			        "storedbidresponse": [
-							{ "bidder": "testBidder123", "id": "123abc"}]
-    			      }
-    			    }
-    			  }
-    			]}`),
-			expectedErrorList: []error{errors.New("request.imp[impId: imp-id1].ext.prebid.bidder contains unknown bidder: testBidder123. Did you forget an alias in request.ext.prebid.aliases?")},
-		},
 		{
 			description: "Invalid stored auction response format: empty stored Auction Response Id in second imp",
-			requestJson: []byte(`{"imp": [
-    			  {
-    			    "id": "imp-id1",
-    			    "ext": {
+			request: openrtb2.BidRequest{
+				Imp: []openrtb2.Imp{
+					{ID: "imp-id1",
+						Ext: json.RawMessage(`{
     			      "prebid": {
     			        "storedauctionresponse": {
 							"id":"123"
     			        }
-    			      }
-    			    }
-    			  },
-			      {
-    			    "id": "imp-id2",
-    			    "ext": {
+    			      }}`)},
+					{ID: "imp-id2",
+						Ext: json.RawMessage(`{
     			      "prebid": {
-    			        "storedauctionresponse": {
+    			         "storedauctionresponse": {
 							"id":""
     			        }
-    			      }
-    			    }
-    			  }
-    			]}`),
+    			      }}`)},
+				},
+			},
 			expectedErrorList: []error{errors.New("request.imp[1] has ext.prebid.storedauctionresponse specified, but \"id\" field is missing ")},
 		},
 		{
 			description: "Invalid stored bid response format: empty stored bid Response Id in second imp",
-			requestJson: []byte(`{"imp": [
-    			  {
-    			    "id": "imp-id1",
-    			    "ext": {
+			request: openrtb2.BidRequest{
+				Imp: []openrtb2.Imp{
+					{ID: "imp-id1",
+						Ext: json.RawMessage(`{
     			      "prebid": {
-    			        "storedbidresponse": [
+    			         "storedbidresponse": [
                              {"bidder":"testBidder", "id": "123abc"}
                         ]
-    			      }
-    			    }
-    			  },
-			      {
-    			    "id": "imp-id2",
-    			    "ext": {
+    			      }}`)},
+					{ID: "imp-id2",
+						Ext: json.RawMessage(`{
     			      "prebid": {
-    			        "storedbidresponse": [
+    			         "storedbidresponse": [
                              {"bidder":"testBidder", "id": ""}
                         ]
-    			      }
-    			    }
-    			  }
-    			]}`),
+    			      }}`)},
+				},
+			},
 			expectedErrorList: []error{errors.New("request.imp[1] has ext.prebid.storedbidresponse specified, but \"id\" or/and \"bidder\" fields are missing ")},
 		},
 	}
 
 	for _, test := range testCases {
-		_, _, _, errorList := ProcessStoredResponses(nil, test.requestJson, nil, bidderMap)
-		assert.Equalf(t, test.expectedErrorList, errorList, "Error doesn't match: %s\n", test.description)
+		t.Run(test.description, func(t *testing.T) {
+			rw := &openrtb_ext.RequestWrapper{BidRequest: &test.request}
+			_, _, _, errorList := ProcessStoredResponses(nil, rw, nil)
+			assert.Equalf(t, test.expectedErrorList, errorList, "Error doesn't match: %s\n", test.description)
+		})
 	}
 
 }
 
 func TestProcessStoredAuctionAndBidResponses(t *testing.T) {
-	bidderMap := map[string]openrtb_ext.BidderName{"bidderA": "bidderA", "bidderB": "bidderB"}
 	bidStoredResp1 := json.RawMessage(`[{"bid": [{"id": "bid_id1"],"seat": "bidderA"}]`)
 	bidStoredResp2 := json.RawMessage(`[{"bid": [{"id": "bid_id2"],"seat": "bidderB"}]`)
 	bidStoredResp3 := json.RawMessage(`[{"bid": [{"id": "bid_id3"],"seat": "bidderA"}]`)
@@ -305,33 +278,31 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) {
 
 	testCases := []struct {
 		description                    string
-		requestJson                    []byte
+		request                        openrtb2.BidRequest
 		expectedStoredAuctionResponses ImpsWithBidResponses
 		expectedStoredBidResponses     ImpBidderStoredResp
 		expectedBidderImpReplaceImpID  BidderImpReplaceImpID
 	}{
 		{
 			description: "No stored responses",
-			requestJson: []byte(`{"imp": [
-    			  {
-    			    "id": "imp-id1",
-    			    "ext": {
-    			      "prebid": {
-    			        
-    			      }
-    			    }
-    			  }
-    			]}`),
+			request: openrtb2.BidRequest{
+				Imp: []openrtb2.Imp{
+					{ID: "imp-id1",
+						Ext: json.RawMessage(`{
+    			      "prebid": {}
+    			    }`)},
+				},
+			},
 			expectedStoredAuctionResponses: nil,
 			expectedStoredBidResponses:     nil,
 			expectedBidderImpReplaceImpID:  nil,
 		},
 		{
 			description: "Stored auction response one imp",
-			requestJson: []byte(`{"imp": [
-    			  {
-    			    "id": "imp-id1",
-    			    "ext": {
+			request: openrtb2.BidRequest{
+				Imp: []openrtb2.Imp{
+					{ID: "imp-id1",
+						Ext: json.RawMessage(`{
                 		"appnexus": {
 							"placementId": 123
                 		},
@@ -340,9 +311,9 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) {
                         		"id": "1"
                     		}
                 		}
-            		}
-    			  }
-    			]}`),
+            		}`)},
+				},
+			},
 			expectedStoredAuctionResponses: ImpsWithBidResponses{
 				"imp-id1": bidStoredResp1,
 			},
@@ -351,11 +322,11 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) {
 		},
 		{
 			description: "Stored bid response one imp",
-			requestJson: []byte(`{"imp": [
-    			  {
-    			    "id": "imp-id1",
-    			    "ext": {
-                		"appnexus": {
+			request: openrtb2.BidRequest{
+				Imp: []openrtb2.Imp{
+					{ID: "imp-id1",
+						Ext: json.RawMessage(`{
+                		"bidderA": {
 							"placementId": 123
                 		},
                 		"prebid": {
@@ -363,9 +334,9 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) {
                         		{"bidder":"bidderA", "id": "1"}
                     		]
                 		}
-            		}
-    			  }
-    			]}`),
+            		}`)},
+				},
+			},
 			expectedStoredAuctionResponses: ImpsWithBidResponses{},
 			expectedStoredBidResponses: ImpBidderStoredResp{
 				"imp-id1": {"bidderA": bidStoredResp1},
@@ -376,11 +347,14 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) {
 		},
 		{
 			description: "Stored bid responses two bidders one imp",
-			requestJson: []byte(`{"imp": [
-    			  {
-    			    "id": "imp-id1",
-    			    "ext": {
-                		"appnexus": {
+			request: openrtb2.BidRequest{
+				Imp: []openrtb2.Imp{
+					{ID: "imp-id1",
+						Ext: json.RawMessage(`{
+                		"bidderA": {
+							"placementId": 123
+                		},
+						"bidderB": {
 							"placementId": 123
                 		},
                 		"prebid": {
@@ -389,9 +363,9 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) {
                         		{"bidder":"bidderB", "id": "2", "replaceimpid": false}
                     		]
                 		}
-            		}
-    			  }
-    			]}`),
+            		}`)},
+				},
+			},
 			expectedStoredAuctionResponses: ImpsWithBidResponses{},
 			expectedStoredBidResponses: ImpBidderStoredResp{
 				"imp-id1": {"bidderA": bidStoredResp1, "bidderB": bidStoredResp2},
@@ -401,14 +375,120 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) {
 				"bidderB": map[string]bool{"imp-id1": false},
 			},
 		},
+		{
+			description: "Stored bid responses two same mixed case bidders one imp",
+			request: openrtb2.BidRequest{
+				Imp: []openrtb2.Imp{
+					{ID: "imp-id1",
+						Ext: json.RawMessage(`{
+                		"bidderA": {
+							"placementId": 123
+                		},
+						"BIDDERa": {
+							"placementId": 123
+                		},
+                		"prebid": {
+                    		"storedbidresponse": [
+                        		{"bidder":"bidderA", "id": "1", "replaceimpid": true},
+                        		{"bidder":"bidderB", "id": "2", "replaceimpid": false}
+                    		]
+                		}
+            		}`)},
+				},
+			},
+			expectedStoredAuctionResponses: ImpsWithBidResponses{},
+			expectedStoredBidResponses: ImpBidderStoredResp{
+				"imp-id1": {"bidderA": bidStoredResp1, "BIDDERa": bidStoredResp1},
+			},
+			expectedBidderImpReplaceImpID: BidderImpReplaceImpID{
+				"BIDDERa": map[string]bool{"imp-id1": true},
+				"bidderA": map[string]bool{"imp-id1": true},
+			},
+		},
+		{
+			description: "Stored bid responses 3 same mixed case bidders in imp.ext and imp.ext.prebid.bidders one imp",
+			request: openrtb2.BidRequest{
+				Imp: []openrtb2.Imp{
+					{ID: "imp-id1",
+						Ext: json.RawMessage(`{
+                		"bidderA": {
+							"placementId": 123
+                		},
+						"BIDDERa": {
+							"placementId": 123
+                		},
+                		"prebid": {
+							"bidder": {
+                        		"BiddeRa": {
+                            		"placementId": 12883451
+                        		}
+                    		},
+                    		"storedbidresponse": [
+                        		{"bidder":"bidderA", "id": "1", "replaceimpid": true},
+                        		{"bidder":"bidderB", "id": "2", "replaceimpid": false}
+                    		]
+                		}
+            		}`)},
+				},
+			},
+			expectedStoredAuctionResponses: ImpsWithBidResponses{},
+			expectedStoredBidResponses: ImpBidderStoredResp{
+				"imp-id1": {"bidderA": bidStoredResp1, "BIDDERa": bidStoredResp1, "BiddeRa": bidStoredResp1},
+			},
+			expectedBidderImpReplaceImpID: BidderImpReplaceImpID{
+				"BIDDERa": map[string]bool{"imp-id1": true},
+				"bidderA": map[string]bool{"imp-id1": true},
+				"BiddeRa": map[string]bool{"imp-id1": true},
+			},
+		},
+		{
+			description: "Stored bid responses 3 same mixed case bidders in imp.ext and imp.ext.prebid.bidders one imp, duplicated stored response",
+			request: openrtb2.BidRequest{
+				Imp: []openrtb2.Imp{
+					{ID: "imp-id1",
+						Ext: json.RawMessage(`{
+                		"bidderA": {
+							"placementId": 123
+                		},
+						"BIDDERa": {
+							"placementId": 123
+                		},
+                		"prebid": {
+							"bidder": {
+                        		"BiddeRa": {
+                            		"placementId": 12883451
+                        		}
+                    		},
+                    		"storedbidresponse": [
+                        		{"bidder":"bidderA", "id": "1", "replaceimpid": true},
+                        		{"bidder":"bidderA", "id": "2", "replaceimpid": true},
+                        		{"bidder":"bidderB", "id": "2", "replaceimpid": false}
+                    		]
+                		}
+            		}`)},
+				},
+			},
+			expectedStoredAuctionResponses: ImpsWithBidResponses{},
+			expectedStoredBidResponses: ImpBidderStoredResp{
+				"imp-id1": {"bidderA": bidStoredResp1, "BIDDERa": bidStoredResp1, "BiddeRa": bidStoredResp1},
+			},
+			expectedBidderImpReplaceImpID: BidderImpReplaceImpID{
+				"BIDDERa": map[string]bool{"imp-id1": true},
+				"bidderA": map[string]bool{"imp-id1": true},
+				"BiddeRa": map[string]bool{"imp-id1": true},
+			},
+		},
 		{
 			//This is not a valid scenario for real auction request, added for testing purposes
 			description: "Stored auction and bid responses one imp",
-			requestJson: []byte(`{"imp": [
-    			  {
-    			    "id": "imp-id1",
-    			    "ext": {
-                		"appnexus": {
+			request: openrtb2.BidRequest{
+				Imp: []openrtb2.Imp{
+					{ID: "imp-id1",
+						Ext: json.RawMessage(`{
+                		"bidderA": {
+							"placementId": 123
+                		},
+						"bidderB": {
 							"placementId": 123
                 		},
                 		"prebid": {
@@ -420,9 +500,9 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) {
                         		{"bidder":"bidderB", "id": "2"}
                     		]
                 		}
-            		}
-    			  }
-    			]}`),
+            		}`)},
+				},
+			},
 			expectedStoredAuctionResponses: ImpsWithBidResponses{
 				"imp-id1": bidStoredResp1,
 			},
@@ -436,10 +516,10 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) {
 		},
 		{
 			description: "Stored auction response three imps",
-			requestJson: []byte(`{"imp": [
-    			  {
-    			    "id": "imp-id1",
-    			    "ext": {
+			request: openrtb2.BidRequest{
+				Imp: []openrtb2.Imp{
+					{ID: "imp-id1",
+						Ext: json.RawMessage(`{
                 		"appnexus": {
 							"placementId": 123
                 		},
@@ -448,11 +528,9 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) {
                         		"id": "1"
                     		}
                 		}
-            		}
-    			  },
-					{
-    			    "id": "imp-id2",
-    			    "ext": {
+            		}`)},
+					{ID: "imp-id2",
+						Ext: json.RawMessage(`{
                 		"appnexus": {
 							"placementId": 123
                 		},
@@ -461,11 +539,10 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) {
                         		"id": "2"
                     		}
                 		}
-            		}
-    			  },
+            		}`)},
 					{
-    			    "id": "imp-id3",
-    			    "ext": {
+						ID: "imp-id3",
+						Ext: json.RawMessage(`{
                 		"appnexus": {
 							"placementId": 123
                 		},
@@ -474,9 +551,10 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) {
                         		"id": "3"
                     		}
                 		}
-            		}
-    			  }
-    			]}`),
+            		}`),
+					},
+				},
+			},
 			expectedStoredAuctionResponses: ImpsWithBidResponses{
 				"imp-id1": bidStoredResp1,
 				"imp-id2": bidStoredResp2,
@@ -487,10 +565,10 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) {
 		},
 		{
 			description: "Stored auction response three imps duplicated stored auction response",
-			requestJson: []byte(`{"imp": [
-    			  {
-    			    "id": "imp-id1",
-    			    "ext": {
+			request: openrtb2.BidRequest{
+				Imp: []openrtb2.Imp{
+					{ID: "imp-id1",
+						Ext: json.RawMessage(`{
                 		"appnexus": {
 							"placementId": 123
                 		},
@@ -499,11 +577,9 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) {
                         		"id": "1"
                     		}
                 		}
-            		}
-    			  },
-					{
-    			    "id": "imp-id2",
-    			    "ext": {
+            		}`)},
+					{ID: "imp-id2",
+						Ext: json.RawMessage(`{
                 		"appnexus": {
 							"placementId": 123
                 		},
@@ -512,11 +588,10 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) {
                         		"id": "2"
                     		}
                 		}
-            		}
-    			  },
+            		}`)},
 					{
-    			    "id": "imp-id3",
-    			    "ext": {
+						ID: "imp-id3",
+						Ext: json.RawMessage(`{
                 		"appnexus": {
 							"placementId": 123
                 		},
@@ -525,9 +600,10 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) {
                         		"id": "2"
                     		}
                 		}
-            		}
-    			  }
-    			]}`),
+            		}`),
+					},
+				},
+			},
 			expectedStoredAuctionResponses: ImpsWithBidResponses{
 				"imp-id1": bidStoredResp1,
 				"imp-id2": bidStoredResp2,
@@ -538,11 +614,14 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) {
 		},
 		{
 			description: "Stored bid responses two bidders two imp",
-			requestJson: []byte(`{"imp": [
-    			  {
-    			    "id": "imp-id1",
-    			    "ext": {
-                		"appnexus": {
+			request: openrtb2.BidRequest{
+				Imp: []openrtb2.Imp{
+					{ID: "imp-id1",
+						Ext: json.RawMessage(`{
+                		"bidderA": {
+							"placementId": 123
+                		},
+						"bidderB": {
 							"placementId": 123
                 		},
                 		"prebid": {
@@ -551,12 +630,13 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) {
                         		{"bidder":"bidderB", "id": "2"}
                     		]
                 		}
-            		}
-    			  },
-					{
-    			    "id": "imp-id2",
-    			    "ext": {
-                		"appnexus": {
+            		}`)},
+					{ID: "imp-id2",
+						Ext: json.RawMessage(`{
+                		"bidderA": {
+							"placementId": 123
+                		},
+						"bidderB": {
 							"placementId": 123
                 		},
                 		"prebid": {
@@ -565,9 +645,9 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) {
                         		{"bidder":"bidderB", "id": "2", "replaceimpid": false}
                     		]
                 		}
-            		}
-    			  }
-    			]}`),
+            		}`)},
+				},
+			},
 			expectedStoredAuctionResponses: ImpsWithBidResponses{},
 			expectedStoredBidResponses: ImpBidderStoredResp{
 				"imp-id1": {"bidderA": bidStoredResp1, "bidderB": bidStoredResp2},
@@ -581,17 +661,19 @@ func TestProcessStoredAuctionAndBidResponses(t *testing.T) {
 	}
 
 	for _, test := range testCases {
-		storedAuctionResponses, storedBidResponses, bidderImpReplaceImpId, errorList := ProcessStoredResponses(nil, test.requestJson, fetcher, bidderMap)
-		assert.Equal(t, test.expectedStoredAuctionResponses, storedAuctionResponses, "storedAuctionResponses doesn't match: %s\n", test.description)
-		assert.Equalf(t, test.expectedStoredBidResponses, storedBidResponses, "storedBidResponses doesn't match: %s\n", test.description)
-		assert.Equal(t, test.expectedBidderImpReplaceImpID, bidderImpReplaceImpId, "bidderImpReplaceImpId doesn't match: %s\n", test.description)
-		assert.Nil(t, errorList, "Error should be nil")
+		t.Run(test.description, func(t *testing.T) {
+			rw := openrtb_ext.RequestWrapper{BidRequest: &test.request}
+			storedAuctionResponses, storedBidResponses, bidderImpReplaceImpId, errorList := ProcessStoredResponses(nil, &rw, fetcher)
+			assert.Equal(t, test.expectedStoredAuctionResponses, storedAuctionResponses)
+			assert.Equal(t, test.expectedStoredBidResponses, storedBidResponses)
+			assert.Equal(t, test.expectedBidderImpReplaceImpID, bidderImpReplaceImpId)
+			assert.Nil(t, errorList, "Error should be nil")
+		})
 	}
 
 }
 
 func TestProcessStoredResponsesNotFoundResponse(t *testing.T) {
-	bidderMap := map[string]openrtb_ext.BidderName{"bidderA": "bidderA", "bidderB": "bidderB"}
 	bidStoredResp1 := json.RawMessage(`[{"bid": [{"id": "bid_id1"],"seat": "bidderA"}]`)
 	bidStoredResp2 := json.RawMessage(`[{"bid": [{"id": "bid_id2"],"seat": "bidderB"}]`)
 	mockStoredResponses := map[string]json.RawMessage{
@@ -604,16 +686,16 @@ func TestProcessStoredResponsesNotFoundResponse(t *testing.T) {
 
 	testCases := []struct {
 		description    string
-		requestJson    []byte
+		request        openrtb2.BidRequest
 		expectedErrors []error
 	}{
 		{
 			description: "Stored bid response with nil data, one bidder one imp",
-			requestJson: []byte(`{"imp": [
-    			  {
-    			    "id": "imp-id1",
-    			    "ext": {
-                		"appnexus": {
+			request: openrtb2.BidRequest{
+				Imp: []openrtb2.Imp{
+					{ID: "imp-id1",
+						Ext: json.RawMessage(`{
+                		"bidderB": {
 							"placementId": 123
                 		},
                 		"prebid": {
@@ -621,20 +703,20 @@ func TestProcessStoredResponsesNotFoundResponse(t *testing.T) {
                         		{"bidder":"bidderB", "id": "3"}
                     		]
                 		}
-            		}
-    			  }
-    			]}`),
+            		}`)},
+				},
+			},
 			expectedErrors: []error{
 				errors.New("failed to fetch stored bid response for impId = imp-id1, bidder = bidderB and storedBidResponse id = 3"),
 			},
 		},
 		{
 			description: "Stored bid response with nil data, one bidder, two imps, one with correct stored response",
-			requestJson: []byte(`{"imp": [
-    			  {
-    			    "id": "imp-id1",
-    			    "ext": {
-                		"appnexus": {
+			request: openrtb2.BidRequest{
+				Imp: []openrtb2.Imp{
+					{ID: "imp-id1",
+						Ext: json.RawMessage(`{
+                		"bidderB": {
 							"placementId": 123
                 		},
                 		"prebid": {
@@ -642,12 +724,10 @@ func TestProcessStoredResponsesNotFoundResponse(t *testing.T) {
                         		{"bidder":"bidderB", "id": "1"}
                     		]
                 		}
-            		}
-    			  },
-                  {
-    			    "id": "imp-id2",
-    			    "ext": {
-                		"appnexus": {
+            		}`)},
+					{ID: "imp-id2",
+						Ext: json.RawMessage(`{
+                		"bidderB": {
 							"placementId": 123
                 		},
                 		"prebid": {
@@ -655,20 +735,20 @@ func TestProcessStoredResponsesNotFoundResponse(t *testing.T) {
                         		{"bidder":"bidderB", "id": "3"}
                     		]
                 		}
-            		}
-    			  }
-    			]}`),
+            		}`)},
+				},
+			},
 			expectedErrors: []error{
 				errors.New("failed to fetch stored bid response for impId = imp-id2, bidder = bidderB and storedBidResponse id = 3"),
 			},
 		},
 		{
 			description: "Stored bid response with nil data, one bidder, two imps, both with correct stored response",
-			requestJson: []byte(`{"imp": [
-    			  {
-    			    "id": "imp-id1",
-    			    "ext": {
-                		"appnexus": {
+			request: openrtb2.BidRequest{
+				Imp: []openrtb2.Imp{
+					{ID: "imp-id1",
+						Ext: json.RawMessage(`{
+                		"bidderB": {
 							"placementId": 123
                 		},
                 		"prebid": {
@@ -676,12 +756,10 @@ func TestProcessStoredResponsesNotFoundResponse(t *testing.T) {
                         		{"bidder":"bidderB", "id": "4"}
                     		]
                 		}
-            		}
-    			  },
-                  {
-    			    "id": "imp-id2",
-    			    "ext": {
-                		"appnexus": {
+            		}`)},
+					{ID: "imp-id2",
+						Ext: json.RawMessage(`{
+                		"bidderB": {
 							"placementId": 123
                 		},
                 		"prebid": {
@@ -689,9 +767,9 @@ func TestProcessStoredResponsesNotFoundResponse(t *testing.T) {
                         		{"bidder":"bidderB", "id": "3"}
                     		]
                 		}
-            		}
-    			  }
-    			]}`),
+            		}`)},
+				},
+			},
 			expectedErrors: []error{
 				errors.New("failed to fetch stored bid response for impId = imp-id1, bidder = bidderB and storedBidResponse id = 4"),
 				errors.New("failed to fetch stored bid response for impId = imp-id2, bidder = bidderB and storedBidResponse id = 3"),
@@ -699,10 +777,10 @@ func TestProcessStoredResponsesNotFoundResponse(t *testing.T) {
 		},
 		{
 			description: "Stored auction response with nil data and one imp",
-			requestJson: []byte(`{"imp": [
-    			  {
-    			    "id": "imp-id1",
-    			    "ext": {
+			request: openrtb2.BidRequest{
+				Imp: []openrtb2.Imp{
+					{ID: "imp-id1",
+						Ext: json.RawMessage(`{
                 		"appnexus": {
 							"placementId": 123
                 		},
@@ -711,19 +789,19 @@ func TestProcessStoredResponsesNotFoundResponse(t *testing.T) {
                         		"id": "4"
                     		}
                 		}
-            		}
-    			  }
-    			]}`),
+            		}`)},
+				},
+			},
 			expectedErrors: []error{
 				errors.New("failed to fetch stored auction response for impId = imp-id1 and storedAuctionResponse id = 4"),
 			},
 		},
 		{
 			description: "Stored auction response with nil data, and two imps with nil responses",
-			requestJson: []byte(`{"imp": [
-    			  {
-    			    "id": "imp-id1",
-    			    "ext": {
+			request: openrtb2.BidRequest{
+				Imp: []openrtb2.Imp{
+					{ID: "imp-id1",
+						Ext: json.RawMessage(`{
                 		"appnexus": {
 							"placementId": 123
                 		},
@@ -732,11 +810,9 @@ func TestProcessStoredResponsesNotFoundResponse(t *testing.T) {
                         		"id": "4"
                     		}
                 		}
-            		}
-    			  },
-                  {
-    			    "id": "imp-id2",
-    			    "ext": {
+            		}`)},
+					{ID: "imp-id2",
+						Ext: json.RawMessage(`{
                 		"appnexus": {
 							"placementId": 123
                 		},
@@ -745,9 +821,9 @@ func TestProcessStoredResponsesNotFoundResponse(t *testing.T) {
                         		"id": "3"
                     		}
                 		}
-            		}
-    			  }
-    			]}`),
+            		}`)},
+				},
+			},
 			expectedErrors: []error{
 				errors.New("failed to fetch stored auction response for impId = imp-id1 and storedAuctionResponse id = 4"),
 				errors.New("failed to fetch stored auction response for impId = imp-id2 and storedAuctionResponse id = 3"),
@@ -755,10 +831,10 @@ func TestProcessStoredResponsesNotFoundResponse(t *testing.T) {
 		},
 		{
 			description: "Stored auction response with nil data, two imps, one with nil responses",
-			requestJson: []byte(`{"imp": [
-    			  {
-    			    "id": "imp-id1",
-    			    "ext": {
+			request: openrtb2.BidRequest{
+				Imp: []openrtb2.Imp{
+					{ID: "imp-id1",
+						Ext: json.RawMessage(`{
                 		"appnexus": {
 							"placementId": 123
                 		},
@@ -767,11 +843,9 @@ func TestProcessStoredResponsesNotFoundResponse(t *testing.T) {
                         		"id": "2"
                     		}
                 		}
-            		}
-    			  },
-                  {
-    			    "id": "imp-id2",
-    			    "ext": {
+            		}`)},
+					{ID: "imp-id2",
+						Ext: json.RawMessage(`{
                 		"appnexus": {
 							"placementId": 123
                 		},
@@ -780,9 +854,9 @@ func TestProcessStoredResponsesNotFoundResponse(t *testing.T) {
                         		"id": "3"
                     		}
                 		}
-            		}
-    			  }
-    			]}`),
+            		}`)},
+				},
+			},
 			expectedErrors: []error{
 				errors.New("failed to fetch stored auction response for impId = imp-id2 and storedAuctionResponse id = 3"),
 			},
@@ -790,10 +864,13 @@ func TestProcessStoredResponsesNotFoundResponse(t *testing.T) {
 	}
 
 	for _, test := range testCases {
-		_, _, _, errorList := ProcessStoredResponses(nil, test.requestJson, fetcher, bidderMap)
-		for _, err := range test.expectedErrors {
-			assert.Contains(t, errorList, err, "incorrect errors returned: %s", test.description)
-		}
+		t.Run(test.description, func(t *testing.T) {
+			rw := openrtb_ext.RequestWrapper{BidRequest: &test.request}
+			_, _, _, errorList := ProcessStoredResponses(nil, &rw, fetcher)
+			for _, err := range test.expectedErrors {
+				assert.Contains(t, errorList, err)
+			}
+		})
 	}
 }
 
@@ -847,8 +924,10 @@ func TestFlipMap(t *testing.T) {
 	}
 
 	for _, test := range testCases {
-		actualResult := flipMap(test.inImpBidderReplaceImpID)
-		assert.Equal(t, test.outBidderImpReplaceImpID, actualResult, "Incorrect flipped map for test case %s\n", test.description)
+		t.Run(test.description, func(t *testing.T) {
+			actualResult := flipMap(test.inImpBidderReplaceImpID)
+			assert.Equal(t, test.outBidderImpReplaceImpID, actualResult)
+		})
 	}
 }