Repository: prebid/prebid-server
Pull request #3328 (2023-11-29 16:04:55)

RTBHouse: native support (renewal)
## Type of change
- [x] Feature
- [x] Code style update (formatting, local variables)
- [x] Bugfix

## Description of change
This is a renewal of the PR #3212 which has been reverted by PR #3271. Making a new PR to re-merge the changes. Please do not port this feature to PBS Java (it's already there).

Native ads are now available to be processed and accessed by RTB House adapter. Test coverage has increased significantly.

There is also a little bugfix added to how the adapter handles bid floors. Previous version dropped bid floor defined in a bidder param ("`bidfloor`") when publishers didn't set currency module. Now it is fine with that case and the bidfloor currency is set to the bidder's default (USD).

## Other information
Please reach us at [inventory_support@rtbhouse.com](mailto:inventory_support@rtbhouse.com) with [piotr.jaworski@rtbhouse.com](mailto:piotr.jaworski@rtbhouse.com) and cc [leandro.otani@rtbhouse.com](mailto:leandro.otani@rtbhouse.com).

github-actions[bot]: ## Code coverage summary 
Note: 
- Prebid team doesn't anticipate tests covering code paths that might result in marshal and unmarshal errors 
- Coverage summary encompasses all commits leading up to the latest one, 45257889459be64bb3a0c270f85a3b77d9be7dc3 
#### rtbhouse 
Refer [here](https://htmlpreview.github.io/?https://github.com/prebid/prebid-server/coverage-preview/.github/preview/7035263925_1701273944/rtbhouse.html) for heat map coverage report 
``` 
github.com/prebid/prebid-server/v2/adapters/rtbhouse/rtbhouse.go:28:	Builder			100.0%
github.com/prebid/prebid-server/v2/adapters/rtbhouse/rtbhouse.go:36:	MakeRequests		94.1%
github.com/prebid/prebid-server/v2/adapters/rtbhouse/rtbhouse.go:106:	getImpressionExt	100.0%
github.com/prebid/prebid-server/v2/adapters/rtbhouse/rtbhouse.go:128:	MakeBids		100.0%
github.com/prebid/prebid-server/v2/adapters/rtbhouse/rtbhouse.go:194:	getMediaTypeForBid	100.0%
github.com/prebid/prebid-server/v2/adapters/rtbhouse/rtbhouse.go:205:	getNativeAdm		100.0%
total:									(statements)		97.7%

 ``` 


Patch:
diff --git a/adapters/huaweiads/huaweiads.go b/adapters/huaweiads/huaweiads.go
index 0d4f43e1..06ad88f4 100644
--- a/adapters/huaweiads/huaweiads.go
+++ b/adapters/huaweiads/huaweiads.go
@@ -535,7 +535,7 @@ func getNativeFormat(adslot30 *adslot30, openRTBImp *openrtb2.Imp) error {
 	}
 
 	//popular size for native ads
-	popularSizes := []map[string]int64{{"w": 225, "h": 150}, {"w": 300, "h": 250}, {"w": 320, "h": 250}, {"w": 640, "h": 360}, {"w": 1080, "h": 170}, {"w": 1080, "h": 430}, {"w": 1080, "h": 432}, {"w": 1080, "h": 504}, {"w": 1080, "h": 607}, {"w": 1080, "h": 1620}, {"w": 1200, "h": 627}, {"w": 1280, "h": 720}, {"w": 1312, "h": 768}, {"w": 1920, "h": 1080}}
+	popularSizes := []format{{W: 225, H: 150}, {W: 1080, H: 607}, {W: 300, H: 250}, {W: 1080, H: 1620}, {W: 1280, H: 720}, {W: 640, H: 360}, {W: 1080, H: 1920}, {W: 720, H: 1280}}
 
 	// only compute the main image number, type = native1.ImageAssetTypeMain
 	var numMainImage = 0
@@ -555,11 +555,21 @@ func getNativeFormat(adslot30 *adslot30, openRTBImp *openrtb2.Imp) error {
 			}
 		}
 	}
+
+	sizeMap := make(map[format]struct{})
+	for _, size := range popularSizes {
+		sizeMap[size] = struct{}{}
+	}
+
 	for _, asset := range nativePayload.Assets {
 		// Only one of the {title,img,video,data} objects should be present in each object.
 		if asset.Video != nil {
 			numVideo++
-			continue
+			formats = popularSizes
+			_, ok := sizeMap[format{W: asset.Video.W, H: asset.Video.H}]
+			if (asset.Video.W != 0 && asset.Video.H != 0) && !ok {
+				formats = append(formats, format{asset.Video.W, asset.Video.H})
+			}
 		}
 		// every image has the same W, H.
 		if asset.Img != nil {
@@ -570,37 +580,38 @@ func getNativeFormat(adslot30 *adslot30, openRTBImp *openrtb2.Imp) error {
 				}
 				if numFormat == 1 && asset.Img.H != 0 && asset.Img.W != 0 && asset.Img.WMin != 0 && asset.Img.HMin != 0 {
 					result := filterPopularSizes(popularSizes, asset.Img.W, asset.Img.H, "ratio")
-					for i := 0; i < len(result); i++ {
-						formats = append(formats, format{result[i]["w"], result[i]["h"]})
-					}
+					formats = append(formats, result...)
 				}
 				if numFormat == 1 && asset.Img.H == 0 && asset.Img.W == 0 && asset.Img.WMin != 0 && asset.Img.HMin != 0 {
-					result := filterPopularSizes(popularSizes, asset.Img.W, asset.Img.H, "range")
-					for i := 0; i < len(result); i++ {
-						formats = append(formats, format{result[i]["w"], result[i]["h"]})
-					}
+					result := filterPopularSizes(popularSizes, asset.Img.WMin, asset.Img.HMin, "range")
+					formats = append(formats, result...)
 				}
 			}
 		}
 		adslot30.Format = formats
 	}
-	detailedCreativeTypeList = append(detailedCreativeTypeList, "901", "905")
+	if numVideo >= 1 {
+		detailedCreativeTypeList = append(detailedCreativeTypeList, "903")
+	}
+	if numMainImage >= 1 {
+		detailedCreativeTypeList = append(detailedCreativeTypeList, "901", "904", "905")
+	}
 	adslot30.DetailedCreativeTypeList = detailedCreativeTypeList
 	return nil
 }
 
 // filter popular size by range or ratio to append format array
-func filterPopularSizes(sizes []map[string]int64, width int64, height int64, byWhat string) []map[string]int64 {
+func filterPopularSizes(sizes []format, width int64, height int64, byWhat string) []format {
 
-	filtered := []map[string]int64{}
+	filtered := []format{}
 	for _, size := range sizes {
-		w := size["w"]
-		h := size["h"]
+		w := size.W
+		h := size.H
 
 		if byWhat == "ratio" {
 			ratio := float64(width) / float64(height)
 			diff := math.Abs(float64(w)/float64(h) - ratio)
-			if diff <= 0.3 {
+			if diff <= 0.5 {
 				filtered = append(filtered, size)
 			}
 		}
diff --git a/adapters/rtbhouse/rtbhouse.go b/adapters/rtbhouse/rtbhouse.go
index 089634cb..92e0e57b 100644
--- a/adapters/rtbhouse/rtbhouse.go
+++ b/adapters/rtbhouse/rtbhouse.go
@@ -2,10 +2,12 @@ package rtbhouse
 
 import (
 	"encoding/json"
+	"errors"
 	"fmt"
 	"net/http"
 	"strings"
 
+	"github.com/buger/jsonparser"
 	"github.com/prebid/openrtb/v19/openrtb2"
 	"github.com/prebid/prebid-server/v2/adapters"
 	"github.com/prebid/prebid-server/v2/config"
@@ -49,9 +51,12 @@ func (adapter *RTBHouseAdapter) MakeRequests(
 			if err != nil {
 				return nil, []error{err}
 			}
-			if rtbhouseExt.BidFloor > 0 && len(reqCopy.Cur) > 0 {
-				bidFloorCur = reqCopy.Cur[0]
+			if rtbhouseExt.BidFloor > 0 {
 				bidFloor = rtbhouseExt.BidFloor
+				bidFloorCur = BidderCurrency
+				if len(reqCopy.Cur) > 0 {
+					bidFloorCur = reqCopy.Cur[0]
+				}
 			}
 		}
 
@@ -156,13 +161,63 @@ func (adapter *RTBHouseAdapter) MakeBids(
 	for _, seatBid := range openRTBBidderResponse.SeatBid {
 		for _, bid := range seatBid.Bid {
 			bid := bid // pin! -> https://github.com/kyoh86/scopelint#whats-this
-			typedBid = &adapters.TypedBid{Bid: &bid, BidType: "banner"}
-			bidderResponse.Bids = append(bidderResponse.Bids, typedBid)
+			bidType, err := getMediaTypeForBid(bid)
+			if err != nil {
+				errs = append(errs, err)
+				continue
+			} else {
+				typedBid = &adapters.TypedBid{
+					Bid:     &bid,
+					BidType: bidType,
+				}
+
+				// for native bid responses fix Adm field
+				if typedBid.BidType == openrtb_ext.BidTypeNative {
+					bid.AdM, err = getNativeAdm(bid.AdM)
+					if err != nil {
+						errs = append(errs, err)
+						continue
+					}
+				}
+
+				bidderResponse.Bids = append(bidderResponse.Bids, typedBid)
+			}
 		}
 	}
 
 	bidderResponse.Currency = BidderCurrency
 
-	return bidderResponse, nil
+	return bidderResponse, errs
+
+}
+
+func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) {
+	switch bid.MType {
+	case openrtb2.MarkupBanner:
+		return openrtb_ext.BidTypeBanner, nil
+	case openrtb2.MarkupNative:
+		return openrtb_ext.BidTypeNative, nil
+	default:
+		return "", fmt.Errorf("unrecognized bid type in response from rtbhouse for bid %s", bid.ImpID)
+	}
+}
+
+func getNativeAdm(adm string) (string, error) {
+	nativeAdm := make(map[string]interface{})
+	err := json.Unmarshal([]byte(adm), &nativeAdm)
+	if err != nil {
+		return adm, errors.New("unable to unmarshal native adm")
+	}
+
+	// move bid.adm.native to bid.adm
+	if _, ok := nativeAdm["native"]; ok {
+		//using jsonparser to avoid marshaling, encode escape, etc.
+		value, dataType, _, err := jsonparser.Get([]byte(adm), string(openrtb_ext.BidTypeNative))
+		if err != nil || dataType != jsonparser.Object {
+			return adm, errors.New("unable to get native adm")
+		}
+		adm = string(value)
+	}
 
+	return adm, nil
 }
diff --git a/adapters/yieldmo/yieldmo.go b/adapters/yieldmo/yieldmo.go
index 795d32b8..69841e88 100644
--- a/adapters/yieldmo/yieldmo.go
+++ b/adapters/yieldmo/yieldmo.go
@@ -30,6 +30,10 @@ type Ext struct {
 	Gpid        string `json:"gpid,omitempty"`
 }
 
+type ExtBid struct {
+	MediaType string `json:"mediatype,omitempty"`
+}
+
 func (a *YieldmoAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
 	var errs []error
 	var adapterRequests []*adapters.RequestData
@@ -138,14 +142,18 @@ func (a *YieldmoAdapter) MakeBids(internalRequest *openrtb2.BidRequest, external
 
 	for _, sb := range bidResp.SeatBid {
 		for i := range sb.Bid {
+			bidType, err := getMediaTypeForImp(sb.Bid[i])
+			if err != nil {
+				continue
+			}
+
 			bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{
 				Bid:     &sb.Bid[i],
-				BidType: getMediaTypeForImp(sb.Bid[i].ImpID, internalRequest.Imp),
+				BidType: bidType,
 			})
 		}
 	}
 	return bidResponse, nil
-
 }
 
 // Builder builds a new instance of the Yieldmo adapter for the given bidder with the given config.
@@ -156,12 +164,21 @@ func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server co
 	return bidder, nil
 }
 
-func getMediaTypeForImp(impId string, imps []openrtb2.Imp) openrtb_ext.BidType {
-	//default to video unless banner exists in impression
-	for _, imp := range imps {
-		if imp.ID == impId && imp.Banner != nil {
-			return openrtb_ext.BidTypeBanner
-		}
+// Retrieve the media type corresponding to the bid from the bid.ext object
+func getMediaTypeForImp(bid openrtb2.Bid) (openrtb_ext.BidType, error) {
+	var bidExt ExtBid
+	if err := json.Unmarshal(bid.Ext, &bidExt); err != nil {
+		return "", &errortypes.BadInput{Message: err.Error()}
+	}
+
+	switch bidExt.MediaType {
+	case "banner":
+		return openrtb_ext.BidTypeBanner, nil
+	case "video":
+		return openrtb_ext.BidTypeVideo, nil
+	case "native":
+		return openrtb_ext.BidTypeNative, nil
+	default:
+		return "", fmt.Errorf("invalid BidType: %s", bidExt.MediaType)
 	}
-	return openrtb_ext.BidTypeVideo
 }
diff --git a/endpoints/setuid.go b/endpoints/setuid.go
index f9c55fc8..aae31f10 100644
--- a/endpoints/setuid.go
+++ b/endpoints/setuid.go
@@ -126,7 +126,6 @@ func NewSetUIDEndpoint(cfg *config.Configuration, syncersByBidder map[string]use
 				handleBadStatus(w, http.StatusBadRequest, metrics.SetUidBadRequest, err, metricsEngine, &so)
 				return
 			}
-			w.Write([]byte("Warning: " + err.Error()))
 		}
 
 		tcf2Cfg := tcf2CfgBuilder(cfg.GDPR.TCF2, account.GDPR)
diff --git a/exchange/exchange.go b/exchange/exchange.go
index 211d82fc..446dfaf9 100644
--- a/exchange/exchange.go
+++ b/exchange/exchange.go
@@ -762,6 +762,7 @@ func (e *exchange) getAllBids(
 					} else {
 						adapterBids[bidderName] = seatBid
 					}
+					extraRespInfo.bidsFound = true
 				}
 				// collect fledgeAuctionConfigs separately from bids, as empty seatBids may be discarded
 				extraRespInfo.fledge = collectFledgeFromSeatBid(extraRespInfo.fledge, bidderName, brw.adapter, seatBid)
@@ -769,10 +770,6 @@ func (e *exchange) getAllBids(
 		}
 		//but we need to add all bidders data to adapterExtra to have metrics and other metadata
 		adapterExtra[brw.bidder] = brw.adapterExtra
-
-		if !extraRespInfo.bidsFound && adapterBids[brw.bidder] != nil && len(adapterBids[brw.bidder].Bids) > 0 {
-			extraRespInfo.bidsFound = true
-		}
 	}
 
 	return adapterBids, adapterExtra, extraRespInfo
diff --git a/static/bidder-info/embimedia.yaml b/static/bidder-info/embimedia.yaml
new file mode 100644
index 00000000..9cfa1546
--- /dev/null
+++ b/static/bidder-info/embimedia.yaml
@@ -0,0 +1,2 @@
+endpoint: "http://ads-pbs.bidder-embi.media/openrtb/{{.PublisherID}}?host={{.Host}}"
+aliasOf: "limelightDigital"
diff --git a/static/bidder-info/rtbhouse.yaml b/static/bidder-info/rtbhouse.yaml
index ad2fbfcb..b80cc0ff 100644
--- a/static/bidder-info/rtbhouse.yaml
+++ b/static/bidder-info/rtbhouse.yaml
@@ -7,6 +7,7 @@ capabilities:
   site:
     mediaTypes:
       - banner
+      - native
 userSync:
   # rtbhouse supports user syncing, but requires configuration by the host. contact this
   # bidder directly at the email address in this file to ask about enabling user sync.


Test patch:
diff --git a/adapters/huaweiads/huaweiadstest/exemplary/nativeIncludeVideo.json b/adapters/huaweiads/huaweiadstest/exemplary/nativeIncludeVideo.json
index 49562dac..c38c4124 100644
--- a/adapters/huaweiads/huaweiadstest/exemplary/nativeIncludeVideo.json
+++ b/adapters/huaweiads/huaweiadstest/exemplary/nativeIncludeVideo.json
@@ -5,7 +5,7 @@
       {
         "id": "test-imp-id",
         "native": {
-          "request": "{\"context\":2,\"contextsubtype\":20,\"plcmttype\":1,\"plcmtcnt\":1,\"seq\":0,\"aurlsupport\":0,\"durlsupport\":0,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"privacy\":0,\"assets\":[{\"id\":100,\"title\":{\"len\":90},\"required\":1},{\"id\":101,\"img\":{\"type\":3,\"w\":200,\"h\":300,\"wmin\":300,\"hmin\":200},\"required\":1},{\"id\":102,\"img\":{\"type\":3,\"w\":400,\"h\":500,\"wmin\":400,\"hmin\":500},\"required\":1},{\"id\":103,\"img\":{\"type\":3,\"w\":300,\"h\":250,\"wmin\":300,\"hmin\":250},\"required\":1},{\"id\":105,\"data\":{\"type\":2,\"len\":90},\"required\":1}],\"ver\":\"1.2\"}",
+          "request": "{\"context\":2,\"contextsubtype\":20,\"plcmttype\":1,\"plcmtcnt\":1,\"seq\":0,\"aurlsupport\":0,\"durlsupport\":0,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"privacy\":0,\"assets\":[{\"id\":100,\"title\":{\"len\":90},\"required\":1},{\"id\":101,\"img\":{\"type\":3,\"wmin\":1080,\"hmin\":607},\"required\":1},{\"id\":107,\"video\":{\"mimes\":[\"mp4\"],\"minduration\":100,\"maxduration\":100,\"protocols\":[1,2]},\"required\":1},{\"id\":105,\"data\":{\"type\":2,\"len\":90},\"required\":1}],\"ver\":\"1.2\"}",
           "ver": "1.2"
         },
         "ext": {
@@ -21,14 +21,15 @@
       }
     ],
     "app": {
-      "bundle": "com.huawei.p11",
+      "bundle": "com.huawei.browser",
       "name": "Huawei Browser",
       "ver": "9.1.0.301"
     },
     "device": {
       "ua": "useragent",
       "h": 1920,
-      "language": "en",
+      "language": "zh",
+      "geoCountry": "CH",
       "model": "COL-TEST",
       "os": "android",
       "osv": "10.0.0",
@@ -38,10 +39,12 @@
       "ip": "152.193.6.74",
       "pxratio": 23.01,
       "geo": {
-        "country": "ARG"
+        "country": ""
       }
     },
     "user": {
+      "id": "db089de9-a62e-4861-a881-0ff15e052516",
+      "buyeruid": "v4_bidder_token",
       "ext": {
         "data": {
           "gaid": [
@@ -80,44 +83,28 @@
         "body": {
           "app": {
             "lang": "en",
-            "country": "AR",
+            "country": "ZA",
             "name": "Huawei Browser",
-            "pkgname": "com.example.pkgname2",
+            "pkgname": "com.huawei.browser",
             "version": "9.1.0.301"
           },
           "multislot": [
             {
               "adtype": 3,
               "slotid": "u42ohmaufh",
-              "detailedCreativeTypeList": [
-                "901",
-                "905"
-              ],
-              "format": [
-                {
-                    "w": 200,
-                    "h": 300
-                },
-                {
-                    "w": 400,
-                    "h": 500
-                },
-                {
-                    "w": 300,
-                    "h": 250
-                }
-            ],
+              "detailedCreativeTypeList":["903","901","904","905"],
+              "format":[{"w":225,"h":150},{"w":1080,"h":607},{"w":300,"h":250},{"w":1080,"h":1620},{"w":1280,"h":720},{"w":640,"h":360},{"w":1080,"h":1920},{"w":720,"h":1280}],
               "test": 1
             }
           ],
           "device": {
             "height": 1920,
-            "language": "en",
+            "language": "zh",
             "oaid": "oaid",
             "os": "android",
             "type": 4,
             "ip": "152.193.6.74",
-            "localeCountry": "AR",
+            "localeCountry": "ZA",
             "pxratio": 23.01,
             "model": "COL-TEST",
             "width": 1080,
@@ -126,7 +113,7 @@
             "useragent": "useragent",
             "version": "10.0.0",
             "maker": "huawei",
-            "belongCountry": "AR"
+            "belongCountry": "ZA"
           },
           "geo": {
           },
@@ -156,7 +143,7 @@
                   "metaData": {
                     "adSign": "2",
                     "apkInfo": {
-                      "appIcon": "https://icon.png",
+                      "appIcon": "https://pps-icon.png",
                       "appName": "%E6%89%8B%E6%9C%BA%E6%B7%98%E5%AE%9D",
                       "fileSize": 118902470,
                       "packageName": "com.demo.package",
@@ -181,80 +168,61 @@
                         "height": 160,
                         "imageType": "img",
                         "sha256": "042479eccbda9a8d7d3aa3da73c42486854407835623a30ffff875cb578242d0",
-                        "url": "https://icon1.png",
-                        "width": 160
-                      },
-                      {
-                        "checkSha256Flag": 1,
-                        "fileSize": 10797,
-                        "height": 320,
-                        "imageType": "img",
-                        "sha256": "042479eccbda9a8d7d3aa3da73c42486854407835623a30ffff875cb578242d0",
-                        "url": "https://icon2.png",
+                        "url": "https://pps-icon.png",
                         "width": 160
                       }
                     ],
                     "imageInfo": [
                       {
                         "checkSha256Flag": 0,
-                        "height": 350,
+                        "height": 607,
                         "imageType": "img",
                         "sha256": "8baa56fdb2702b9fb044d95b328936160cd245764375cdb25a4ab504f4ae2e19",
                         "url": "http://image1.jpg",
-                        "width": 400
-                      },
-                      {
-                        "checkSha256Flag": 0,
-                        "height": 300,
-                        "imageType": "img",
-                        "sha256": "8baa56fdb2702b9fb044d95b328936160cd245764375cdb25a4ab504f4ae2e19",
-                        "url": "http://image2.jpg",
-                        "width": 400
-                      },
-                      {
-                        "checkSha256Flag": 0,
-                        "height": 300,
-                        "imageType": "img",
-                        "sha256": "8baa56fdb2702b9fb044d95b328936160cd245764375cdb25a4ab504f4ae2e19",
-                        "url": "http://image3.jpg",
-                        "width": 400
+                        "width": 1080
                       }
                     ],
                     "label": "%E6%89%8B%E6%9C%BA%E6%B7%98%E5%AE%9D",
                     "landingPageType": "3",
                     "marketAppId": "C101219405",
                     "title": "%2Ftest%2F",
-                    "description": "this is a test ad"
+                    "description": "this is a test ad",
+                    "videoInfo": {
+                      "autoPlayAreaRatio": 100,
+                      "autoStopPlayAreaRatio": 10,
+                      "checkSha256Flag": 1,
+                      "sha256": "aa08c8ffce82bbcd37cabefd6c8972b407de48f0b4e332e06d4cc18d25377d77",
+                      "timeBeforeVideoAutoPlay": 50,
+                      "videoAutoPlayOnWifi": "y",
+                      "videoAutoPlayWithSound": "n",
+                      "videoDownloadUrl": "https://video.mp4",
+                      "videoDuration": 6038,
+                      "videoFileSize": 949951,
+                      "videoPlayMode": 2,
+                      "videoRatio": 0.5625,
+                      "width": 600,
+                      "height": 500
+                    }
                   },
                   "monitor": [
                     {
-                      "eventType": "click",
-                      "url": [
-                        "http://test/click"
-                      ]
-                    },
-                    {
-                      "eventType": "imp",
-                      "url": [
-                        "http://test/imp"
-                      ]
-                    },
-                    {
-                      "eventType": "download",
+                      "eventType": "vastError",
                       "url": [
-                        "http://test/download"
+                        "http://test/vastError"
                       ]
                     },
                     {
-                      "eventType": "install",
+                      "eventType": "click",
                       "url": [
-                        "http://test/install"
+                        "http://test/click",
+                        "http://test/dspclick"
                       ]
                     },
                     {
-                      "eventType": "downloadstart",
+                      "eventType": "imp",
                       "url": [
-                        "http://test/downloadstart"
+                        "http://test/imp",
+                        "http://test/dspimp"
                       ]
                     },
                     {
@@ -272,7 +240,8 @@
                     {
                       "eventType": "playEnd",
                       "url": [
-                        "http://test/playEnd"
+                        "http://test/playEnd1",
+                        "http://test/playEnd2"
                       ]
                     },
                     {
@@ -332,12 +301,12 @@
               "huaweiads"
             ],
             "crid": "58022259",
-            "adm": "{\"ver\":\"1.2\",\"assets\":[{\"id\":100,\"title\":{\"text\":\"/test/\",\"len\":6}},{\"id\":101,\"img\":{\"type\":3,\"url\":\"http://image1.jpg\",\"w\":400,\"h\":350}},{\"id\":102,\"img\":{\"type\":3,\"url\":\"http://image2.jpg\",\"w\":400,\"h\":300}},{\"id\":103,\"img\":{\"type\":3,\"url\":\"http://image3.jpg\",\"w\":400,\"h\":300}},{\"id\":105,\"data\":{\"label\":\"desc\",\"value\":\"this is a test ad\"}}],\"link\":{\"url\":\"https://ads.huawei.com/usermgtportal/home/index.html#/\",\"clicktrackers\":[\"http://test/click\"]},\"eventtrackers\":[{\"event\":1,\"method\":1,\"url\":\"http://test/imp\"}]}",
+            "adm": "{\"ver\":\"1.2\",\"assets\":[{\"id\":100,\"title\":{\"text\":\"/test/\",\"len\":6}},{\"id\":101,\"img\":{\"type\":3,\"url\":\"http://image1.jpg\",\"w\":1080,\"h\":607}},{\"id\":107,\"video\":{\"vasttag\":\"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?><VAST version=\\\"3.0\\\"><Ad id=\\\"58022259\\\"><InLine><AdSystem>HuaweiAds</AdSystem><AdTitle>/test/</AdTitle><Error><![CDATA[http://test/vastError&et=[ERRORCODE]]]></Error><Impression><![CDATA[http://test/imp]]></Impression><Impression><![CDATA[http://test/dspimp]]></Impression><Creatives><Creative adId=\\\"58022259\\\" id=\\\"58022259\\\"><Linear><Duration>00:00:06.038</Duration><TrackingEvents><Tracking event=\\\"skip\\\"><![CDATA[http://test/userclose]]></Tracking><Tracking event=\\\"closeLinear\\\"><![CDATA[http://test/userclose]]></Tracking><Tracking event=\\\"start\\\"><![CDATA[http://test/playStart]]></Tracking><Tracking event=\\\"complete\\\"><![CDATA[http://test/playEnd1]]></Tracking><Tracking event=\\\"complete\\\"><![CDATA[http://test/playEnd2]]></Tracking><Tracking event=\\\"resume\\\"><![CDATA[http://test/playResume]]></Tracking><Tracking event=\\\"pause\\\"><![CDATA[http://test/playPause]]></Tracking></TrackingEvents><VideoClicks><ClickThrough><![CDATA[https://ads.huawei.com/usermgtportal/home/index.html#/]]></ClickThrough><ClickTracking><![CDATA[http://test/click]]></ClickTracking><ClickTracking><![CDATA[http://test/dspclick]]></ClickTracking></VideoClicks><MediaFiles><MediaFile delivery=\\\"progressive\\\" type=\\\"video/mp4\\\" width=\\\"600\\\" height=\\\"500\\\" scalable=\\\"true\\\" maintainAspectRatio=\\\"true\\\"> <![CDATA[https://video.mp4]]></MediaFile></MediaFiles></Linear></Creative></Creatives></InLine></Ad></VAST>\"}},{\"id\":105,\"data\":{\"label\":\"desc\",\"value\":\"this is a test ad\"}}],\"link\":{\"url\":\"https://ads.huawei.com/usermgtportal/home/index.html#/\",\"clicktrackers\":[\"http://test/click\",\"http://test/dspclick\"]},\"eventtrackers\":[{\"event\":1,\"method\":1,\"url\":\"http://test/imp\"},{\"event\":1,\"method\":1,\"url\":\"http://test/dspimp\"}]}",
             "id": "test-imp-id",
             "impid": "test-imp-id",
             "price": 2.8,
-            "h": 350,
-            "w": 400
+            "h": 500,
+            "w": 600
           },
           "type": "native"
         }
diff --git a/adapters/huaweiads/huaweiadstest/exemplary/nativeMultiSizesByRange.json b/adapters/huaweiads/huaweiadstest/exemplary/nativeMultiSizesByRange.json
index 92d62bac..97679a3b 100644
--- a/adapters/huaweiads/huaweiadstest/exemplary/nativeMultiSizesByRange.json
+++ b/adapters/huaweiads/huaweiadstest/exemplary/nativeMultiSizesByRange.json
@@ -92,9 +92,10 @@
                 "slotid": "u42ohmaufh",
                 "detailedCreativeTypeList": [
                   "901",
+                  "904",
                   "905"
                 ],
-                "format":[{"w":225,"h":150},{"w":300,"h":250},{"w":320,"h":250},{"w":640,"h":360},{"w":1080,"h":170},{"w":1080,"h":430},{"w":1080,"h":432},{"w":1080,"h":504},{"w":1080,"h":607},{"w":1080,"h":1620},{"w":1200,"h":627},{"w":1280,"h":720},{"w":1312,"h":768},{"w":1920,"h":1080}],
+                "format":[{"w":1080,"h":607},{"w":300,"h":250},{"w":1080,"h":1620},{"w":1280,"h":720},{"w":640,"h":360},{"w":1080,"h":1920},{"w":720,"h":1280}],
                 "test": 1
               }
             ],
diff --git a/adapters/huaweiads/huaweiadstest/exemplary/nativeMultiSizesByRatio.json b/adapters/huaweiads/huaweiadstest/exemplary/nativeMultiSizesByRatio.json
index cd21f40e..e9c50bae 100644
--- a/adapters/huaweiads/huaweiadstest/exemplary/nativeMultiSizesByRatio.json
+++ b/adapters/huaweiads/huaweiadstest/exemplary/nativeMultiSizesByRatio.json
@@ -92,9 +92,10 @@
                 "slotid": "u42ohmaufh",
                 "detailedCreativeTypeList": [
                   "901",
+                  "904",
                   "905"
                 ],
-              "format": [{"w":225,"h":150},{"w":320,"h":250},{"w":640,"h":360},{"w":1080,"h":607},{"w":1280,"h":720},{"w":1312,"h":768},{"w":1920,"h":1080}],
+                "format":[{"w":225,"h":150},{"w":1080,"h":607},{"w":300,"h":250},{"w":1280,"h":720},{"w":640,"h":360}],
                 "test": 1
               }
             ],
diff --git a/adapters/huaweiads/huaweiadstest/exemplary/nativeSingleImage.json b/adapters/huaweiads/huaweiadstest/exemplary/nativeSingleImage.json
index 4faec81d..4ba3adce 100644
--- a/adapters/huaweiads/huaweiadstest/exemplary/nativeSingleImage.json
+++ b/adapters/huaweiads/huaweiadstest/exemplary/nativeSingleImage.json
@@ -92,66 +92,10 @@
               "slotid": "u42ohmaufh",
               "detailedCreativeTypeList": [
                 "901",
+                "904",
                 "905"
               ],
-              "format": [
-                {
-                    "w": 225,
-                    "h": 150
-                },
-                {
-                    "w": 300,
-                    "h": 250
-                },
-                {
-                    "w": 320,
-                    "h": 250
-                },
-                {
-                    "w": 640,
-                    "h": 360
-                },
-                {
-                    "w": 1080,
-                    "h": 170
-                },
-                {
-                    "w": 1080,
-                    "h": 430
-                },
-                {
-                    "w": 1080,
-                    "h": 432
-                },
-                {
-                    "w": 1080,
-                    "h": 504
-                },
-                {
-                    "w": 1080,
-                    "h": 607
-                },
-                {
-                    "w": 1080,
-                    "h": 1620
-                },
-                {
-                    "w": 1200,
-                    "h": 627
-                },
-                {
-                    "w": 1280,
-                    "h": 720
-                },
-                {
-                    "w": 1312,
-                    "h": 768
-                },
-                {
-                    "w": 1920,
-                    "h": 1080
-                }
-            ],
+              "format":[{"w":1080,"h":607},{"w":300,"h":250},{"w":1080,"h":1620},{"w":1280,"h":720},{"w":640,"h":360},{"w":1080,"h":1920},{"w":720,"h":1280}],
               "test": 1
             }
           ],
diff --git a/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImage.json b/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImage.json
index 49562dac..240dee2d 100644
--- a/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImage.json
+++ b/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImage.json
@@ -91,6 +91,7 @@
               "slotid": "u42ohmaufh",
               "detailedCreativeTypeList": [
                 "901",
+                "904",
                 "905"
               ],
               "format": [
diff --git a/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImageIncludeIcon.json b/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImageIncludeIcon.json
index 6c33294b..3f4222c2 100644
--- a/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImageIncludeIcon.json
+++ b/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImageIncludeIcon.json
@@ -92,66 +92,10 @@
               "slotid": "u42ohmaufh",
               "detailedCreativeTypeList": [
                 "901",
+                "904",
                 "905"
               ],
-              "format": [
-                {
-                    "w": 225,
-                    "h": 150
-                },
-                {
-                    "w": 300,
-                    "h": 250
-                },
-                {
-                    "w": 320,
-                    "h": 250
-                },
-                {
-                    "w": 640,
-                    "h": 360
-                },
-                {
-                    "w": 1080,
-                    "h": 170
-                },
-                {
-                    "w": 1080,
-                    "h": 430
-                },
-                {
-                    "w": 1080,
-                    "h": 432
-                },
-                {
-                    "w": 1080,
-                    "h": 504
-                },
-                {
-                    "w": 1080,
-                    "h": 607
-                },
-                {
-                    "w": 1080,
-                    "h": 1620
-                },
-                {
-                    "w": 1200,
-                    "h": 627
-                },
-                {
-                    "w": 1280,
-                    "h": 720
-                },
-                {
-                    "w": 1312,
-                    "h": 768
-                },
-                {
-                    "w": 1920,
-                    "h": 1080
-                }
-            ],
+              "format":[{"w":1080,"h":607},{"w":300,"h":250},{"w":1080,"h":1620},{"w":1280,"h":720},{"w":640,"h":360},{"w":1080,"h":1920},{"w":720,"h":1280}],
               "test": 1
             }
           ],
diff --git a/adapters/huaweiads/huaweiadstest/supplemental/bad_response_not_native.json b/adapters/huaweiads/huaweiadstest/supplemental/bad_response_not_native.json
index 75bf3f25..10814d7e 100644
--- a/adapters/huaweiads/huaweiadstest/supplemental/bad_response_not_native.json
+++ b/adapters/huaweiads/huaweiadstest/supplemental/bad_response_not_native.json
@@ -5,7 +5,7 @@
       {
         "id": "test-imp-id",
         "native": {
-          "request": "{\"context\":2,\"contextsubtype\":20,\"plcmttype\":1,\"plcmtcnt\":1,\"seq\":0,\"aurlsupport\":0,\"durlsupport\":0,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"privacy\":0,\"assets\":[{\"id\":100,\"title\":{\"len\":90},\"required\":1},{\"id\":101,\"img\":{\"type\":3,\"wmin\":200,\"hmin\":200},\"required\":1},{\"id\":107,\"video\":{\"mimes\":[\"mp4\"],\"minduration\":100,\"maxduration\":100,\"protocols\":[1,2]},\"required\":1},{\"id\":105,\"data\":{\"type\":2,\"len\":90},\"required\":1}],\"ver\":\"1.2\"}",
+          "request": "{\"context\":2,\"contextsubtype\":20,\"plcmttype\":1,\"plcmtcnt\":1,\"seq\":0,\"aurlsupport\":0,\"durlsupport\":0,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"privacy\":0,\"assets\":[{\"id\":100,\"title\":{\"len\":90},\"required\":1},{\"id\":107,\"video\":{\"mimes\":[\"mp4\"],\"minduration\":100,\"maxduration\":100,\"protocols\":[1,2]},\"required\":1},{\"id\":105,\"data\":{\"type\":2,\"len\":90},\"required\":1}],\"ver\":\"1.2\"}",
           "ver": "1.2"
         },
         "ext": {
@@ -91,68 +91,43 @@
               "adtype": 3,
               "slotid": "m8x9x3rzff",
               "test": 1,
-              "detailedCreativeTypeList": [
-                "901",
-                "905"
-              ],
               "format": [
                 {
                     "w": 225,
                     "h": 150
                 },
-                {
-                    "w": 300,
-                    "h": 250
-                },
-                {
-                    "w": 320,
-                    "h": 250
-                },
-                {
-                    "w": 640,
-                    "h": 360
-                },
                 {
                     "w": 1080,
-                    "h": 170
-                },
-                {
-                    "w": 1080,
-                    "h": 430
-                },
-                {
-                    "w": 1080,
-                    "h": 432
-                },
-                {
-                    "w": 1080,
-                    "h": 504
+                    "h": 607
                 },
                 {
-                    "w": 1080,
-                    "h": 607
+                    "w": 300,
+                    "h": 250
                 },
                 {
                     "w": 1080,
                     "h": 1620
                 },
-                {
-                    "w": 1200,
-                    "h": 627
-                },
                 {
                     "w": 1280,
                     "h": 720
                 },
                 {
-                    "w": 1312,
-                    "h": 768
+                    "w": 640,
+                    "h": 360
+                },
+                {
+                    "w": 1080,
+                    "h": 1920
                 },
                 {
-                    "w": 1920,
-                    "h": 1080
+                    "w": 720,
+                    "h": 1280
                 }
-            ]
+            ],
+              "detailedCreativeTypeList": [
+                "903"
+              ]
             }
           ],
           "device": {
diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-bidder-param-without-cur.json b/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-bidder-param-without-cur.json
new file mode 100644
index 00000000..79aa038c
--- /dev/null
+++ b/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-bidder-param-without-cur.json
@@ -0,0 +1,130 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "imp": [
+      {
+        "id": "test-imp-id",
+        "banner": {
+          "format": [
+            {
+              "w": 300,
+              "h": 250
+            }
+          ]
+        },
+        "ext": {
+          "bidder": {
+            "publisherId": "12345",
+            "bidfloor": 3.00
+          }
+        }
+      }
+    ],
+    "ext": {
+      "prebid": {
+        "currency": {
+          "rates": {
+            "EUR": {
+              "USD": 0.05
+            }
+          },
+          "usepbsrates": false
+        }
+      }
+    }
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "http://localhost/prebid_server",
+        "body": {
+          "id": "test-request-id",
+          "cur": [
+            "USD"
+          ],
+          "imp": [
+            {
+              "banner": {
+                "format": [
+                  {
+                    "h": 250,
+                    "w": 300
+                  }
+                ]
+              },
+              "bidfloor": 3.00,
+              "bidfloorcur": "USD",
+              "ext": {
+                "bidder": {
+                  "publisherId": "12345",
+                  "bidfloor": 3.00
+                }
+              },
+              "id": "test-imp-id"
+            }
+          ],
+          "ext": {
+            "prebid": {
+              "currency": {
+                "rates": {
+                  "EUR": {
+                    "USD": 0.05
+                  }
+                },
+                "usepbsrates": false
+              }
+            }
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "test-response-id",
+          "cur": "USD",
+          "seatbid": [
+            {
+              "seat": "rtbhouse",
+              "bid": [
+                {
+                  "id": "randomid",
+                  "impid": "test-imp-id",
+                  "price": 300,
+                  "adid": "12345678",
+                  "adm": "some-test-ad",
+                  "cid": "987",
+                  "crid": "12345678",
+                  "h": 250,
+                  "w": 300,
+                  "mtype": 1
+                }
+              ]
+            }
+          ]
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": [
+        {
+          "bid": {
+            "id": "randomid",
+            "impid": "test-imp-id",
+            "price": 300,
+            "adid": "12345678",
+            "adm": "some-test-ad",
+            "cid": "987",
+            "crid": "12345678",
+            "h": 250,
+            "w": 300,
+            "mtype": 1
+          },
+          "type": "banner"
+        }
+      ]
+    }
+  ]
+}
diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-bidder-param.json b/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-bidder-param.json
new file mode 100644
index 00000000..99b3a87e
--- /dev/null
+++ b/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-bidder-param.json
@@ -0,0 +1,133 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "cur": [
+      "EUR"
+    ],
+    "imp": [
+      {
+        "id": "test-imp-id",
+        "banner": {
+          "format": [
+            {
+              "w": 300,
+              "h": 250
+            }
+          ]
+        },
+        "ext": {
+          "bidder": {
+            "publisherId": "12345",
+            "bidfloor": 2
+          }
+        }
+      }
+    ],
+    "ext": {
+      "prebid": {
+        "currency": {
+          "rates": {
+            "EUR": {
+              "USD": 0.05
+            }
+          },
+          "usepbsrates": false
+        }
+      }
+    }
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "http://localhost/prebid_server",
+        "body": {
+          "id": "test-request-id",
+          "cur": [
+            "USD"
+          ],
+          "imp": [
+            {
+              "banner": {
+                "format": [
+                  {
+                    "h": 250,
+                    "w": 300
+                  }
+                ]
+              },
+              "bidfloor": 0.1,
+              "bidfloorcur": "USD",
+              "ext": {
+                "bidder": {
+                  "publisherId": "12345",
+                  "bidfloor": 2
+                }
+              },
+              "id": "test-imp-id"
+            }
+          ],
+          "ext": {
+            "prebid": {
+              "currency": {
+                "rates": {
+                  "EUR": {
+                    "USD": 0.05
+                  }
+                },
+                "usepbsrates": false
+              }
+            }
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "test-response-id",
+          "cur": "USD",
+          "seatbid": [
+            {
+              "seat": "rtbhouse",
+              "bid": [
+                {
+                  "id": "randomid",
+                  "impid": "test-imp-id",
+                  "price": 300,
+                  "adid": "12345678",
+                  "adm": "some-test-ad",
+                  "cid": "987",
+                  "crid": "12345678",
+                  "h": 250,
+                  "w": 300,
+                  "mtype": 1
+                }
+              ]
+            }
+          ]
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": [
+        {
+          "bid": {
+            "id": "randomid",
+            "impid": "test-imp-id",
+            "price": 300,
+            "adid": "12345678",
+            "adm": "some-test-ad",
+            "cid": "987",
+            "crid": "12345678",
+            "h": 250,
+            "w": 300,
+            "mtype": 1
+          },
+          "type": "banner"
+        }
+      ]
+    }
+  ]
+}
diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-impbidfloor-with-cur.json b/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-impbidfloor-with-cur.json
new file mode 100644
index 00000000..85e8a1c2
--- /dev/null
+++ b/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-impbidfloor-with-cur.json
@@ -0,0 +1,130 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "imp": [
+      {
+        "id": "test-imp-id",
+        "banner": {
+          "format": [
+            {
+              "w": 300,
+              "h": 250
+            }
+          ]
+        },
+        "bidfloor": 1.00,
+        "bidfloorcur": "EUR",
+        "ext": {
+          "bidder": {
+            "publisherId": "12345"
+          }
+        }
+      }
+    ],
+    "ext": {
+      "prebid": {
+        "currency": {
+          "rates": {
+            "EUR": {
+              "USD": 0.05
+            }
+          },
+          "usepbsrates": false
+        }
+      }
+    }
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "http://localhost/prebid_server",
+        "body": {
+          "id": "test-request-id",
+          "cur": [
+            "USD"
+          ],
+          "imp": [
+            {
+              "banner": {
+                "format": [
+                  {
+                    "h": 250,
+                    "w": 300
+                  }
+                ]
+              },
+              "bidfloor": 0.05,
+              "bidfloorcur": "USD",
+              "ext": {
+                "bidder": {
+                  "publisherId": "12345"
+                }
+              },
+              "id": "test-imp-id"
+            }
+          ],
+          "ext": {
+            "prebid": {
+              "currency": {
+                "rates": {
+                  "EUR": {
+                    "USD": 0.05
+                  }
+                },
+                "usepbsrates": false
+              }
+            }
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "test-response-id",
+          "cur": "USD",
+          "seatbid": [
+            {
+              "seat": "rtbhouse",
+              "bid": [
+                {
+                  "id": "randomid",
+                  "impid": "test-imp-id",
+                  "price": 300,
+                  "adid": "12345678",
+                  "adm": "some-test-ad",
+                  "cid": "987",
+                  "crid": "12345678",
+                  "h": 250,
+                  "w": 300,
+                  "mtype": 1
+                }
+              ]
+            }
+          ]
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": [
+        {
+          "bid": {
+            "id": "randomid",
+            "impid": "test-imp-id",
+            "price": 300,
+            "adid": "12345678",
+            "adm": "some-test-ad",
+            "cid": "987",
+            "crid": "12345678",
+            "h": 250,
+            "w": 300,
+            "mtype": 1
+          },
+          "type": "banner"
+        }
+      ]
+    }
+  ]
+}
diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-impbidfloor-without-cur.json b/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-impbidfloor-without-cur.json
new file mode 100644
index 00000000..14179657
--- /dev/null
+++ b/adapters/rtbhouse/rtbhousetest/exemplary/bidfloor-as-impbidfloor-without-cur.json
@@ -0,0 +1,128 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "imp": [
+      {
+        "id": "test-imp-id",
+        "banner": {
+          "format": [
+            {
+              "w": 300,
+              "h": 250
+            }
+          ]
+        },
+        "bidfloor": 1.00,
+        "ext": {
+          "bidder": {
+            "publisherId": "12345"
+          }
+        }
+      }
+    ],
+    "ext": {
+      "prebid": {
+        "currency": {
+          "rates": {
+            "EUR": {
+              "USD": 0.05
+            }
+          },
+          "usepbsrates": false
+        }
+      }
+    }
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "http://localhost/prebid_server",
+        "body": {
+          "id": "test-request-id",
+          "cur": [
+            "USD"
+          ],
+          "imp": [
+            {
+              "banner": {
+                "format": [
+                  {
+                    "h": 250,
+                    "w": 300
+                  }
+                ]
+              },
+              "bidfloor": 1,
+              "ext": {
+                "bidder": {
+                  "publisherId": "12345"
+                }
+              },
+              "id": "test-imp-id"
+            }
+          ],
+          "ext": {
+            "prebid": {
+              "currency": {
+                "rates": {
+                  "EUR": {
+                    "USD": 0.05
+                  }
+                },
+                "usepbsrates": false
+              }
+            }
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "test-response-id",
+          "cur": "USD",
+          "seatbid": [
+            {
+              "seat": "rtbhouse",
+              "bid": [
+                {
+                  "id": "randomid",
+                  "impid": "test-imp-id",
+                  "price": 300,
+                  "adid": "12345678",
+                  "adm": "some-test-ad",
+                  "cid": "987",
+                  "crid": "12345678",
+                  "h": 250,
+                  "w": 300,
+                  "mtype": 1
+                }
+              ]
+            }
+          ]
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": [
+        {
+          "bid": {
+            "id": "randomid",
+            "impid": "test-imp-id",
+            "price": 300,
+            "adid": "12345678",
+            "adm": "some-test-ad",
+            "cid": "987",
+            "crid": "12345678",
+            "h": 250,
+            "w": 300,
+            "mtype": 1
+          },
+          "type": "banner"
+        }
+      ]
+    }
+  ]
+}
diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/currency-conversion.json b/adapters/rtbhouse/rtbhousetest/exemplary/currency-conversion.json
deleted file mode 100644
index 95bfb1e4..00000000
--- a/adapters/rtbhouse/rtbhousetest/exemplary/currency-conversion.json
+++ /dev/null
@@ -1,123 +0,0 @@
-{
-    "mockBidRequest": {
-      "id": "test-request-id",
-      "imp": [
-        {
-          "id": "test-imp-id",
-          "banner": {
-            "format": [
-              {
-                "w": 300,
-                "h": 250
-              }
-            ]
-          },
-          "bidfloor": 1.00,
-          "bidfloorcur": "EUR",
-          "ext": {
-            "bidder": {
-              "placementId": "12345"
-            }
-          }
-        }
-      ],
-      "ext": {
-        "prebid": {
-          "currency": {
-            "rates": {
-              "EUR": {
-                "USD": 0.05
-              }
-            },
-            "usepbsrates": false
-          }
-        }
-      }
-    },
-    "httpCalls": [
-      {
-        "expectedRequest": {
-          "uri": "http://localhost/prebid_server",
-          "body": {
-            "id": "test-request-id",
-            "cur": ["USD"],
-            "imp": [
-              {
-                "banner": {
-                  "format": [
-                    {
-                      "h": 250,
-                      "w": 300
-                    }
-                  ]
-                },
-                "bidfloor": 0.05,
-                "bidfloorcur": "USD",
-                "ext": {
-                  "bidder": {
-                    "placementId": "12345"
-                  }
-                },
-                "id": "test-imp-id"
-              }
-            ],
-            "ext": {
-              "prebid": {
-                "currency": {
-                  "rates": {
-                    "EUR": {
-                      "USD": 0.05
-                    }
-                  },
-                  "usepbsrates": false
-                }
-              }
-             }
-          }
-        },
-        "mockResponse": {
-          "status": 200,
-          "body": {
-            "id": "test-response-id",
-            "cur": "USD",
-            "seatbid": [{
-              "seat": "rtbhouse",
-              "bid": [{
-                "id": "randomid",
-                "impid": "test-imp-id",
-                "price": 300,
-                "adid": "12345678",
-                "adm": "some-test-ad",
-                "cid": "987",
-                "crid": "12345678",
-                "h": 250,
-                "w": 300
-                }
-              ]
-            }]
-          }
-        }
-      }
-    ],
-    "expectedBidResponses": [
-      {
-        "currency": "USD",
-        "bids": [
-          {
-            "bid": {
-              "id": "randomid",
-              "impid": "test-imp-id",
-              "price": 300,
-              "adid": "12345678",
-              "adm": "some-test-ad",
-              "cid": "987",
-              "crid": "12345678",
-              "h": 250,
-              "w": 300
-            },
-            "type": "banner"
-          }
-        ]
-      }
-    ]
-  }
diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/native-with-deprecated-native-prop.json b/adapters/rtbhouse/rtbhousetest/exemplary/native-with-deprecated-native-prop.json
new file mode 100644
index 00000000..e79b21a1
--- /dev/null
+++ b/adapters/rtbhouse/rtbhousetest/exemplary/native-with-deprecated-native-prop.json
@@ -0,0 +1,100 @@
+{
+  "mockBidRequest": {
+    "imp": [
+      {
+        "ext": {
+          "bidder": {}
+        },
+        "id": "test-native-imp",
+        "native": {
+          "request": "{\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140}},{\"id\":1,\"required\":1,\"data\":{\"type\":2}},{\"id\":2,\"required\":1,\"img\":{\"type\":3}}]}",
+          "ver": "1.2"
+        }
+      }
+    ],
+    "site": {
+      "page": "https://good.site/url"
+    },
+    "id": "test-native-request",
+    "ext": {},
+    "debug": 1
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "http://localhost/prebid_server",
+        "body": {
+          "id": "test-native-request",
+          "cur": [
+            "USD"
+          ],
+          "imp": [
+            {
+              "id": "test-native-imp",
+              "native": {
+                "request": "{\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140}},{\"id\":1,\"required\":1,\"data\":{\"type\":2}},{\"id\":2,\"required\":1,\"img\":{\"type\":3}}]}",
+                "ver": "1.2"
+              },
+              "ext": {
+                "bidder": {}
+              }
+            }
+          ],
+          "site": {
+            "page": "https://good.site/url"
+          },
+          "ext": {}
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "test-native-request",
+          "bidid": "test-bidid",
+          "cur": "USD",
+          "seatbid": [
+            {
+              "seat": "rtbhouse",
+              "bid": [
+                {
+                  "id": "test-native-request",
+                  "impid": "test-native-imp",
+                  "price": 0.5,
+                  "adid": "test-adid",
+                  "adm": "{\"native\":{\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"title\":{\"text\":\"title text\"}},{\"id\":1,\"data\":{\"value\":\"data value\"}},{\"id\":2,\"img\":{\"url\":\"image.url\",\"w\":1200,\"h\":628}}],\"link\":{\"url\":\"link.url\"},\"imptrackers\":[\"imp.tracker.url\"],\"eventtrackers\":[{\"event\":1,\"method\":1,\"url\":\"event.tracker.url\"}]}}",
+                  "adomain": [ "adomain.com" ],
+                  "cid": "test-cid",
+                  "crid": "test-crid",
+                  "dealid": "test-dealid",
+                  "mtype": 4
+                }
+              ]
+            }
+          ]
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": [
+        {
+          "bid": {
+            "id": "test-native-request",
+            "impid": "test-native-imp",
+            "price": 0.5,
+            "adid": "test-adid",
+            "adm": "{\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"title\":{\"text\":\"title text\"}},{\"id\":1,\"data\":{\"value\":\"data value\"}},{\"id\":2,\"img\":{\"url\":\"image.url\",\"w\":1200,\"h\":628}}],\"link\":{\"url\":\"link.url\"},\"imptrackers\":[\"imp.tracker.url\"],\"eventtrackers\":[{\"event\":1,\"method\":1,\"url\":\"event.tracker.url\"}]}",
+            "adomain": [ "adomain.com" ],
+            "cid": "test-cid",
+            "crid": "test-crid",
+            "dealid": "test-dealid",
+            "mtype": 4
+          },
+          "type": "native"
+        }
+      ]
+    }
+  ]
+}
diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/native-with-proper-native-response.json b/adapters/rtbhouse/rtbhousetest/exemplary/native-with-proper-native-response.json
new file mode 100644
index 00000000..9f5962fd
--- /dev/null
+++ b/adapters/rtbhouse/rtbhousetest/exemplary/native-with-proper-native-response.json
@@ -0,0 +1,100 @@
+{
+  "mockBidRequest": {
+    "imp": [
+      {
+        "ext": {
+          "bidder": {}
+        },
+        "id": "test-native-imp",
+        "native": {
+          "request": "{\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140}},{\"id\":1,\"required\":1,\"data\":{\"type\":2}},{\"id\":2,\"required\":1,\"img\":{\"type\":3}}]}",
+          "ver": "1.2"
+        }
+      }
+    ],
+    "site": {
+      "page": "https://good.site/url"
+    },
+    "id": "test-native-request",
+    "ext": {},
+    "debug": 1
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "http://localhost/prebid_server",
+        "body": {
+          "id": "test-native-request",
+          "cur": [
+            "USD"
+          ],
+          "imp": [
+            {
+              "id": "test-native-imp",
+              "native": {
+                "request": "{\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140}},{\"id\":1,\"required\":1,\"data\":{\"type\":2}},{\"id\":2,\"required\":1,\"img\":{\"type\":3}}]}",
+                "ver": "1.2"
+              },
+              "ext": {
+                "bidder": {}
+              }
+            }
+          ],
+          "site": {
+            "page": "https://good.site/url"
+          },
+          "ext": {}
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "test-native-request",
+          "bidid": "test-bidid",
+          "cur": "USD",
+          "seatbid": [
+            {
+              "seat": "rtbhouse",
+              "bid": [
+                {
+                  "id": "test-native-request",
+                  "impid": "test-native-imp",
+                  "price": 0.5,
+                  "adid": "test-adid",
+                  "adm": "{\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"title\":{\"text\":\"title text\"}},{\"id\":1,\"data\":{\"value\":\"data value\"}},{\"id\":2,\"img\":{\"url\":\"image.url\",\"w\":1200,\"h\":628}}],\"link\":{\"url\":\"link.url\"},\"imptrackers\":[\"imp.tracker.url\"],\"eventtrackers\":[{\"event\":1,\"method\":1,\"url\":\"event.tracker.url\"}]}",
+                  "adomain": [ "adomain.com" ],
+                  "cid": "test-cid",
+                  "crid": "test-crid",
+                  "dealid": "test-dealid",
+                  "mtype": 4
+                }
+              ]
+            }
+          ]
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": [
+        {
+          "bid": {
+            "id": "test-native-request",
+            "impid": "test-native-imp",
+            "price": 0.5,
+            "adid": "test-adid",
+            "adm": "{\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"title\":{\"text\":\"title text\"}},{\"id\":1,\"data\":{\"value\":\"data value\"}},{\"id\":2,\"img\":{\"url\":\"image.url\",\"w\":1200,\"h\":628}}],\"link\":{\"url\":\"link.url\"},\"imptrackers\":[\"imp.tracker.url\"],\"eventtrackers\":[{\"event\":1,\"method\":1,\"url\":\"event.tracker.url\"}]}",
+            "adomain": [ "adomain.com" ],
+            "cid": "test-cid",
+            "crid": "test-crid",
+            "dealid": "test-dealid",
+            "mtype": 4
+          },
+          "type": "native"
+        }
+      ]
+    }
+  ]
+}
diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/simple-banner.json b/adapters/rtbhouse/rtbhousetest/exemplary/simple-banner.json
index 2a8c4681..468e73f2 100644
--- a/adapters/rtbhouse/rtbhousetest/exemplary/simple-banner.json
+++ b/adapters/rtbhouse/rtbhousetest/exemplary/simple-banner.json
@@ -56,7 +56,8 @@
                         "cid": "987",
                         "crid": "12345678",
                         "h": 250,
-                        "w": 300
+                        "w": 300,
+                        "mtype": 1
                     }]
                 }],
                 "cur": "USD"
@@ -76,7 +77,8 @@
                 "cid": "987",
                 "crid": "12345678",
                 "w": 300,
-                "h": 250
+                "h": 250,
+                "mtype": 1
             },
             "type": "banner"
         }]
diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/two-bidfloors-given-param-and-impbidfloor.json b/adapters/rtbhouse/rtbhousetest/exemplary/two-bidfloors-given-param-and-impbidfloor.json
new file mode 100644
index 00000000..fc706d97
--- /dev/null
+++ b/adapters/rtbhouse/rtbhousetest/exemplary/two-bidfloors-given-param-and-impbidfloor.json
@@ -0,0 +1,132 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "imp": [
+      {
+        "id": "test-imp-id",
+        "banner": {
+          "format": [
+            {
+              "w": 300,
+              "h": 250
+            }
+          ]
+        },
+        "bidfloor": 1.00,
+        "bidfloorcur": "EUR",
+        "ext": {
+          "bidder": {
+            "publisherId": "12345",
+            "bidfloor": 2.00
+          }
+        }
+      }
+    ],
+    "ext": {
+      "prebid": {
+        "currency": {
+          "rates": {
+            "EUR": {
+              "USD": 0.05
+            }
+          },
+          "usepbsrates": false
+        }
+      }
+    }
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "http://localhost/prebid_server",
+        "body": {
+          "id": "test-request-id",
+          "cur": [
+            "USD"
+          ],
+          "imp": [
+            {
+              "banner": {
+                "format": [
+                  {
+                    "h": 250,
+                    "w": 300
+                  }
+                ]
+              },
+              "bidfloor": 0.05,
+              "bidfloorcur": "USD",
+              "ext": {
+                "bidder": {
+                  "publisherId": "12345",
+                  "bidfloor": 2
+                }
+              },
+              "id": "test-imp-id"
+            }
+          ],
+          "ext": {
+            "prebid": {
+              "currency": {
+                "rates": {
+                  "EUR": {
+                    "USD": 0.05
+                  }
+                },
+                "usepbsrates": false
+              }
+            }
+          }
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "test-response-id",
+          "cur": "USD",
+          "seatbid": [
+            {
+              "seat": "rtbhouse",
+              "bid": [
+                {
+                  "id": "randomid",
+                  "impid": "test-imp-id",
+                  "price": 300,
+                  "adid": "12345678",
+                  "adm": "some-test-ad",
+                  "cid": "987",
+                  "crid": "12345678",
+                  "h": 250,
+                  "w": 300,
+                  "mtype": 1
+                }
+              ]
+            }
+          ]
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": [
+        {
+          "bid": {
+            "id": "randomid",
+            "impid": "test-imp-id",
+            "price": 300,
+            "adid": "12345678",
+            "adm": "some-test-ad",
+            "cid": "987",
+            "crid": "12345678",
+            "h": 250,
+            "w": 300,
+            "mtype": 1
+          },
+          "type": "banner"
+        }
+      ]
+    }
+  ]
+}
diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/banner-native-req-faulty-mtype-in-native.json b/adapters/rtbhouse/rtbhousetest/supplemental/banner-native-req-faulty-mtype-in-native.json
new file mode 100644
index 00000000..6e6f415a
--- /dev/null
+++ b/adapters/rtbhouse/rtbhousetest/supplemental/banner-native-req-faulty-mtype-in-native.json
@@ -0,0 +1,141 @@
+{
+  "mockBidRequest": {
+    "imp": [
+      {
+        "ext": {
+          "bidder": {}
+        },
+        "id": "test-native-imp",
+        "native": {
+          "request": "{\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140}},{\"id\":1,\"required\":1,\"data\":{\"type\":2}},{\"id\":2,\"required\":1,\"img\":{\"type\":3}}]}",
+          "ver": "1.2"
+        }
+      },
+      {
+        "id": "test-banner-imp",
+        "banner": {
+            "format": [{
+                "w": 300,
+                "h": 250
+            }]
+        },
+        "ext": {
+            "bidder": {}
+        }
+    }
+    ],
+    "site": {
+      "page": "https://good.site/url"
+    },
+    "id": "test-multi-slot-request",
+    "ext": {},
+    "debug": 1
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "http://localhost/prebid_server",
+        "body": {
+          "id": "test-multi-slot-request",
+          "cur": [
+            "USD"
+          ],
+          "imp": [
+            {
+              "id": "test-native-imp",
+              "native": {
+                "request": "{\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140}},{\"id\":1,\"required\":1,\"data\":{\"type\":2}},{\"id\":2,\"required\":1,\"img\":{\"type\":3}}]}",
+                "ver": "1.2"
+              },
+              "ext": {
+                "bidder": {}
+              }
+            },
+            {
+              "id": "test-banner-imp",
+              "banner": {
+                  "format": [{
+                      "w": 300,
+                      "h": 250
+                  }]
+              },
+              "ext": {
+                  "bidder": {}
+              }
+          }
+          ],
+          "site": {
+            "page": "https://good.site/url"
+          },
+          "ext": {}
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "test-multi-slot-request",
+          "bidid": "test-bidid",
+          "cur": "USD",
+          "seatbid": [
+            {
+              "seat": "rtbhouse",
+              "bid": [
+                {
+                  "id": "randomid-native",
+                  "impid": "test-native-imp",
+                  "price": 0.5,
+                  "adid": "test-adid",
+                  "adm": "{\"native\":{\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"title\":{\"text\":\"title text\"}},{\"id\":1,\"data\":{\"value\":\"data value\"}},{\"id\":2,\"img\":{\"url\":\"image.url\",\"w\":1200,\"h\":628}}],\"link\":{\"url\":\"link.url\"},\"imptrackers\":[\"imp.tracker.url\"],\"eventtrackers\":[{\"event\":1,\"method\":1,\"url\":\"event.tracker.url\"}]}}",
+                  "adomain": [ "adomain.com" ],
+                  "cid": "test-cid",
+                  "crid": "test-crid",
+                  "dealid": "test-dealid",
+                  "mtype": 99
+                },
+                {
+                  "id": "randomid-banner",
+                  "impid": "test-banner-imp",
+                  "price": 0.500000,
+                  "adid": "12345678",
+                  "adm": "some-test-ad",
+                  "cid": "987",
+                  "crid": "12345678",
+                  "h": 250,
+                  "w": 300,
+                  "mtype": 1
+              }
+              ]
+            }
+          ]
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": [{
+          "bid": {
+            "id": "randomid-banner",
+            "impid": "test-banner-imp",
+            "price": 0.500000,
+            "adid": "12345678",
+            "adm": "some-test-ad",
+            "cid": "987",
+            "crid": "12345678",
+            "h": 250,
+            "w": 300,
+            "mtype": 1
+          },
+          "type": "banner"
+        }
+      ]
+    }
+  ],
+  "expectedMakeBidsErrors": [
+    {
+      "value": "unrecognized bid type in response from rtbhouse for bid test-native-imp",
+      "comparison": "literal"
+    }
+  ]
+}
diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/faulty-request-bidder-params.json b/adapters/rtbhouse/rtbhousetest/supplemental/faulty-request-bidder-params.json
new file mode 100644
index 00000000..70fddf62
--- /dev/null
+++ b/adapters/rtbhouse/rtbhousetest/supplemental/faulty-request-bidder-params.json
@@ -0,0 +1,30 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "imp": [
+      {
+        "id": "banner-imp-id",
+        "banner": {
+          "format": [
+            {
+              "w": 300,
+              "h": 250
+            }
+          ]
+        },
+        "ext": {
+          "bidder": {
+            "publisherId": 12345
+          }
+        }
+      }
+    ],
+    "ext": {}
+  },
+  "expectedMakeRequestsErrors": [
+    {
+      "value": "Error while unmarshaling bidder extension",
+      "comparison": "literal"
+    }
+  ]
+}
diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/faulty-request-no-impext.json b/adapters/rtbhouse/rtbhousetest/supplemental/faulty-request-no-impext.json
new file mode 100644
index 00000000..f416f810
--- /dev/null
+++ b/adapters/rtbhouse/rtbhousetest/supplemental/faulty-request-no-impext.json
@@ -0,0 +1,25 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "imp": [
+      {
+        "id": "banner-imp-id",
+        "banner": {
+          "format": [
+            {
+              "w": 300,
+              "h": 250
+            }
+          ]
+        }
+      }
+    ],
+    "ext": {}
+  },
+  "expectedMakeRequestsErrors": [
+    {
+      "value": "Bidder extension not provided or can't be unmarshalled",
+      "comparison": "literal"
+    }
+  ]
+}
diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/native-with-faulty-adm-native-prop.json b/adapters/rtbhouse/rtbhousetest/supplemental/native-with-faulty-adm-native-prop.json
new file mode 100644
index 00000000..5e1aa0ef
--- /dev/null
+++ b/adapters/rtbhouse/rtbhousetest/supplemental/native-with-faulty-adm-native-prop.json
@@ -0,0 +1,90 @@
+{
+  "mockBidRequest": {
+    "imp": [
+      {
+        "ext": {
+          "bidder": {}
+        },
+        "id": "test-native-imp",
+        "native": {
+          "request": "{\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140}},{\"id\":1,\"required\":1,\"data\":{\"type\":2}},{\"id\":2,\"required\":1,\"img\":{\"type\":3}}]}",
+          "ver": "1.2"
+        }
+      }
+    ],
+    "site": {
+      "page": "https://good.site/url"
+    },
+    "id": "test-native-request",
+    "ext": {},
+    "debug": 1
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "http://localhost/prebid_server",
+        "body": {
+          "id": "test-native-request",
+          "cur": [
+            "USD"
+          ],
+          "imp": [
+            {
+              "id": "test-native-imp",
+              "native": {
+                "request": "{\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140}},{\"id\":1,\"required\":1,\"data\":{\"type\":2}},{\"id\":2,\"required\":1,\"img\":{\"type\":3}}]}",
+                "ver": "1.2"
+              },
+              "ext": {
+                "bidder": {}
+              }
+            }
+          ],
+          "site": {
+            "page": "https://good.site/url"
+          },
+          "ext": {}
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "test-native-request",
+          "bidid": "test-bidid",
+          "cur": "USD",
+          "seatbid": [
+            {
+              "seat": "rtbhouse",
+              "bid": [
+                {
+                  "id": "test-native-request",
+                  "impid": "test-native-imp",
+                  "price": 0.5,
+                  "adid": "test-adid",
+                  "adm": "{\"native\":\"faulty object\"}",
+                  "adomain": [ "adomain.com" ],
+                  "cid": "test-cid",
+                  "crid": "test-crid",
+                  "dealid": "test-dealid",
+                  "mtype": 4
+                }
+              ]
+            }
+          ]
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": []
+    }
+  ],
+  "expectedMakeBidsErrors": [
+    {
+      "value": "unable to get native adm",
+      "comparison": "literal"
+    }
+  ]
+}
diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/native-with-faulty-adm-response.json b/adapters/rtbhouse/rtbhousetest/supplemental/native-with-faulty-adm-response.json
new file mode 100644
index 00000000..41cc909f
--- /dev/null
+++ b/adapters/rtbhouse/rtbhousetest/supplemental/native-with-faulty-adm-response.json
@@ -0,0 +1,90 @@
+{
+  "mockBidRequest": {
+    "imp": [
+      {
+        "ext": {
+          "bidder": {}
+        },
+        "id": "test-native-imp",
+        "native": {
+          "request": "{\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140}},{\"id\":1,\"required\":1,\"data\":{\"type\":2}},{\"id\":2,\"required\":1,\"img\":{\"type\":3}}]}",
+          "ver": "1.2"
+        }
+      }
+    ],
+    "site": {
+      "page": "https://good.site/url"
+    },
+    "id": "test-native-request",
+    "ext": {},
+    "debug": 1
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "http://localhost/prebid_server",
+        "body": {
+          "id": "test-native-request",
+          "cur": [
+            "USD"
+          ],
+          "imp": [
+            {
+              "id": "test-native-imp",
+              "native": {
+                "request": "{\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]}],\"ver\":\"1.2\",\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140}},{\"id\":1,\"required\":1,\"data\":{\"type\":2}},{\"id\":2,\"required\":1,\"img\":{\"type\":3}}]}",
+                "ver": "1.2"
+              },
+              "ext": {
+                "bidder": {}
+              }
+            }
+          ],
+          "site": {
+            "page": "https://good.site/url"
+          },
+          "ext": {}
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "test-native-request",
+          "bidid": "test-bidid",
+          "cur": "USD",
+          "seatbid": [
+            {
+              "seat": "rtbhouse",
+              "bid": [
+                {
+                  "id": "test-native-request",
+                  "impid": "test-native-imp",
+                  "price": 0.5,
+                  "adid": "test-adid",
+                  "adm": "{\"ver\":\"1.2\"",
+                  "adomain": [ "adomain.com" ],
+                  "cid": "test-cid",
+                  "crid": "test-crid",
+                  "dealid": "test-dealid",
+                  "mtype": 4
+                }
+              ]
+            }
+          ]
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": []
+    }
+  ],
+  "expectedMakeBidsErrors": [
+    {
+      "value": "unable to unmarshal native adm",
+      "comparison": "literal"
+    }
+  ]
+}
diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/simple-banner-bad-mtype.json b/adapters/rtbhouse/rtbhousetest/supplemental/simple-banner-bad-mtype.json
new file mode 100644
index 00000000..fc52cc30
--- /dev/null
+++ b/adapters/rtbhouse/rtbhousetest/supplemental/simple-banner-bad-mtype.json
@@ -0,0 +1,94 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "site": {
+      "page": "https://good.site/url"
+    },
+    "imp": [
+      {
+        "id": "test-imp-id",
+        "banner": {
+          "format": [
+            {
+              "w": 300,
+              "h": 250
+            }
+          ]
+        },
+        "ext": {
+          "bidder": {}
+        }
+      }
+    ]
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "http://localhost/prebid_server",
+        "body": {
+          "id": "test-request-id",
+          "cur": [
+            "USD"
+          ],
+          "site": {
+            "page": "https://good.site/url"
+          },
+          "imp": [
+            {
+              "id": "test-imp-id",
+              "banner": {
+                "format": [
+                  {
+                    "w": 300,
+                    "h": 250
+                  }
+                ]
+              },
+              "ext": {
+                "bidder": {}
+              }
+            }
+          ]
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "test-request-id",
+          "seatbid": [
+            {
+              "seat": "rtbhouse",
+              "bid": [
+                {
+                  "id": "randomid",
+                  "impid": "test-imp-id",
+                  "price": 0.500000,
+                  "adid": "12345678",
+                  "adm": "some-test-ad",
+                  "cid": "987",
+                  "crid": "12345678",
+                  "h": 250,
+                  "w": 300,
+                  "mtype": 99
+                }
+              ]
+            }
+          ],
+          "cur": "USD"
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": []
+    }
+  ],
+  "expectedMakeBidsErrors": [
+    {
+      "value": "unrecognized bid type in response from rtbhouse for bid test-imp-id",
+      "comparison": "literal"
+    }
+  ]
+}
diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/simple-banner-no-mtype.json b/adapters/rtbhouse/rtbhousetest/supplemental/simple-banner-no-mtype.json
new file mode 100644
index 00000000..8bb9e8a1
--- /dev/null
+++ b/adapters/rtbhouse/rtbhousetest/supplemental/simple-banner-no-mtype.json
@@ -0,0 +1,93 @@
+{
+  "mockBidRequest": {
+    "id": "test-request-id",
+    "site": {
+      "page": "https://good.site/url"
+    },
+    "imp": [
+      {
+        "id": "test-imp-id",
+        "banner": {
+          "format": [
+            {
+              "w": 300,
+              "h": 250
+            }
+          ]
+        },
+        "ext": {
+          "bidder": {}
+        }
+      }
+    ]
+  },
+  "httpCalls": [
+    {
+      "expectedRequest": {
+        "uri": "http://localhost/prebid_server",
+        "body": {
+          "id": "test-request-id",
+          "cur": [
+            "USD"
+          ],
+          "site": {
+            "page": "https://good.site/url"
+          },
+          "imp": [
+            {
+              "id": "test-imp-id",
+              "banner": {
+                "format": [
+                  {
+                    "w": 300,
+                    "h": 250
+                  }
+                ]
+              },
+              "ext": {
+                "bidder": {}
+              }
+            }
+          ]
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "id": "test-request-id",
+          "seatbid": [
+            {
+              "seat": "rtbhouse",
+              "bid": [
+                {
+                  "id": "randomid",
+                  "impid": "test-imp-id",
+                  "price": 0.500000,
+                  "adid": "12345678",
+                  "adm": "some-test-ad",
+                  "cid": "987",
+                  "crid": "12345678",
+                  "h": 250,
+                  "w": 300
+                }
+              ]
+            }
+          ],
+          "cur": "USD"
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": []
+    }
+  ],
+  "expectedMakeBidsErrors": [
+    {
+      "value": "unrecognized bid type in response from rtbhouse for bid test-imp-id",
+      "comparison": "literal"
+    }
+  ]
+}
diff --git a/adapters/yieldmo/yieldmotest/exemplary/app-banner.json b/adapters/yieldmo/yieldmotest/exemplary/app-banner.json
index e674cf11..92609cae 100644
--- a/adapters/yieldmo/yieldmotest/exemplary/app-banner.json
+++ b/adapters/yieldmo/yieldmotest/exemplary/app-banner.json
@@ -65,7 +65,11 @@
                   "adm": "some-test-ad",
                   "crid": "crid_10",
                   "h": 250,
-                  "w": 300
+                  "w": 300,
+                  "ext":
+                  {
+                    "mediatype": "banner"
+                  }
                 }
               ]
             }
@@ -87,7 +91,11 @@
             "adm": "some-test-ad",
             "crid": "crid_10",
             "w": 300,
-            "h": 250
+            "h": 250,
+            "ext":
+            {
+              "mediatype": "banner"
+            }
           },
           "type": "banner"
         }
diff --git a/adapters/yieldmo/yieldmotest/exemplary/app_video.json b/adapters/yieldmo/yieldmotest/exemplary/app_video.json
index e33c37f6..6f94a30b 100644
--- a/adapters/yieldmo/yieldmotest/exemplary/app_video.json
+++ b/adapters/yieldmo/yieldmotest/exemplary/app_video.json
@@ -63,7 +63,11 @@
                   "adm": "some-test-ad",
                   "crid": "crid_10",
                   "h": 250,
-                  "w": 300
+                  "w": 300,
+                  "ext":
+                  {
+                    "mediatype": "video"
+                  }
                 }
               ]
             }
@@ -85,7 +89,11 @@
             "adm": "some-test-ad",
             "crid": "crid_10",
             "w": 300,
-            "h": 250
+            "h": 250,
+            "ext":
+            {
+              "mediatype": "video"
+            }
           },
           "type": "video"
         }
diff --git a/adapters/yieldmo/yieldmotest/exemplary/simple-banner.json b/adapters/yieldmo/yieldmotest/exemplary/simple-banner.json
index 11739ca1..ba243500 100644
--- a/adapters/yieldmo/yieldmotest/exemplary/simple-banner.json
+++ b/adapters/yieldmo/yieldmotest/exemplary/simple-banner.json
@@ -65,7 +65,11 @@
                   "adm": "some-test-ad",
                   "crid": "crid_10",
                   "h": 250,
-                  "w": 300
+                  "w": 300,
+                  "ext":
+                    {
+                      "mediatype": "banner"
+                    }
                 }
               ]
             }
@@ -87,7 +91,11 @@
             "adm": "some-test-ad",
             "crid": "crid_10",
             "w": 300,
-            "h": 250
+            "h": 250,
+            "ext":
+            {
+              "mediatype": "banner"
+            }
           },
           "type": "banner"
         }
diff --git a/adapters/yieldmo/yieldmotest/exemplary/simple_video.json b/adapters/yieldmo/yieldmotest/exemplary/simple_video.json
index aaf53124..ec65bc98 100644
--- a/adapters/yieldmo/yieldmotest/exemplary/simple_video.json
+++ b/adapters/yieldmo/yieldmotest/exemplary/simple_video.json
@@ -63,7 +63,11 @@
                   "adm": "some-test-ad",
                   "crid": "crid_10",
                   "h": 250,
-                  "w": 300
+                  "w": 300,
+                  "ext":
+                  {
+                    "mediatype": "video"
+                  }
                 }
               ]
             }
@@ -85,7 +89,11 @@
             "adm": "some-test-ad",
             "crid": "crid_10",
             "w": 300,
-            "h": 250
+            "h": 250,
+            "ext":
+            {
+              "mediatype": "video"
+            }
           },
           "type": "video"
         }
diff --git a/adapters/yieldmo/yieldmotest/exemplary/with_gpid.json b/adapters/yieldmo/yieldmotest/exemplary/with_gpid.json
index bd9e9110..d155f5db 100644
--- a/adapters/yieldmo/yieldmotest/exemplary/with_gpid.json
+++ b/adapters/yieldmo/yieldmotest/exemplary/with_gpid.json
@@ -73,7 +73,11 @@
                   "adm": "some-test-ad",
                   "crid": "crid_10",
                   "h": 250,
-                  "w": 300
+                  "w": 300,
+                  "ext":
+                  {
+                    "mediatype": "banner"
+                  }
                 }
               ]
             }
@@ -95,7 +99,11 @@
             "adm": "some-test-ad",
             "crid": "crid_10",
             "w": 300,
-            "h": 250
+            "h": 250,
+            "ext":
+            {
+              "mediatype": "banner"
+            }
           },
           "type": "banner"
         }
diff --git a/endpoints/setuid_test.go b/endpoints/setuid_test.go
index fe663797..145be3d3 100644
--- a/endpoints/setuid_test.go
+++ b/endpoints/setuid_test.go
@@ -217,15 +217,25 @@ func TestSetUIDEndpoint(t *testing.T) {
 		},
 		{
 			uri: "/setuid?bidder=pubmatic&uid=123&gpp_sid=2,4&gpp=DBABMA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA" +
-				"gdpr=1&gdpr_consent=BONciguONcjGKADACHENAOLS1rAHDAFAAEAASABQAMwAeACEAFw",
+				"&gdpr=1&gdpr_consent=BONciguONcjGKADACHENAOLS1rAHDAFAAEAASABQAMwAeACEAFw",
 			syncersBidderNameToKey: map[string]string{"pubmatic": "pubmatic"},
 			gdprAllowsHostCookies:  true,
 			existingSyncs:          nil,
 			expectedSyncs:          map[string]string{"pubmatic": "123"},
 			expectedStatusCode:     http.StatusOK,
-			expectedBody:           "Warning: 'gpp' value will be used over the one found in the deprecated 'gdpr_consent' field.",
-			expectedHeaders:        map[string]string{"Content-Type": "text/plain; charset=utf-8"},
-			description:            "Sets uid for a bidder allowed by GDPR in GPP, throws warning because GDPR legacy values weren't used",
+			expectedHeaders:        map[string]string{"Content-Type": "text/html", "Content-Length": "0"},
+			description:            "GPP value will be used over the one found in the deprecated GDPR consent field for iframe format",
+		},
+		{
+			uri: "/setuid?f=i&bidder=pubmatic&uid=123&gpp_sid=2,4&gpp=DBABMA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA" +
+				"&gdpr=1&gdpr_consent=BONciguONcjGKADACHENAOLS1rAHDAFAAEAASABQAMwAeACEAFw",
+			syncersBidderNameToKey: map[string]string{"pubmatic": "pubmatic"},
+			gdprAllowsHostCookies:  true,
+			existingSyncs:          nil,
+			expectedSyncs:          map[string]string{"pubmatic": "123"},
+			expectedStatusCode:     http.StatusOK,
+			expectedHeaders:        map[string]string{"Content-Type": "image/png", "Content-Length": "86"},
+			description:            "GPP value will be used over the one found in the deprecated GDPR consent field for redirect format",
 		},
 		{
 			uri:                    "/setuid?bidder=pubmatic&uid=123&gdpr=1&gdpr_consent=malformed",
diff --git a/exchange/exchange_test.go b/exchange/exchange_test.go
index cc5c7ac0..aa354ea2 100644
--- a/exchange/exchange_test.go
+++ b/exchange/exchange_test.go
@@ -5037,6 +5037,325 @@ func TestOverrideConfigAlternateBidderCodesWithRequestValues(t *testing.T) {
 	}
 }
 
+func TestGetAllBids(t *testing.T) {
+	noBidServer := func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(200) }
+	server := httptest.NewServer(http.HandlerFunc(noBidServer))
+	defer server.Close()
+
+	type testIn struct {
+		bidderRequests             []BidderRequest
+		bidAdjustments             map[string]float64
+		conversions                currency.Conversions
+		accountDebugAllowed        bool
+		globalPrivacyControlHeader string
+		headerDebugAllowed         bool
+		alternateBidderCodes       openrtb_ext.ExtAlternateBidderCodes
+		experiment                 *openrtb_ext.Experiment
+		hookExecutor               hookexecution.StageExecutor
+		pbsRequestStartTime        time.Time
+		bidAdjustmentRules         map[string][]openrtb_ext.Adjustment
+		tmaxAdjustments            *TmaxAdjustmentsPreprocessed
+		adapterMap                 map[openrtb_ext.BidderName]AdaptedBidder
+	}
+	type testResults struct {
+		adapterBids   map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid
+		adapterExtra  map[openrtb_ext.BidderName]*seatResponseExtra
+		extraRespInfo extraAuctionResponseInfo
+	}
+	testCases := []struct {
+		desc     string
+		in       testIn
+		expected testResults
+	}{
+		{
+			desc: "alternateBidderCodes-config-absent: pubmatic bidder returns bids with 'pubmatic' and 'groupm' seats",
+			in: testIn{
+				bidderRequests: []BidderRequest{
+					{
+						BidderName:     "pubmatic",
+						BidderCoreName: "pubmatic",
+						BidRequest: &openrtb2.BidRequest{
+							ID: "some-request-id",
+							Imp: []openrtb2.Imp{{
+								ID: "some-impression-id",
+							}},
+						},
+					},
+				},
+				conversions:         &currency.ConstantRates{},
+				hookExecutor:        hookexecution.EmptyHookExecutor{},
+				pbsRequestStartTime: time.Now(),
+				adapterMap: map[openrtb_ext.BidderName]AdaptedBidder{
+					openrtb_ext.BidderPubmatic: AdaptBidder(&goodSingleBidder{
+						httpRequest: &adapters.RequestData{
+							Method: "POST",
+							Uri:    server.URL,
+						},
+						bidResponse: &adapters.BidderResponse{
+							Bids: []*adapters.TypedBid{
+								{Bid: &openrtb2.Bid{ID: "1"}, Seat: "pubmatic"},
+								{Bid: &openrtb2.Bid{ID: "2"}, Seat: "groupm"},
+							},
+						},
+					}, server.Client(), &config.Configuration{}, &metricsConfig.NilMetricsEngine{}, openrtb_ext.BidderPubmatic, nil, ""),
+				},
+			},
+			expected: testResults{
+				extraRespInfo: extraAuctionResponseInfo{
+					bidsFound: true,
+				},
+				adapterExtra: map[openrtb_ext.BidderName]*seatResponseExtra{
+					"pubmatic": {
+						Warnings: []openrtb_ext.ExtBidderMessage{
+							{
+								Code:    errortypes.AlternateBidderCodeWarningCode,
+								Message: `alternateBidderCodes disabled for "pubmatic", rejecting bids for "groupm"`,
+							},
+						},
+					},
+				},
+				adapterBids: map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid{
+					"pubmatic": {
+						Bids: []*entities.PbsOrtbBid{
+							{
+								Bid: &openrtb2.Bid{
+									ID: "1",
+								},
+								OriginalBidCur: "USD",
+							},
+						},
+						Currency:  "USD",
+						Seat:      "pubmatic",
+						HttpCalls: []*openrtb_ext.ExtHttpCall{},
+					},
+				},
+			},
+		},
+		{
+			desc: "alternateBidderCodes-enabled: pubmatic bidder returns bids with 'pubmatic' and 'groupm' seats",
+			in: testIn{
+				bidderRequests: []BidderRequest{
+					{
+						BidderName:     "pubmatic",
+						BidderCoreName: "pubmatic",
+						BidRequest: &openrtb2.BidRequest{
+							ID: "some-request-id",
+							Imp: []openrtb2.Imp{{
+								ID: "some-impression-id",
+							}},
+						},
+					},
+				},
+				conversions: &currency.ConstantRates{},
+				alternateBidderCodes: openrtb_ext.ExtAlternateBidderCodes{
+					Enabled: true,
+					Bidders: map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{
+						"pubmatic": {
+							Enabled:            true,
+							AllowedBidderCodes: []string{"groupm"},
+						},
+					},
+				},
+				hookExecutor:        hookexecution.EmptyHookExecutor{},
+				pbsRequestStartTime: time.Now(),
+				adapterMap: map[openrtb_ext.BidderName]AdaptedBidder{
+					openrtb_ext.BidderPubmatic: AdaptBidder(&goodSingleBidder{
+						httpRequest: &adapters.RequestData{
+							Method: "POST",
+							Uri:    server.URL,
+						},
+						bidResponse: &adapters.BidderResponse{
+							Bids: []*adapters.TypedBid{
+								{Bid: &openrtb2.Bid{ID: "1"}, Seat: "pubmatic"},
+								{Bid: &openrtb2.Bid{ID: "2"}, Seat: "groupm"},
+							},
+						},
+					}, server.Client(), &config.Configuration{}, &metricsConfig.NilMetricsEngine{}, openrtb_ext.BidderPubmatic, nil, ""),
+				},
+			},
+			expected: testResults{
+				extraRespInfo: extraAuctionResponseInfo{
+					bidsFound: true,
+				},
+				adapterExtra: map[openrtb_ext.BidderName]*seatResponseExtra{
+					"pubmatic": {
+						Warnings: []openrtb_ext.ExtBidderMessage{},
+					},
+				},
+				adapterBids: map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid{
+					"pubmatic": {
+						Bids: []*entities.PbsOrtbBid{
+							{
+								Bid: &openrtb2.Bid{
+									ID: "1",
+								},
+								OriginalBidCur: "USD",
+							},
+						},
+						Currency:  "USD",
+						Seat:      "pubmatic",
+						HttpCalls: []*openrtb_ext.ExtHttpCall{},
+					},
+					"groupm": {
+						Bids: []*entities.PbsOrtbBid{
+							{
+								Bid: &openrtb2.Bid{
+									ID: "2",
+								},
+								OriginalBidCur: "USD",
+							},
+						},
+						Currency:  "USD",
+						Seat:      "groupm",
+						HttpCalls: []*openrtb_ext.ExtHttpCall{},
+					},
+				},
+			},
+		},
+		{
+			desc: "alternateBidderCodes-enabled: pubmatic bidder returns bids with only 'groupm' seat",
+			in: testIn{
+				bidderRequests: []BidderRequest{
+					{
+						BidderName:     "pubmatic",
+						BidderCoreName: "pubmatic",
+						BidRequest: &openrtb2.BidRequest{
+							ID: "some-request-id",
+							Imp: []openrtb2.Imp{{
+								ID: "some-impression-id",
+							}},
+						},
+					},
+				},
+				conversions: &currency.ConstantRates{},
+				alternateBidderCodes: openrtb_ext.ExtAlternateBidderCodes{
+					Enabled: true,
+					Bidders: map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{
+						"pubmatic": {
+							Enabled:            true,
+							AllowedBidderCodes: []string{"groupm"},
+						},
+					},
+				},
+				hookExecutor:        hookexecution.EmptyHookExecutor{},
+				pbsRequestStartTime: time.Now(),
+				adapterMap: map[openrtb_ext.BidderName]AdaptedBidder{
+					openrtb_ext.BidderPubmatic: AdaptBidder(&goodSingleBidder{
+						httpRequest: &adapters.RequestData{
+							Method: "POST",
+							Uri:    server.URL,
+						},
+						bidResponse: &adapters.BidderResponse{
+							Bids: []*adapters.TypedBid{
+								{Bid: &openrtb2.Bid{ID: "2"}, Seat: "groupm"},
+							},
+						},
+					}, server.Client(), &config.Configuration{}, &metricsConfig.NilMetricsEngine{}, openrtb_ext.BidderPubmatic, nil, ""),
+				},
+			},
+			expected: testResults{
+				extraRespInfo: extraAuctionResponseInfo{
+					bidsFound: true,
+				},
+				adapterExtra: map[openrtb_ext.BidderName]*seatResponseExtra{
+					"pubmatic": {
+						Warnings: []openrtb_ext.ExtBidderMessage{},
+					},
+				},
+				adapterBids: map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid{
+					"groupm": {
+						Bids: []*entities.PbsOrtbBid{
+							{
+								Bid: &openrtb2.Bid{
+									ID: "2",
+								},
+								OriginalBidCur: "USD",
+							},
+						},
+						Currency:  "USD",
+						Seat:      "groupm",
+						HttpCalls: []*openrtb_ext.ExtHttpCall{},
+					},
+				},
+			},
+		},
+		{
+			desc: "bidder responded with empty bid",
+			in: testIn{
+				bidderRequests: []BidderRequest{
+					{
+						BidderName:     "pubmatic",
+						BidderCoreName: "pubmatic",
+						BidRequest: &openrtb2.BidRequest{
+							ID: "some-request-id",
+							Imp: []openrtb2.Imp{{
+								ID: "some-impression-id",
+							}},
+						},
+					},
+				},
+				conversions: &currency.ConstantRates{},
+				alternateBidderCodes: openrtb_ext.ExtAlternateBidderCodes{
+					Enabled: true,
+					Bidders: map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{
+						"pubmatic": {
+							Enabled:            true,
+							AllowedBidderCodes: []string{"groupm"},
+						},
+					},
+				},
+				hookExecutor:        hookexecution.EmptyHookExecutor{},
+				pbsRequestStartTime: time.Now(),
+				adapterMap: map[openrtb_ext.BidderName]AdaptedBidder{
+					openrtb_ext.BidderPubmatic: AdaptBidder(&goodSingleBidder{
+						httpRequest: &adapters.RequestData{
+							Method: "POST",
+							Uri:    server.URL,
+						},
+						bidResponse: &adapters.BidderResponse{},
+					}, server.Client(), &config.Configuration{}, &metricsConfig.NilMetricsEngine{}, openrtb_ext.BidderPubmatic, nil, ""),
+				},
+			},
+			expected: testResults{
+				extraRespInfo: extraAuctionResponseInfo{
+					bidsFound: false,
+				},
+				adapterExtra: map[openrtb_ext.BidderName]*seatResponseExtra{
+					"pubmatic": {
+						Warnings: []openrtb_ext.ExtBidderMessage{},
+					},
+				},
+				adapterBids: map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid{},
+			},
+		},
+	}
+	for _, test := range testCases {
+		t.Run(test.desc, func(t *testing.T) {
+			e := exchange{
+				cache: &wellBehavedCache{},
+				me:    &metricsConf.NilMetricsEngine{},
+				gdprPermsBuilder: fakePermissionsBuilder{
+					permissions: &permissionsMock{
+						allowAllBidders: true,
+					},
+				}.Builder,
+				adapterMap: test.in.adapterMap,
+			}
+
+			adapterBids, adapterExtra, extraRespInfo := e.getAllBids(context.Background(), test.in.bidderRequests, test.in.bidAdjustments,
+				test.in.conversions, test.in.accountDebugAllowed, test.in.globalPrivacyControlHeader, test.in.headerDebugAllowed, test.in.alternateBidderCodes, test.in.experiment,
+				test.in.hookExecutor, test.in.pbsRequestStartTime, test.in.bidAdjustmentRules, test.in.tmaxAdjustments)
+
+			assert.Equalf(t, test.expected.extraRespInfo.bidsFound, extraRespInfo.bidsFound, "extraRespInfo.bidsFound mismatch")
+			assert.Equalf(t, test.expected.adapterBids, adapterBids, "adapterBids mismatch")
+			assert.Equalf(t, len(test.expected.adapterExtra), len(adapterExtra), "adapterExtra length mismatch")
+			for adapter, extra := range test.expected.adapterExtra {
+				assert.Equalf(t, extra.Warnings, adapterExtra[adapter].Warnings, "adapterExtra.Warnings mismatch for adapter [%s]", adapter)
+			}
+		})
+	}
+}
+
 type MockSigner struct {
 	data string
 }