diff --git a/-vv b/-vv new file mode 100644 index 00000000000..28f4857db7b --- /dev/null +++ b/-vv @@ -0,0 +1,78 @@ +mode: set +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:67.119,69.16 2 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:69.16,71.3 1 0 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:72.2,75.20 2 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:78.59,81.68 2 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:81.68,91.3 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:92.2,92.16 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:95.79,96.39 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:96.39,97.21 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:97.21,99.4 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:103.141,109.38 2 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:109.38,111.17 2 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:111.17,113.12 2 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:116.3,117.17 2 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:117.17,119.12 2 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:122.3,123.17 2 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:123.17,125.12 2 0 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:128.3,134.5 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:137.2,137.25 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:140.139,143.29 2 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:143.29,146.3 2 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:148.2,153.63 2 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:153.63,155.26 2 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:155.26,157.4 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:158.3,158.26 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:158.26,160.4 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:161.3,161.29 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:161.29,166.4 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:168.2,168.61 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:168.61,170.25 2 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:170.25,172.4 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:173.3,173.25 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:173.25,175.4 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:176.3,176.29 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:176.29,181.4 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:183.2,183.61 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:183.62,197.3 0 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:199.2,202.60 3 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:202.60,204.3 1 0 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:205.2,205.75 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:205.75,207.3 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:208.2,210.21 2 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:213.166,214.58 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:214.58,216.3 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:218.2,218.80 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:218.80,220.3 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:222.2,223.69 2 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:223.69,225.3 1 0 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:227.2,231.34 4 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:231.34,233.3 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:235.2,235.31 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:235.31,240.17 3 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:240.17,243.12 2 0 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:246.3,247.17 2 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:247.17,249.12 2 0 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:252.3,257.49 2 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:260.2,260.27 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:260.27,262.3 1 0 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:264.2,264.26 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:267.78,268.26 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:268.26,271.3 1 0 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:273.2,283.16 3 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:283.16,285.3 1 0 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:286.2,289.16 3 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:289.16,291.3 1 0 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:292.2,293.17 2 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:296.64,297.23 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:297.23,299.3 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:299.8,299.29 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:299.29,301.3 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:301.8,301.29 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:301.29,303.3 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:305.2,305.73 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:308.104,311.41 2 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:311.41,312.50 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:312.50,316.4 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:317.3,317.24 1 1 +github.com/prebid/prebid-server/v2/adapters/resetdigital/resetdigital.go:319.2,319.73 1 0 diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index ebf6f614df3..f9bb82598ff 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -6,7 +6,7 @@ "dockerfile": "Dockerfile", "args": { // Update the VARIANT arg to pick a version of Go - "VARIANT": "1.20", + "VARIANT": "1.22", // Options "INSTALL_NODE": "false", "NODE_VERSION": "lts/*" diff --git a/.gitignore b/.gitignore index 0df7cde54fd..8e22128eae6 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ _obj _test .cover/ .idea/ +.vscode/ # Architecture specific extensions/prefixes *.[568vq] @@ -42,11 +43,8 @@ inventory_url.yaml analytics/config/testFiles/ analytics/filesystem/testFiles/ -# autogenerated version file -# static/version.txt - -.idea/ -.vscode/ +# autogenerated files +prebid-server.iml # autogenerated mac file diff --git a/Dockerfile b/Dockerfile index 17b6ce20387..ad509721ba9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,16 +11,20 @@ WORKDIR /app/prebid-server/ ENV GOROOT=/usr/local/go ENV PATH=$GOROOT/bin:$PATH ENV GOPROXY="https://proxy.golang.org" + +# Installing gcc as cgo uses it to build native code of some modules RUN apt-get update && \ - apt-get install -y git && \ + apt-get install -y git gcc && \ apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* -ENV CGO_ENABLED 0 + +# CGO must be enabled because some modules depend on native C code +ENV CGO_ENABLED 1 COPY ./ ./ RUN go mod tidy RUN go mod vendor ARG TEST="true" RUN if [ "$TEST" != "false" ]; then ./validate.sh ; fi -RUN go build -mod=vendor -ldflags "-X github.com/prebid/prebid-server/v2/version.Ver=`git describe --tags | sed 's/^v//'` -X github.com/prebid/prebid-server/v2/version.Rev=`git rev-parse HEAD`" . +RUN go build -mod=vendor -ldflags "-X github.com/prebid/prebid-server/v3/version.Ver=`git describe --tags | sed 's/^v//'` -X github.com/prebid/prebid-server/v3/version.Rev=`git rev-parse HEAD`" . FROM ubuntu:20.04 AS release LABEL maintainer="hans.hjort@xandr.com" @@ -30,8 +34,10 @@ RUN chmod a+xr prebid-server COPY static static/ COPY stored_requests/data stored_requests/data RUN chmod -R a+r static/ stored_requests/data + +# Installing libatomic1 as it is a runtime dependency for some modules RUN apt-get update && \ - apt-get install -y ca-certificates mtr && \ + apt-get install -y ca-certificates mtr libatomic1 && \ apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* RUN adduser prebid_user USER prebid_user diff --git a/Makefile b/Makefile index cf4ac52b515..8b68afe3bee 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ test: deps ifeq "$(adapter)" "" ./validate.sh else - go test github.com/prebid/prebid-server/v2/adapters/$(adapter) -bench=. + go test github.com/prebid/prebid-server/v3/adapters/$(adapter) -bench=. endif # build-modules generates modules/builder.go file which provides a list of all available modules diff --git a/README.md b/README.md index 4a44ecd7c6a..b616594a68a 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,11 @@ or compile a standalone binary using the command: ``` bash go build . ``` +**Note:** if building from source there are a couple dependencies to be aware of: +1. *Compile-time*. Some modules ship native code that requires `cgo` (comes with the `go` compiler) being enabled - by default it is and environment variable `CGO_ENABLED=1` do NOT set it to `0`. +2. *Compile-time*. `cgo` depends on the C-compiler, which usually is `gcc`, but can be changed by setting the value of `CC` env var, f.e. `CC=clang`. On ubuntu `gcc` can be installed via `sudo apt-get install gcc`. +3. *Runtime*. Some modules require `libatomic`. On ubuntu it is installed by running `sudo apt-get install libatomic1`. `libatomic1` is a dependency of `gcc`, so if you are building with `gcc` and running on the same machine, it is likely that `libatomic1` is already installed. + Ensure that you deploy the `/static` directory, as Prebid Server requires those files at startup. ## Developing diff --git a/account/account.go b/account/account.go index 418fd90c9ac..0087548cc79 100644 --- a/account/account.go +++ b/account/account.go @@ -6,13 +6,13 @@ import ( "github.com/prebid/go-gdpr/consentconstants" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/metrics" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/stored_requests" - "github.com/prebid/prebid-server/v2/util/iputil" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/metrics" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/stored_requests" + "github.com/prebid/prebid-server/v3/util/iputil" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) // GetAccount looks up the config.Account object referenced by the given accountID, with access rules applied diff --git a/account/account_test.go b/account/account_test.go index b4ea64f0287..c8b17b53ff8 100644 --- a/account/account_test.go +++ b/account/account_test.go @@ -6,13 +6,13 @@ import ( "fmt" "testing" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/metrics" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/stored_requests" - "github.com/prebid/prebid-server/v2/util/iputil" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/metrics" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/stored_requests" + "github.com/prebid/prebid-server/v3/util/iputil" + "github.com/prebid/prebid-server/v3/util/ptrutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" ) diff --git a/adapters/33across/33across.go b/adapters/33across/33across.go index b9f0c98a38f..94ddf1f91fd 100644 --- a/adapters/33across/33across.go +++ b/adapters/33across/33across.go @@ -7,10 +7,11 @@ import ( "github.com/prebid/openrtb/v20/adcom1" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type TtxAdapter struct { @@ -76,7 +77,7 @@ func (a *TtxAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapter // Skip over imps whose extensions cannot be read since // we cannot glean Prod or ZoneID which are required to // group together. However let's not block request creation. - if err := json.Unmarshal(impCopy.Ext, &impExt); err == nil { + if err := jsonutil.Unmarshal(impCopy.Ext, &impExt); err == nil { impKey := impExt.Ttx.Prod + impExt.Ttx.Zoneid groupedImps[impKey] = append(groupedImps[impKey], impCopy) } else { @@ -126,14 +127,14 @@ func makeImps(imp openrtb2.Imp) (openrtb2.Imp, error) { } var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return openrtb2.Imp{}, &errortypes.BadInput{ Message: err.Error(), } } var ttxExt openrtb_ext.ExtImp33across - if err := json.Unmarshal(bidderExt.Bidder, &ttxExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &ttxExt); err != nil { return openrtb2.Imp{}, &errortypes.BadInput{ Message: err.Error(), } @@ -177,7 +178,7 @@ func makeReqExt(request *openrtb2.BidRequest) ([]byte, error) { var reqExt reqExt if len(request.Ext) > 0 { - if err := json.Unmarshal(request.Ext, &reqExt); err != nil { + if err := jsonutil.Unmarshal(request.Ext, &reqExt); err != nil { return nil, err } } @@ -215,7 +216,7 @@ func (a *TtxAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequ var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } @@ -226,7 +227,7 @@ func (a *TtxAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequ var bidExt bidExt var bidType openrtb_ext.BidType - if err := json.Unmarshal(sb.Bid[i].Ext, &bidExt); err != nil { + if err := jsonutil.Unmarshal(sb.Bid[i].Ext, &bidExt); err != nil { bidType = openrtb_ext.BidTypeBanner } else { bidType = getBidType(bidExt) diff --git a/adapters/33across/33across_test.go b/adapters/33across/33across_test.go index c84ca0ad1d2..3ed177deacd 100644 --- a/adapters/33across/33across_test.go +++ b/adapters/33across/33across_test.go @@ -3,9 +3,9 @@ package ttx import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/33across/params_test.go b/adapters/33across/params_test.go index ba985b2b250..3169a1d9944 100644 --- a/adapters/33across/params_test.go +++ b/adapters/33across/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/33across.json diff --git a/adapters/aax/aax.go b/adapters/aax/aax.go index 09a06a1f5bb..10969559658 100644 --- a/adapters/aax/aax.go +++ b/adapters/aax/aax.go @@ -7,10 +7,11 @@ import ( "net/url" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -63,7 +64,7 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } @@ -96,7 +97,7 @@ func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server co func getMediaTypeForImp(bid openrtb2.Bid, imps []openrtb2.Imp) (openrtb_ext.BidType, error) { var bidExt aaxResponseBidExt - err := json.Unmarshal(bid.Ext, &bidExt) + err := jsonutil.Unmarshal(bid.Ext, &bidExt) if err == nil { switch bidExt.AdCodeType { case "banner": diff --git a/adapters/aax/aax_test.go b/adapters/aax/aax_test.go index c4fd1c392aa..ad24a2d62e1 100644 --- a/adapters/aax/aax_test.go +++ b/adapters/aax/aax_test.go @@ -5,9 +5,9 @@ import ( "github.com/stretchr/testify/assert" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/aax/params_test.go b/adapters/aax/params_test.go index bdfa46a9e63..0f93a063e65 100644 --- a/adapters/aax/params_test.go +++ b/adapters/aax/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/aax.json diff --git a/adapters/aceex/aceex.go b/adapters/aceex/aceex.go index c579fe81c9b..73a040bbe56 100644 --- a/adapters/aceex/aceex.go +++ b/adapters/aceex/aceex.go @@ -7,11 +7,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -90,13 +91,13 @@ func (a *adapter) MakeRequests( func (a *adapter) getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtAceex, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: "ext.bidder not provided", } } var aceexExt openrtb_ext.ExtAceex - if err := json.Unmarshal(bidderExt.Bidder, &aceexExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &aceexExt); err != nil { return nil, &errortypes.BadInput{ Message: "ext.bidder not provided", } @@ -151,7 +152,7 @@ func (a *adapter) MakeBids( responseBody := bidderRawResponse.Body var bidResp openrtb2.BidResponse - if err := json.Unmarshal(responseBody, &bidResp); err != nil { + if err := jsonutil.Unmarshal(responseBody, &bidResp); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: "Bad Server Response", }} diff --git a/adapters/aceex/aceex_test.go b/adapters/aceex/aceex_test.go index 71c26ed0bed..7aef7dd93f7 100644 --- a/adapters/aceex/aceex_test.go +++ b/adapters/aceex/aceex_test.go @@ -3,9 +3,9 @@ package aceex import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/aceex/params_test.go b/adapters/aceex/params_test.go index cb6445c491a..c09e2683073 100644 --- a/adapters/aceex/params_test.go +++ b/adapters/aceex/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/acuityads/acuityads.go b/adapters/acuityads/acuityads.go index 43d8e1eff97..e05ded95e80 100644 --- a/adapters/acuityads/acuityads.go +++ b/adapters/acuityads/acuityads.go @@ -7,11 +7,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type AcuityAdsAdapter struct { @@ -90,13 +91,13 @@ func (a *AcuityAdsAdapter) MakeRequests( func (a *AcuityAdsAdapter) getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtAcuityAds, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: "ext.bidder not provided", } } var acuityAdsExt openrtb_ext.ExtAcuityAds - if err := json.Unmarshal(bidderExt.Bidder, &acuityAdsExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &acuityAdsExt); err != nil { return nil, &errortypes.BadInput{ Message: "ext.bidder not provided", } @@ -155,7 +156,7 @@ func (a *AcuityAdsAdapter) MakeBids( responseBody := bidderRawResponse.Body var bidResp openrtb2.BidResponse - if err := json.Unmarshal(responseBody, &bidResp); err != nil { + if err := jsonutil.Unmarshal(responseBody, &bidResp); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: "Bad Server Response", }} diff --git a/adapters/acuityads/acuityads_test.go b/adapters/acuityads/acuityads_test.go index c426d02c533..b19abd3f7d9 100644 --- a/adapters/acuityads/acuityads_test.go +++ b/adapters/acuityads/acuityads_test.go @@ -3,9 +3,9 @@ package acuityads import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/acuityads/params_test.go b/adapters/acuityads/params_test.go index 3c7b3a97914..756dda3ea1e 100644 --- a/adapters/acuityads/params_test.go +++ b/adapters/acuityads/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/adapterstest/test_json.go b/adapters/adapterstest/test_json.go index 1c10513919b..c2124abfcad 100644 --- a/adapters/adapterstest/test_json.go +++ b/adapters/adapterstest/test_json.go @@ -8,15 +8,16 @@ import ( "os" "path/filepath" "regexp" + "strings" "testing" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/mitchellh/copystructure" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/currency" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/currency" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" "github.com/yudai/gojsondiff" "github.com/yudai/gojsondiff/formatter" @@ -226,9 +227,10 @@ type expectedBidResponse struct { } type expectedBid struct { - Bid json.RawMessage `json:"bid"` - Type string `json:"type"` - Seat string `json:"seat"` + Bid json.RawMessage `json:"bid"` + Type string `json:"type"` + Seat string `json:"seat"` + Video json.RawMessage `json:"video,omitempty"` } // --------------------------------------- @@ -272,6 +274,10 @@ func assertErrorList(t *testing.T, description string, actual []error, expected if matched, _ := regexp.MatchString(expected[i].Value, actual[i].Error()); !matched { t.Errorf(`%s error[%d] had wrong message. Expected match with regex "%s", got "%s"`, description, i, expected[i].Value, actual[i].Error()) } + } else if expected[i].Comparison == "startswith" { + if !strings.HasPrefix(actual[i].Error(), expected[i].Value) { + t.Errorf(`%s error[%d] had wrong message. Expected to start with "%s", got "%s"`, description, i, expected[i].Value, actual[i].Error()) + } } else { t.Fatalf(`invalid comparison type "%s"`, expected[i].Comparison) } @@ -342,6 +348,9 @@ func diffBids(t *testing.T, description string, actual *adapters.TypedBid, expec assert.Equal(t, string(expected.Seat), string(actual.Seat), fmt.Sprintf(`%s.seat "%s" does not match expected "%s."`, description, string(actual.Seat), string(expected.Seat))) assert.Equal(t, string(expected.Type), string(actual.BidType), fmt.Sprintf(`%s.type "%s" does not match expected "%s."`, description, string(actual.BidType), string(expected.Type))) assert.NoError(t, diffOrtbBids(fmt.Sprintf("%s.bid", description), actual.Bid, expected.Bid)) + if expected.Video != nil { + assert.NoError(t, diffBidVideo(fmt.Sprintf("%s.video", description), actual.BidVideo, expected.Video)) + } } // diffOrtbBids compares the actual Bid made by the adapter to the expectation from the JSON file. @@ -358,6 +367,15 @@ func diffOrtbBids(description string, actual *openrtb2.Bid, expected json.RawMes return diffJson(description, actualJson, expected) } +func diffBidVideo(description string, actual *openrtb_ext.ExtBidPrebidVideo, expected json.RawMessage) error { + actualJson, err := json.Marshal(actual) + if err != nil { + return fmt.Errorf("%s failed to marshal actual Bid Video into JSON. %v", description, err) + } + + return diffJson(description, actualJson, []byte(expected)) +} + // diffJson compares two JSON byte arrays for structural equality. It will produce an error if either // byte array is not actually JSON. func diffJson(description string, actual []byte, expected []byte) error { diff --git a/adapters/adelement/adelement.go b/adapters/adelement/adelement.go index 427741eb077..11b79ad37b7 100644 --- a/adapters/adelement/adelement.go +++ b/adapters/adelement/adelement.go @@ -6,11 +6,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -58,13 +59,13 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte func getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtAdelement, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: "ext.bidder not provided", } } var adelementExt openrtb_ext.ExtAdelement - if err := json.Unmarshal(bidderExt.Bidder, &adelementExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &adelementExt); err != nil { return nil, &errortypes.BadInput{ Message: "ext.bidder not provided", } @@ -88,7 +89,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: "Bad Server Response", }} diff --git a/adapters/adelement/adelement_test.go b/adapters/adelement/adelement_test.go index d1c58bbebb4..2cfa599f803 100644 --- a/adapters/adelement/adelement_test.go +++ b/adapters/adelement/adelement_test.go @@ -3,9 +3,9 @@ package adelement import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/adf/adf.go b/adapters/adf/adf.go index afa9bc84562..08fb9b8bb4a 100644 --- a/adapters/adf/adf.go +++ b/adapters/adf/adf.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -36,7 +37,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte for _, imp := range request.Imp { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { errors = append(errors, &errortypes.BadInput{ Message: err.Error(), }) @@ -44,7 +45,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte } var adfImpExt openrtb_ext.ExtImpAdf - if err := json.Unmarshal(bidderExt.Bidder, &adfImpExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &adfImpExt); err != nil { errors = append(errors, &errortypes.BadInput{ Message: err.Error(), }) @@ -65,7 +66,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte var err error if len(request.Ext) > 0 { - if err = json.Unmarshal(request.Ext, &requestExt); err != nil { + if err = jsonutil.Unmarshal(request.Ext, &requestExt); err != nil { errors = append(errors, err) } } @@ -117,7 +118,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } @@ -144,7 +145,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) { if bid.Ext != nil { var bidExt openrtb_ext.ExtBid - err := json.Unmarshal(bid.Ext, &bidExt) + err := jsonutil.Unmarshal(bid.Ext, &bidExt) if err == nil && bidExt.Prebid != nil { return openrtb_ext.ParseBidType(string(bidExt.Prebid.Type)) } diff --git a/adapters/adf/adf_test.go b/adapters/adf/adf_test.go index 20e4f3dde32..21e8a769c15 100644 --- a/adapters/adf/adf_test.go +++ b/adapters/adf/adf_test.go @@ -3,9 +3,9 @@ package adf import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/adf/adftest/supplemental/unparsable-response.json b/adapters/adf/adftest/supplemental/unparsable-response.json index 5e63febee4c..5a89ff2dd3b 100644 --- a/adapters/adf/adftest/supplemental/unparsable-response.json +++ b/adapters/adf/adftest/supplemental/unparsable-response.json @@ -43,7 +43,7 @@ "expectedBidResponses": [], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/adf/params_test.go b/adapters/adf/params_test.go index dc0d84927bc..9b3fd7b3e31 100644 --- a/adapters/adf/params_test.go +++ b/adapters/adf/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/adf.json diff --git a/adapters/adgeneration/adgeneration.go b/adapters/adgeneration/adgeneration.go index 192680ca9f2..31e27b862a9 100644 --- a/adapters/adgeneration/adgeneration.go +++ b/adapters/adgeneration/adgeneration.go @@ -1,7 +1,6 @@ package adgeneration import ( - "encoding/json" "errors" "fmt" "net/http" @@ -11,10 +10,11 @@ import ( "strings" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type AdgenerationAdapter struct { @@ -149,10 +149,10 @@ func (adg *AdgenerationAdapter) getRawQuery(id string, request *openrtb2.BidRequ func unmarshalExtImpAdgeneration(imp *openrtb2.Imp) (*openrtb_ext.ExtImpAdgeneration, error) { var bidderExt adapters.ExtImpBidder var adgExt openrtb_ext.ExtImpAdgeneration - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, err } - if err := json.Unmarshal(bidderExt.Bidder, &adgExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &adgExt); err != nil { return nil, err } if adgExt.Id == "" { @@ -203,7 +203,7 @@ func (adg *AdgenerationAdapter) MakeBids(internalRequest *openrtb2.BidRequest, e }} } var bidResp adgServerResponse - err := json.Unmarshal(response.Body, &bidResp) + err := jsonutil.Unmarshal(response.Body, &bidResp) if err != nil { return nil, []error{err} } diff --git a/adapters/adgeneration/adgeneration_test.go b/adapters/adgeneration/adgeneration_test.go index 24e1de5eccd..e12ed431f04 100644 --- a/adapters/adgeneration/adgeneration_test.go +++ b/adapters/adgeneration/adgeneration_test.go @@ -5,10 +5,10 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/adgeneration/params_test.go b/adapters/adgeneration/params_test.go index 58400e96656..bdef4ec1d05 100644 --- a/adapters/adgeneration/params_test.go +++ b/adapters/adgeneration/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/adhese/adhese.go b/adapters/adhese/adhese.go index 09bd4ba8041..181cc661e46 100644 --- a/adapters/adhese/adhese.go +++ b/adapters/adhese/adhese.go @@ -11,11 +11,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type AdheseAdapter struct { @@ -32,7 +33,7 @@ func extractTargetParameters(parameters openrtb_ext.ExtImpAdhese) string { } var parametersAsString = "" var targetParsed map[string]interface{} - err := json.Unmarshal(parameters.Keywords, &targetParsed) + err := jsonutil.Unmarshal(parameters.Keywords, &targetParsed) if err != nil { return "" } @@ -59,7 +60,7 @@ func extractTargetParameters(parameters openrtb_ext.ExtImpAdhese) string { func extractGdprParameter(request *openrtb2.BidRequest) string { if request.User != nil { var extUser openrtb_ext.ExtUser - if err := json.Unmarshal(request.User.Ext, &extUser); err == nil { + if err := jsonutil.Unmarshal(request.User.Ext, &extUser); err == nil { return "/xt" + extUser.Consent } } @@ -94,13 +95,13 @@ func (a *AdheseAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adap var imp = &request.Imp[0] var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { errs = append(errs, WrapReqError("Request could not be parsed as ExtImpBidder due to: "+err.Error())) return nil, errs } var params openrtb_ext.ExtImpAdhese - if err := json.Unmarshal(bidderExt.Bidder, ¶ms); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, ¶ms); err != nil { errs = append(errs, WrapReqError("Request could not be parsed as ExtImpAdhese due to: "+err.Error())) return nil, errs } @@ -138,7 +139,7 @@ func (a *AdheseAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalR var bidResponse openrtb2.BidResponse var adheseBidResponseArray []AdheseBid - if err := json.Unmarshal(response.Body, &adheseBidResponseArray); err != nil { + if err := jsonutil.Unmarshal(response.Body, &adheseBidResponseArray); err != nil { return nil, []error{err, WrapServerError(fmt.Sprintf("Response %v could not be parsed as generic Adhese bid.", string(response.Body)))} } @@ -150,11 +151,11 @@ func (a *AdheseAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalR if adheseBid.Origin == "JERLICIA" { var extArray []AdheseExt var originDataArray []AdheseOriginData - if err := json.Unmarshal(response.Body, &extArray); err != nil { + if err := jsonutil.Unmarshal(response.Body, &extArray); err != nil { return nil, []error{err, WrapServerError(fmt.Sprintf("Response %v could not be parsed to JERLICIA ext.", string(response.Body)))} } - if err := json.Unmarshal(response.Body, &originDataArray); err != nil { + if err := jsonutil.Unmarshal(response.Body, &originDataArray); err != nil { return nil, []error{err, WrapServerError(fmt.Sprintf("Response %v could not be parsed to JERLICIA origin data.", string(response.Body)))} } bidResponse = convertAdheseBid(adheseBid, extArray[0], originDataArray[0]) diff --git a/adapters/adhese/adhese_test.go b/adapters/adhese/adhese_test.go index 2b70bb001a6..b8abd82a06f 100644 --- a/adapters/adhese/adhese_test.go +++ b/adapters/adhese/adhese_test.go @@ -3,9 +3,9 @@ package adhese import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/adhese/adhesetest/supplemental/req-invalid-empty-imp-ext.json b/adapters/adhese/adhesetest/supplemental/req-invalid-empty-imp-ext.json index e98823b2914..9169847be35 100644 --- a/adapters/adhese/adhesetest/supplemental/req-invalid-empty-imp-ext.json +++ b/adapters/adhese/adhesetest/supplemental/req-invalid-empty-imp-ext.json @@ -31,8 +31,8 @@ "expectedBidResponses": [], "expectedMakeRequestsErrors": [ { - "value": "Request could not be parsed as ExtImpAdhese due to: unexpected end of JSON input", - "comparison": "literal" + "value": "Request could not be parsed as ExtImpAdhese due to: expect { or n, but found", + "comparison": "startswith" } ] } \ No newline at end of file diff --git a/adapters/adhese/adhesetest/supplemental/req-invalid-no-imp-ext.json b/adapters/adhese/adhesetest/supplemental/req-invalid-no-imp-ext.json index bcb891719ae..76f5315c1cb 100644 --- a/adapters/adhese/adhesetest/supplemental/req-invalid-no-imp-ext.json +++ b/adapters/adhese/adhesetest/supplemental/req-invalid-no-imp-ext.json @@ -30,8 +30,8 @@ "expectedBidResponses": [], "expectedMakeRequestsErrors": [ { - "value": "Request could not be parsed as ExtImpBidder due to: unexpected end of JSON input", - "comparison": "literal" + "value": "Request could not be parsed as ExtImpBidder due to: expect { or n, but found", + "comparison": "startswith" } ] } \ No newline at end of file diff --git a/adapters/adhese/adhesetest/supplemental/res-invalid-height.json b/adapters/adhese/adhesetest/supplemental/res-invalid-height.json index 86ff3e49692..4c7989cb56b 100644 --- a/adapters/adhese/adhesetest/supplemental/res-invalid-height.json +++ b/adapters/adhese/adhesetest/supplemental/res-invalid-height.json @@ -82,7 +82,7 @@ "expectedBidResponses": [], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal number into Go struct field AdheseBid.height of type string", + "value": "cannot unmarshal adhese.AdheseBid.Height: expects \" or n, but found 9", "comparison": "literal" }, { "value": "Response (.*\n.*)+ could not be parsed as generic Adhese bid", diff --git a/adapters/adhese/adhesetest/supplemental/res-invalid-no-body.json b/adapters/adhese/adhesetest/supplemental/res-invalid-no-body.json index f05ca15a862..1ec91d9ad0a 100644 --- a/adapters/adhese/adhesetest/supplemental/res-invalid-no-body.json +++ b/adapters/adhese/adhesetest/supplemental/res-invalid-no-body.json @@ -53,8 +53,8 @@ "expectedBidResponses": [], "expectedMakeBidsErrors": [ { - "value": "unexpected end of JSON input", - "comparison": "literal" + "value": "decode slice: expect [ or n, but found", + "comparison": "startswith" },{ "value": "Response could not be parsed as generic Adhese bid.", "comparison": "literal" diff --git a/adapters/adhese/adhesetest/supplemental/res-invalid-price.json b/adapters/adhese/adhesetest/supplemental/res-invalid-price.json index 9505af358bf..7fcbc298876 100644 --- a/adapters/adhese/adhesetest/supplemental/res-invalid-price.json +++ b/adapters/adhese/adhesetest/supplemental/res-invalid-price.json @@ -82,7 +82,7 @@ "expectedBidResponses": [], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal number into Go struct field CPMValues.*\\.amount of type string", + "value": "cannot unmarshal adhese.CPMValues.Amount: expects \" or n, but found 1", "comparison": "regex" }, { "value": "Response (.*\n.*)+ could not be parsed as generic Adhese bid", diff --git a/adapters/adhese/adhesetest/supplemental/res-invalid-width.json b/adapters/adhese/adhesetest/supplemental/res-invalid-width.json index b554ed65450..139a5c598a1 100644 --- a/adapters/adhese/adhesetest/supplemental/res-invalid-width.json +++ b/adapters/adhese/adhesetest/supplemental/res-invalid-width.json @@ -82,7 +82,7 @@ "expectedBidResponses": [], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal number into Go struct field AdheseBid.width of type string", + "value": "cannot unmarshal adhese.AdheseBid.Width: expects \" or n, but found 7", "comparison": "literal" }, { "value": "Response (.*\n.*)+ could not be parsed as generic Adhese bid", diff --git a/adapters/adhese/params_test.go b/adapters/adhese/params_test.go index 1a0aa381cb1..b8ca161d57d 100644 --- a/adapters/adhese/params_test.go +++ b/adapters/adhese/params_test.go @@ -5,7 +5,7 @@ import ( "fmt" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/adkernel/adkernel.go b/adapters/adkernel/adkernel.go index 2b3df333975..443da423fc9 100644 --- a/adapters/adkernel/adkernel.go +++ b/adapters/adkernel/adkernel.go @@ -9,11 +9,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) const ( @@ -169,13 +170,13 @@ func splitMultiFormatImp(imp *openrtb2.Imp) []openrtb2.Imp { func getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpAdkernel, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: err.Error(), } } var adkernelExt openrtb_ext.ExtImpAdkernel - if err := json.Unmarshal(bidderExt.Bidder, &adkernelExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &adkernelExt); err != nil { return nil, &errortypes.BadInput{ Message: err.Error(), } @@ -243,7 +244,7 @@ func (adapter *adkernelAdapter) MakeBids(internalRequest *openrtb2.BidRequest, e } } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{ newBadServerResponseError(fmt.Sprintf("Bad server response: %d", err)), } diff --git a/adapters/adkernel/adkernel_test.go b/adapters/adkernel/adkernel_test.go index e7ff02e4c03..f874e92d57e 100644 --- a/adapters/adkernel/adkernel_test.go +++ b/adapters/adkernel/adkernel_test.go @@ -3,9 +3,9 @@ package adkernel import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/adkernelAdn/adkernelAdn.go b/adapters/adkernelAdn/adkernelAdn.go index 33e5ee93b05..ffee88250ca 100644 --- a/adapters/adkernelAdn/adkernelAdn.go +++ b/adapters/adkernelAdn/adkernelAdn.go @@ -8,11 +8,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adkernelAdnAdapter struct { @@ -149,13 +150,13 @@ func compatVideoImpression(imp *openrtb2.Imp) error { func getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpAdkernelAdn, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: err.Error(), } } var adkernelAdnExt openrtb_ext.ExtImpAdkernelAdn - if err := json.Unmarshal(bidderExt.Bidder, &adkernelAdnExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &adkernelAdnExt); err != nil { return nil, &errortypes.BadInput{ Message: err.Error(), } @@ -226,7 +227,7 @@ func (adapter *adkernelAdnAdapter) MakeBids(internalRequest *openrtb2.BidRequest } } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{ newBadServerResponseError(fmt.Sprintf("Bad server response: %d", err)), } diff --git a/adapters/adkernelAdn/adkernelAdn_test.go b/adapters/adkernelAdn/adkernelAdn_test.go index e43d00bf0bf..f99da329403 100644 --- a/adapters/adkernelAdn/adkernelAdn_test.go +++ b/adapters/adkernelAdn/adkernelAdn_test.go @@ -3,9 +3,9 @@ package adkernelAdn import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/adkernelAdn/adkerneladntest/supplemental/wrong-imp-ext-1.json b/adapters/adkernelAdn/adkerneladntest/supplemental/wrong-imp-ext-1.json index 8b2b5837e13..4d5b3228d16 100644 --- a/adapters/adkernelAdn/adkerneladntest/supplemental/wrong-imp-ext-1.json +++ b/adapters/adkernelAdn/adkerneladntest/supplemental/wrong-imp-ext-1.json @@ -18,8 +18,8 @@ "expectedMakeRequestsErrors": [ { - "value": "json: cannot unmarshal string into Go struct field ExtImpAdkernelAdn.pubId of type int", - "comparison": "literal" + "value": "cannot unmarshal openrtb_ext.ExtImpAdkernelAdn.PublisherID: unexpected character", + "comparison": "startswith" } ] } diff --git a/adapters/adman/adman.go b/adapters/adman/adman.go index e6a4da712b3..8f90a0fe5bb 100644 --- a/adapters/adman/adman.go +++ b/adapters/adman/adman.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) // AdmanAdapter struct @@ -38,12 +39,12 @@ func (a *AdmanAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapt reqCopy.Imp = []openrtb2.Imp{imp} var bidderExt adapters.ExtImpBidder - if err = json.Unmarshal(reqCopy.Imp[0].Ext, &bidderExt); err != nil { + if err = jsonutil.Unmarshal(reqCopy.Imp[0].Ext, &bidderExt); err != nil { errs = append(errs, err) continue } - if err = json.Unmarshal(bidderExt.Bidder, &admanExt); err != nil { + if err = jsonutil.Unmarshal(bidderExt.Bidder, &admanExt); err != nil { errs = append(errs, err) continue } @@ -98,7 +99,7 @@ func (a *AdmanAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRe var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } diff --git a/adapters/adman/adman_test.go b/adapters/adman/adman_test.go index 5617035c713..1a8eccca62b 100644 --- a/adapters/adman/adman_test.go +++ b/adapters/adman/adman_test.go @@ -3,9 +3,9 @@ package adman import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/adman/admantest/supplemental/bad-imp-ext.json b/adapters/adman/admantest/supplemental/bad-imp-ext.json index db3c8de5767..a4b5cc546f4 100644 --- a/adapters/adman/admantest/supplemental/bad-imp-ext.json +++ b/adapters/adman/admantest/supplemental/bad-imp-ext.json @@ -35,8 +35,8 @@ }, "expectedMakeRequestsErrors": [ { - "value": "unexpected end of JSON input", - "comparison": "literal" + "value": "expect { or n, but found", + "comparison": "startswith" } ] } diff --git a/adapters/adman/admantest/supplemental/bad_response.json b/adapters/adman/admantest/supplemental/bad_response.json index f9920c9069d..96d7a6098ca 100644 --- a/adapters/adman/admantest/supplemental/bad_response.json +++ b/adapters/adman/admantest/supplemental/bad_response.json @@ -79,7 +79,7 @@ }], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/adman/admantest/supplemental/no-imp-ext-1.json b/adapters/adman/admantest/supplemental/no-imp-ext-1.json index 8fad5ba5ef0..d93995bb33e 100644 --- a/adapters/adman/admantest/supplemental/no-imp-ext-1.json +++ b/adapters/adman/admantest/supplemental/no-imp-ext-1.json @@ -31,7 +31,7 @@ }, "expectedMakeRequestsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type adapters.ExtImpBidder", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/adman/admantest/supplemental/no-imp-ext-2.json b/adapters/adman/admantest/supplemental/no-imp-ext-2.json index 337dfd044b3..677260f21e4 100644 --- a/adapters/adman/admantest/supplemental/no-imp-ext-2.json +++ b/adapters/adman/admantest/supplemental/no-imp-ext-2.json @@ -31,8 +31,8 @@ }, "expectedMakeRequestsErrors": [ { - "value": "unexpected end of JSON input", - "comparison": "literal" + "value": "expect { or n, but found", + "comparison": "startswith" } ] } diff --git a/adapters/adman/params_test.go b/adapters/adman/params_test.go index 9d7e0c16d51..97b3d8f3f2c 100644 --- a/adapters/adman/params_test.go +++ b/adapters/adman/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // TestValidParams makes sure that the adman schema accepts all imp.ext fields which we intend to support. diff --git a/adapters/admatic/admatic.go b/adapters/admatic/admatic.go new file mode 100644 index 00000000000..6b0ed99f4df --- /dev/null +++ b/adapters/admatic/admatic.go @@ -0,0 +1,139 @@ +package admatic + +import ( + "encoding/json" + "fmt" + "net/http" + "text/template" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" +) + +type adapter struct { + endpoint *template.Template +} + +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + endpointTemplate, err := template.New("endpointTemplate").Parse(config.Endpoint) + if err != nil { + return nil, fmt.Errorf("unable to parse endpoint template: %v", err) + } + + bidder := &adapter{ + endpoint: endpointTemplate, + } + return bidder, nil +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + var requests []*adapters.RequestData + var errs []error + + requestCopy := *request + for _, imp := range request.Imp { + requestCopy.Imp = []openrtb2.Imp{imp} + + endpoint, err := a.buildEndpointFromRequest(&imp) + if err != nil { + errs = append(errs, err) + continue + } + + requestJSON, err := json.Marshal(requestCopy) + if err != nil { + errs = append(errs, err) + continue + } + + request := &adapters.RequestData{ + Method: http.MethodPost, + Body: requestJSON, + Uri: endpoint, + ImpIDs: openrtb_ext.GetImpIDs(requestCopy.Imp), + } + + requests = append(requests, request) + } + + return requests, errs +} + +func (a *adapter) buildEndpointFromRequest(imp *openrtb2.Imp) (string, error) { + var impExt adapters.ExtImpBidder + if err := jsonutil.Unmarshal(imp.Ext, &impExt); err != nil { + return "", &errortypes.BadInput{ + Message: fmt.Sprintf("Failed to deserialize bidder impression extension: %v", err), + } + } + + var admaticExt openrtb_ext.ImpExtAdmatic + if err := jsonutil.Unmarshal(impExt.Bidder, &admaticExt); err != nil { + return "", &errortypes.BadInput{ + Message: fmt.Sprintf("Failed to deserialize AdMatic extension: %v", err), + } + } + + endpointParams := macros.EndpointTemplateParams{ + Host: admaticExt.Host, + } + + return macros.ResolveMacros(a.endpoint, endpointParams) +} + +func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if adapters.IsResponseStatusCodeNoContent(responseData) { + return nil, nil + } + + err := adapters.CheckResponseStatusCodeForErrors(responseData) + if err != nil { + return nil, []error{err} + } + var response openrtb2.BidResponse + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { + return nil, []error{err} + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) + if len(response.Cur) != 0 { + bidResponse.Currency = response.Cur + } + + for _, seatBid := range response.SeatBid { + for i := range seatBid.Bid { + + bidMediaType, err := getMediaTypeForBid(seatBid.Bid[i].ImpID, request.Imp) + if err != nil { + return nil, []error{err} + } + bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ + Bid: &seatBid.Bid[i], + BidType: bidMediaType, + }) + } + } + return bidResponse, nil +} + +func getMediaTypeForBid(impID string, imps []openrtb2.Imp) (openrtb_ext.BidType, error) { + for _, imp := range imps { + if imp.ID == impID { + if imp.Banner != nil { + return openrtb_ext.BidTypeBanner, nil + } else if imp.Video != nil { + return openrtb_ext.BidTypeVideo, nil + } else if imp.Native != nil { + return openrtb_ext.BidTypeNative, nil + } + } + } + return "", &errortypes.BadServerResponse{ + Message: fmt.Sprintf("The impression with ID %s is not present into the request", impID), + } +} diff --git a/adapters/admatic/admatic_test.go b/adapters/admatic/admatic_test.go new file mode 100644 index 00000000000..c98f14e90a0 --- /dev/null +++ b/adapters/admatic/admatic_test.go @@ -0,0 +1,29 @@ +package admatic + +import ( + "testing" + + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/stretchr/testify/assert" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderAdmatic, config.Adapter{ + Endpoint: "http://pbs.admatic.com.tr?host={{.Host}}"}, + config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1281, DataCenter: "2"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "admatictest", bidder) +} + +func TestEndpointTemplateMalformed(t *testing.T) { + _, buildErr := Builder(openrtb_ext.BidderAdmatic, config.Adapter{ + Endpoint: "host={{Host}}"}, config.Server{ExternalUrl: "http://hosturl.com"}) + + assert.Error(t, buildErr) +} diff --git a/adapters/admatic/admatictest/exemplary/banner.json b/adapters/admatic/admatictest/exemplary/banner.json new file mode 100644 index 00000000000..5950034a61e --- /dev/null +++ b/adapters/admatic/admatictest/exemplary/banner.json @@ -0,0 +1,96 @@ +{ + "mockBidRequest": { + "id": "test-request-id-banner", + "imp": [ + { + "id": "test-imp-id-banner", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "host": "layer.serve.admatic.com.tr", + "networkId": 12345 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://pbs.admatic.com.tr?host=layer.serve.admatic.com.tr", + "body": { + "id": "test-request-id-banner", + "imp": [ + { + "id": "test-imp-id-banner", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "host": "layer.serve.admatic.com.tr", + "networkId": 12345 + } + } + } + ] + }, + "impIDs": ["test-imp-id-banner"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id-banner", + "seatbid": [ + { + "seat": "admatic", + "bid": [ + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id-banner", + "price": 0.5, + "adm": "some-test-ad-banner", + "crid": "crid_10", + "w": 728, + "h": 90 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id-banner", + "price": 0.5, + "adm": "some-test-ad-banner", + "crid": "crid_10", + "w": 728, + "h": 90 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/admatic/admatictest/exemplary/multiple-imps.json b/adapters/admatic/admatictest/exemplary/multiple-imps.json new file mode 100644 index 00000000000..8738fbb7f95 --- /dev/null +++ b/adapters/admatic/admatictest/exemplary/multiple-imps.json @@ -0,0 +1,181 @@ +{ + "mockBidRequest": { + "id": "test-request-id-banner", + "imp": [ + { + "id": "test-imp-id-banner", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "host": "layer.serve.admatic.com.tr", + "networkId": 12345 + } + } + }, + { + "id": "test-imp-id-banner2", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "host": "layer2.serve.admatic.com.tr", + "networkId": 123456 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://pbs.admatic.com.tr?host=layer.serve.admatic.com.tr", + "body": { + "id": "test-request-id-banner", + "imp": [ + { + "id": "test-imp-id-banner", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "host": "layer.serve.admatic.com.tr", + "networkId": 12345 + } + } + } + ] + }, + "impIDs": ["test-imp-id-banner"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id-banner", + "seatbid": [ + { + "seat": "admatic", + "bid": [ + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id-banner", + "price": 0.5, + "adm": "some-test-ad-banner", + "crid": "crid_10", + "w": 728, + "h": 90 + } + ] + } + ], + "cur": "USD" + } + } + }, + { + "expectedRequest": { + "uri": "http://pbs.admatic.com.tr?host=layer2.serve.admatic.com.tr", + "body": { + "id": "test-request-id-banner", + "imp": [ + { + "id": "test-imp-id-banner2", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "host": "layer2.serve.admatic.com.tr", + "networkId": 123456 + } + } + } + ] + }, + "impIDs": ["test-imp-id-banner2"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id-banner", + "seatbid": [ + { + "seat": "admatic", + "bid": [ + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e801", + "impid": "test-imp-id-banner2", + "price": 0.5, + "adm": "some-test-ad-banner2", + "crid": "crid_11", + "w": 728, + "h": 90 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id-banner", + "price": 0.5, + "adm": "some-test-ad-banner", + "crid": "crid_10", + "w": 728, + "h": 90 + }, + "type": "banner" + } + ] + }, + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e801", + "impid": "test-imp-id-banner2", + "price": 0.5, + "adm": "some-test-ad-banner2", + "crid": "crid_11", + "w": 728, + "h": 90 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/admatic/admatictest/exemplary/native.json b/adapters/admatic/admatictest/exemplary/native.json new file mode 100644 index 00000000000..455406d05c2 --- /dev/null +++ b/adapters/admatic/admatictest/exemplary/native.json @@ -0,0 +1,86 @@ +{ + "mockBidRequest": { + "id": "test-request-id-native", + "imp": [ + { + "id": "test-imp-id-native", + "native": { + "request": "" + }, + "ext": { + "bidder": { + "host": "layer.serve.admatic.com.tr", + "networkId": 12345 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://pbs.admatic.com.tr?host=layer.serve.admatic.com.tr", + "body": { + "id": "test-request-id-native", + "imp": [ + { + "id": "test-imp-id-native", + "native": { + "request": "" + }, + "ext": { + "bidder": { + "host": "layer.serve.admatic.com.tr", + "networkId": 12345 + } + } + } + ] + }, + "impIDs": ["test-imp-id-native"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id-native", + "seatbid": [ + { + "seat": "admatic", + "bid": [ + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id-native", + "price": 0.5, + "adm": "some-test-ad-native", + "crid": "crid_10", + "w": 728, + "h": 90 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id-native", + "price": 0.5, + "adm": "some-test-ad-native", + "crid": "crid_10", + "w": 728, + "h": 90 + }, + "type": "native" + } + ] + } + ] +} diff --git a/adapters/admatic/admatictest/exemplary/optional-params.json b/adapters/admatic/admatictest/exemplary/optional-params.json new file mode 100644 index 00000000000..e1652c30899 --- /dev/null +++ b/adapters/admatic/admatictest/exemplary/optional-params.json @@ -0,0 +1,100 @@ +{ + "mockBidRequest": { + "id": "test-request-id-banner", + "imp": [ + { + "id": "test-imp-id-banner", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "host": "layer.serve.admatic.com.tr", + "networkId": 12345, + "bidFloor": 0.1, + "isTest": false + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://pbs.admatic.com.tr?host=layer.serve.admatic.com.tr", + "body": { + "id": "test-request-id-banner", + "imp": [ + { + "id": "test-imp-id-banner", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "host": "layer.serve.admatic.com.tr", + "networkId": 12345, + "bidFloor": 0.1, + "isTest": false + } + } + } + ] + }, + "impIDs": ["test-imp-id-banner"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id-banner", + "seatbid": [ + { + "seat": "admatic", + "bid": [ + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id-banner", + "price": 0.5, + "adm": "some-test-ad-banner", + "crid": "crid_10", + "w": 728, + "h": 90 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id-banner", + "price": 0.5, + "adm": "some-test-ad-banner", + "crid": "crid_10", + "w": 728, + "h": 90 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/admatic/admatictest/exemplary/video.json b/adapters/admatic/admatictest/exemplary/video.json new file mode 100644 index 00000000000..58f5e89810b --- /dev/null +++ b/adapters/admatic/admatictest/exemplary/video.json @@ -0,0 +1,94 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-video-id", + "video": { + "mimes": ["video/mp4"], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "host": "layer.serve.admatic.com.tr", + "networkId": 12345 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://pbs.admatic.com.tr?host=layer.serve.admatic.com.tr", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-video-id", + "video": { + "mimes": ["video/mp4"], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "host": "layer.serve.admatic.com.tr", + "networkId": 12345 + } + } + } + ] + }, + "impIDs": ["test-video-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id-test-video-id", + "seatbid": [ + { + "seat": "test-seat", + "bid": [ + { + "id": "5dce6055-a93c-1fd0-8c29-14afc3e510fd", + "impid": "test-video-id", + "price": 0.1529, + "nurl": "test-win", + "adm": "test-video", + "adid": "92-288", + "adomain": ["advertiserdomain.com"], + "crid": "288", + "w": 300, + "h": 250 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "5dce6055-a93c-1fd0-8c29-14afc3e510fd", + "impid": "test-video-id", + "price": 0.1529, + "nurl": "test-win", + "adm": "test-video", + "adid": "92-288", + "adomain": ["advertiserdomain.com"], + "crid": "288", + "w": 300, + "h": 250 + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/admatic/admatictest/supplemental/bad-request.json b/adapters/admatic/admatictest/supplemental/bad-request.json new file mode 100644 index 00000000000..90f6ebd6c9d --- /dev/null +++ b/adapters/admatic/admatictest/supplemental/bad-request.json @@ -0,0 +1,66 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "host": "layer.serve.admatic.com.tr", + "networkId": 12345 + } + } + } + ] + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://pbs.admatic.com.tr?host=layer.serve.admatic.com.tr", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "host": "layer.serve.admatic.com.tr", + "networkId": 12345 + } + } + } + ] + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 400, + "headers": {} + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] + } + \ No newline at end of file diff --git a/adapters/admatic/admatictest/supplemental/multiple-imps-with-error.json b/adapters/admatic/admatictest/supplemental/multiple-imps-with-error.json new file mode 100644 index 00000000000..b23c794c1ba --- /dev/null +++ b/adapters/admatic/admatictest/supplemental/multiple-imps-with-error.json @@ -0,0 +1,119 @@ +{ + "mockBidRequest": { + "id": "test-request-id-banner", + "imp": [ + { + "id": "test-imp-id-banner", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "host": "layer.serve.admatic.com.tr", + "networkId": 12345 + } + } + }, + { + "id": "test-imp-id-banner2", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "host": {}, + "networkId": 12345 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://pbs.admatic.com.tr?host=layer.serve.admatic.com.tr", + "body": { + "id": "test-request-id-banner", + "imp": [ + { + "id": "test-imp-id-banner", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "host": "layer.serve.admatic.com.tr", + "networkId": 12345 + } + } + } + ] + }, + "impIDs": ["test-imp-id-banner"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id-banner", + "seatbid": [ + { + "seat": "admatic", + "bid": [ + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id-banner", + "price": 0.5, + "adm": "some-test-ad-banner", + "crid": "crid_10", + "w": 728, + "h": 90 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedMakeRequestsErrors": [ + { + "value": "Failed to deserialize AdMatic extension: cannot unmarshal openrtb_ext.ImpExtAdmatic.Host: expects \" or n, but found {", + "comparison": "literal" + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id-banner", + "price": 0.5, + "adm": "some-test-ad-banner", + "crid": "crid_10", + "w": 728, + "h": 90 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/admatic/admatictest/supplemental/response-200-without-body.json b/adapters/admatic/admatictest/supplemental/response-200-without-body.json new file mode 100644 index 00000000000..6cded7606e2 --- /dev/null +++ b/adapters/admatic/admatictest/supplemental/response-200-without-body.json @@ -0,0 +1,64 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "host": "layer.serve.admatic.com.tr", + "networkId": 12345 + } + } + } + ] + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://pbs.admatic.com.tr?host=layer.serve.admatic.com.tr", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "host": "layer.serve.admatic.com.tr", + "networkId": 12345 + } + } + } + ] + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200 + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "expect { or n, but found", + "comparison": "startswith" + } + ] +} \ No newline at end of file diff --git a/adapters/admatic/admatictest/supplemental/response-204.json b/adapters/admatic/admatictest/supplemental/response-204.json new file mode 100644 index 00000000000..849cc85e89b --- /dev/null +++ b/adapters/admatic/admatictest/supplemental/response-204.json @@ -0,0 +1,59 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "host": "layer.serve.admatic.com.tr", + "networkId": 12345 + } + } + } + ] + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://pbs.admatic.com.tr?host=layer.serve.admatic.com.tr", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "host": "layer.serve.admatic.com.tr", + "networkId": 12345 + } + } + } + ] + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 204 + } + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/admatic/admatictest/supplemental/server-error.json b/adapters/admatic/admatictest/supplemental/server-error.json new file mode 100644 index 00000000000..91bb22733bc --- /dev/null +++ b/adapters/admatic/admatictest/supplemental/server-error.json @@ -0,0 +1,65 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "host": "layer.serve.admatic.com.tr", + "networkId": 12345 + } + } + } + ] + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://pbs.admatic.com.tr?host=layer.serve.admatic.com.tr", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "host": "layer.serve.admatic.com.tr", + "networkId": 12345 + } + } + } + ] + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 500, + "headers": {} + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 500. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} diff --git a/adapters/admatic/params_test.go b/adapters/admatic/params_test.go new file mode 100644 index 00000000000..fc92a1d7799 --- /dev/null +++ b/adapters/admatic/params_test.go @@ -0,0 +1,56 @@ +package admatic + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v3/openrtb_ext" +) + +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json schema. %v", err) + } + + for _, p := range validParams { + if err := validator.Validate(openrtb_ext.BidderAdmatic, json.RawMessage(p)); err != nil { + t.Errorf("Schema rejected valid params: %s", p) + } + } +} + +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json schema. %v", err) + } + + for _, p := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderAdmatic, json.RawMessage(p)); err == nil { + t.Errorf("Schema allowed invalid params: %s", p) + } + } +} + +var validParams = []string{ + `{ "host": "layer.serve.admatic.com.tr", + "networkId": 1111, + "ext": { + "key1": "value1", + "key2": "value2" + } + }`, + `{"host": "layer.serve.admatic.com.tr", "networkId": 1111}`, +} + +var invalidParams = []string{ + `{"ext": { + "key1": "value1", + "key2": "value2" + }`, + `{}`, + `{"host": 123, "networkId":"1111"}`, + `{"host": "layer.serve.admatic.com.tr", "networkId":"1111"}`, + `{"host": 1111, "networkId":1111}`, +} diff --git a/adapters/admixer/admixer.go b/adapters/admixer/admixer.go index 968b5954103..726c2cb98cc 100644 --- a/adapters/admixer/admixer.go +++ b/adapters/admixer/admixer.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type AdmixerAdapter struct { @@ -87,14 +88,14 @@ func (a *AdmixerAdapter) makeRequest(request *openrtb2.BidRequest) (*adapters.Re func preprocess(imp *openrtb2.Imp) error { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return &errortypes.BadInput{ Message: err.Error(), } } var admixerExt openrtb_ext.ExtImpAdmixer - if err := json.Unmarshal(bidderExt.Bidder, &admixerExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &admixerExt); err != nil { return &errortypes.BadInput{ Message: "Wrong Admixer bidder ext", } @@ -154,7 +155,7 @@ func (a *AdmixerAdapter) MakeBids(internalRequest *openrtb2.BidRequest, external } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } diff --git a/adapters/admixer/admixer_test.go b/adapters/admixer/admixer_test.go index 5985d4303c9..62615a63b3c 100644 --- a/adapters/admixer/admixer_test.go +++ b/adapters/admixer/admixer_test.go @@ -3,9 +3,9 @@ package admixer import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/admixer/params_test.go b/adapters/admixer/params_test.go index af85569b460..cdc8d56c77a 100644 --- a/adapters/admixer/params_test.go +++ b/adapters/admixer/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/admixer.json diff --git a/adapters/adnuntius/adnuntius.go b/adapters/adnuntius/adnuntius.go index 823c1783144..a3024c38d1b 100644 --- a/adapters/adnuntius/adnuntius.go +++ b/adapters/adnuntius/adnuntius.go @@ -10,11 +10,12 @@ import ( "github.com/buger/jsonparser" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/timeutil" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/timeutil" ) type QueryString map[string]string @@ -37,6 +38,11 @@ type siteExt struct { Data interface{} `json:"data"` } +type adnAdvertiser struct { + LegalName string `json:"legalName,omitempty"` + Name string `json:"name,omitempty"` +} + type Ad struct { Bid struct { Amount float64 @@ -56,6 +62,7 @@ type Ad struct { LineItemId string Html string DestinationUrls map[string]string + Advertiser adnAdvertiser `json:"advertiser,omitempty"` } type AdUnit struct { @@ -134,7 +141,7 @@ func makeEndpointUrl(ortbRequest openrtb2.BidRequest, a *adapter, noCookies bool if !noCookies { var deviceExt extDeviceAdnuntius if ortbRequest.Device != nil && ortbRequest.Device.Ext != nil { - if err := json.Unmarshal(ortbRequest.Device.Ext, &deviceExt); err != nil { + if err := jsonutil.Unmarshal(ortbRequest.Device.Ext, &deviceExt); err != nil { return "", []error{fmt.Errorf("failed to parse Adnuntius endpoint: %v", err)} } } @@ -162,7 +169,7 @@ func makeEndpointUrl(ortbRequest openrtb2.BidRequest, a *adapter, noCookies bool } q.Set("tzo", fmt.Sprint(tzo)) - q.Set("format", "json") + q.Set("format", "prebid") url := endpointUrl + "?" + q.Encode() return url, nil @@ -205,14 +212,14 @@ func (a *adapter) generateRequests(ortbRequest openrtb2.BidRequest) ([]*adapters } var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, []error{&errortypes.BadInput{ Message: fmt.Sprintf("Error unmarshalling ExtImpBidder: %s", err.Error()), }} } var adnuntiusExt openrtb_ext.ImpExtAdnunitus - if err := json.Unmarshal(bidderExt.Bidder, &adnuntiusExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &adnuntiusExt); err != nil { return nil, []error{&errortypes.BadInput{ Message: fmt.Sprintf("Error unmarshalling ExtImpValues: %s", err.Error()), }} @@ -267,7 +274,7 @@ func (a *adapter) generateRequests(ortbRequest openrtb2.BidRequest) ([]*adapters var extUser openrtb_ext.ExtUser if ortbRequest.User != nil && ortbRequest.User.Ext != nil { - if err := json.Unmarshal(ortbRequest.User.Ext, &extUser); err != nil { + if err := jsonutil.Unmarshal(ortbRequest.User.Ext, &extUser); err != nil { return nil, []error{fmt.Errorf("failed to parse Ext User: %v", err)} } } @@ -322,7 +329,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, externalRequest *adapte } var adnResponse AdnResponse - if err := json.Unmarshal(response.Body, &adnResponse); err != nil { + if err := jsonutil.Unmarshal(response.Body, &adnResponse); err != nil { return nil, []error{err} } @@ -337,7 +344,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, externalRequest *adapte func getSiteExtAsKv(request *openrtb2.BidRequest) (siteExt, error) { var extSite siteExt if request.Site != nil && request.Site.Ext != nil { - if err := json.Unmarshal(request.Site.Ext, &extSite); err != nil { + if err := jsonutil.Unmarshal(request.Site.Ext, &extSite); err != nil { return extSite, fmt.Errorf("failed to parse ExtSite in Adnuntius: %v", err) } } @@ -349,7 +356,7 @@ func getGDPR(request *openrtb2.BidRequest) (string, string, error) { gdpr := "" var extRegs openrtb_ext.ExtRegs if request.Regs != nil && request.Regs.Ext != nil { - if err := json.Unmarshal(request.Regs.Ext, &extRegs); err != nil { + if err := jsonutil.Unmarshal(request.Regs.Ext, &extRegs); err != nil { return "", "", fmt.Errorf("failed to parse ExtRegs in Adnuntius GDPR check: %v", err) } if extRegs.GDPR != nil && (*extRegs.GDPR == 0 || *extRegs.GDPR == 1) { @@ -360,7 +367,7 @@ func getGDPR(request *openrtb2.BidRequest) (string, string, error) { consent := "" if request.User != nil && request.User.Ext != nil { var extUser openrtb_ext.ExtUser - if err := json.Unmarshal(request.User.Ext, &extUser); err != nil { + if err := jsonutil.Unmarshal(request.User.Ext, &extUser); err != nil { return "", "", fmt.Errorf("failed to parse ExtUser in Adnuntius GDPR check: %v", err) } consent = extUser.Consent @@ -369,6 +376,40 @@ func getGDPR(request *openrtb2.BidRequest) (string, string, error) { return gdpr, consent, nil } +func generateReturnExt(ad Ad, request *openrtb2.BidRequest) (json.RawMessage, error) { + // We always force the publisher to render + var adRender int8 = 0 + + var requestRegsExt *openrtb_ext.ExtRegs + if request.Regs != nil && request.Regs.Ext != nil { + if err := jsonutil.Unmarshal(request.Regs.Ext, &requestRegsExt); err != nil { + + return nil, fmt.Errorf("Failed to parse Ext information in Adnuntius: %v", err) + } + } + + if ad.Advertiser.Name != "" && requestRegsExt != nil && requestRegsExt.DSA != nil { + legalName := ad.Advertiser.Name + if ad.Advertiser.LegalName != "" { + legalName = ad.Advertiser.LegalName + } + ext := &openrtb_ext.ExtBid{ + DSA: &openrtb_ext.ExtBidDSA{ + AdRender: &adRender, + Paid: legalName, + Behalf: legalName, + }, + } + returnExt, err := json.Marshal(ext) + if err != nil { + return nil, fmt.Errorf("Failed to parse Ext information in Adnuntius: %v", err) + } + + return returnExt, nil + } + return nil, nil +} + func generateAdResponse(ad Ad, imp openrtb2.Imp, html string, request *openrtb2.BidRequest) (*openrtb2.Bid, []error) { creativeWidth, widthErr := strconv.ParseInt(ad.CreativeWidth, 10, 64) @@ -388,14 +429,14 @@ func generateAdResponse(ad Ad, imp openrtb2.Imp, html string, request *openrtb2. price := ad.Bid.Amount var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, []error{&errortypes.BadInput{ Message: fmt.Sprintf("Error unmarshalling ExtImpBidder: %s", err.Error()), }} } var adnuntiusExt openrtb_ext.ImpExtAdnunitus - if err := json.Unmarshal(bidderExt.Bidder, &adnuntiusExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &adnuntiusExt); err != nil { return nil, []error{&errortypes.BadInput{ Message: fmt.Sprintf("Error unmarshalling ExtImpValues: %s", err.Error()), }} @@ -410,6 +451,13 @@ func generateAdResponse(ad Ad, imp openrtb2.Imp, html string, request *openrtb2. } } + extJson, err := generateReturnExt(ad, request) + if err != nil { + return nil, []error{&errortypes.BadInput{ + Message: fmt.Sprintf("Error extracting Ext: %s", err.Error()), + }} + } + adDomain := []string{} for _, url := range ad.DestinationUrls { domainArray := strings.Split(url, "/") @@ -429,6 +477,7 @@ func generateAdResponse(ad Ad, imp openrtb2.Imp, html string, request *openrtb2. Price: price * 1000, AdM: html, ADomain: adDomain, + Ext: extJson, } return &bid, nil diff --git a/adapters/adnuntius/adnuntius_test.go b/adapters/adnuntius/adnuntius_test.go index f6edb313708..8b048f7996b 100644 --- a/adapters/adnuntius/adnuntius_test.go +++ b/adapters/adnuntius/adnuntius_test.go @@ -4,10 +4,10 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/adnuntius/adnuntiustest/exemplary/simple-banner.json b/adapters/adnuntius/adnuntiustest/exemplary/simple-banner.json index 881c02e340d..49c74ad6683 100644 --- a/adapters/adnuntius/adnuntiustest/exemplary/simple-banner.json +++ b/adapters/adnuntius/adnuntiustest/exemplary/simple-banner.json @@ -31,7 +31,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "http://whatever.url?format=json&tzo=0", + "uri": "http://whatever.url?format=prebid&tzo=0", "body": { "adUnits": [ { diff --git a/adapters/adnuntius/adnuntiustest/supplemental/check-dealId.json b/adapters/adnuntius/adnuntiustest/supplemental/check-dealId.json index 06dbeff4113..7869fa87f94 100644 --- a/adapters/adnuntius/adnuntiustest/supplemental/check-dealId.json +++ b/adapters/adnuntius/adnuntiustest/supplemental/check-dealId.json @@ -31,7 +31,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "http://whatever.url?format=json&tzo=0", + "uri": "http://whatever.url?format=prebid&tzo=0", "body": { "adUnits": [ { diff --git a/adapters/adnuntius/adnuntiustest/supplemental/check-dsa-advertiser-legalName-omitted.json b/adapters/adnuntius/adnuntiustest/supplemental/check-dsa-advertiser-legalName-omitted.json new file mode 100644 index 00000000000..0b44aa16dca --- /dev/null +++ b/adapters/adnuntius/adnuntiustest/supplemental/check-dsa-advertiser-legalName-omitted.json @@ -0,0 +1,133 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "user": { + "id": "1kjh3429kjh295jkl" + }, + "site": { + "ext":{ + "data" : { + "key": ["value"] + } + } + }, + "regs": { + "ext": { + "dsa": { + "dsarequired": 3, + "datatopub": 1 + } + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "auId": "123" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://whatever.url?format=prebid&tzo=0", + "body": { + "adUnits": [ + { + "auId": "123", + "targetId": "123-test-imp-id", + "dimensions": [[300,250],[300,600]] + } + ], + "kv": { + "key": ["value"] + }, + "metaData": { + "usi": "1kjh3429kjh295jkl" + }, + "context": "unknown" + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "adUnits": [ + { + "auId": "0000000000000123", + "targetId": "123-test-imp-id", + "html": "", + "responseId": "adn-rsp-900646517", + "ads": [ + { + "destinationUrls": { + "url": "http://www.google.com" + }, + "bid": { + "amount": 20.0, + "currency": "NOK" + }, + "adId": "adn-id-1559784094", + "creativeWidth": "980", + "creativeHeight": "240", + "creativeId": "jn9hpzvlsf8cpdmm", + "lineItemId": "q7y9qm5b0xt9htrv", + "advertiser": { + "name": "Name" + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "adn-id-1559784094", + "impid": "test-imp-id", + "price": 20000, + "adm": "", + "adid": "adn-id-1559784094", + "adomain": [ + "google.com" + ], + "cid": "q7y9qm5b0xt9htrv", + "crid": "jn9hpzvlsf8cpdmm", + "w": 980, + "h": 240, + "ext": { + "dsa": { + "paid": "Name", + "behalf": "Name", + "adrender": 0 + } + } + }, + "type": "banner" + + } + ], + "currency": "NOK" + } + ] +} \ No newline at end of file diff --git a/adapters/adnuntius/adnuntiustest/supplemental/check-dsa-advertiser-legalName.json b/adapters/adnuntius/adnuntiustest/supplemental/check-dsa-advertiser-legalName.json new file mode 100644 index 00000000000..7999bd476aa --- /dev/null +++ b/adapters/adnuntius/adnuntiustest/supplemental/check-dsa-advertiser-legalName.json @@ -0,0 +1,134 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "user": { + "id": "1kjh3429kjh295jkl" + }, + "site": { + "ext":{ + "data" : { + "key": ["value"] + } + } + }, + "regs": { + "ext": { + "dsa": { + "dsarequired": 3, + "datatopub": 1 + } + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "auId": "123" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://whatever.url?format=prebid&tzo=0", + "body": { + "adUnits": [ + { + "auId": "123", + "targetId": "123-test-imp-id", + "dimensions": [[300,250],[300,600]] + } + ], + "kv": { + "key": ["value"] + }, + "metaData": { + "usi": "1kjh3429kjh295jkl" + }, + "context": "unknown" + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "adUnits": [ + { + "auId": "0000000000000123", + "targetId": "123-test-imp-id", + "html": "", + "responseId": "adn-rsp-900646517", + "ads": [ + { + "destinationUrls": { + "url": "http://www.google.com" + }, + "bid": { + "amount": 20.0, + "currency": "NOK" + }, + "adId": "adn-id-1559784094", + "creativeWidth": "980", + "creativeHeight": "240", + "creativeId": "jn9hpzvlsf8cpdmm", + "lineItemId": "q7y9qm5b0xt9htrv", + "advertiser": { + "name": "Name", + "legalName": "LegalName" + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "adn-id-1559784094", + "impid": "test-imp-id", + "price": 20000, + "adm": "", + "adid": "adn-id-1559784094", + "adomain": [ + "google.com" + ], + "cid": "q7y9qm5b0xt9htrv", + "crid": "jn9hpzvlsf8cpdmm", + "w": 980, + "h": 240, + "ext": { + "dsa": { + "paid": "LegalName", + "behalf": "LegalName", + "adrender": 0 + } + } + }, + "type": "banner" + + } + ], + "currency": "NOK" + } + ] +} \ No newline at end of file diff --git a/adapters/adnuntius/adnuntiustest/supplemental/check-dsa-advertiser-omitted.json b/adapters/adnuntius/adnuntiustest/supplemental/check-dsa-advertiser-omitted.json new file mode 100644 index 00000000000..11cea9bcf66 --- /dev/null +++ b/adapters/adnuntius/adnuntiustest/supplemental/check-dsa-advertiser-omitted.json @@ -0,0 +1,123 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "user": { + "id": "1kjh3429kjh295jkl" + }, + "site": { + "ext":{ + "data" : { + "key": ["value"] + } + } + }, + "regs": { + "ext": { + "dsa": { + "dsarequired": 3, + "datatopub": 1 + } + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "auId": "123" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://whatever.url?format=prebid&tzo=0", + "body": { + "adUnits": [ + { + "auId": "123", + "targetId": "123-test-imp-id", + "dimensions": [[300,250],[300,600]] + } + ], + "kv": { + "key": ["value"] + }, + "metaData": { + "usi": "1kjh3429kjh295jkl" + }, + "context": "unknown" + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "adUnits": [ + { + "auId": "0000000000000123", + "targetId": "123-test-imp-id", + "html": "", + "responseId": "adn-rsp-900646517", + "ads": [ + { + "destinationUrls": { + "url": "http://www.google.com" + }, + "bid": { + "amount": 20.0, + "currency": "NOK" + }, + "adId": "adn-id-1559784094", + "creativeWidth": "980", + "creativeHeight": "240", + "creativeId": "jn9hpzvlsf8cpdmm", + "lineItemId": "q7y9qm5b0xt9htrv" + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "adn-id-1559784094", + "impid": "test-imp-id", + "price": 20000, + "adm": "", + "adid": "adn-id-1559784094", + "adomain": [ + "google.com" + ], + "cid": "q7y9qm5b0xt9htrv", + "crid": "jn9hpzvlsf8cpdmm", + "w": 980, + "h": 240 + }, + "type": "banner" + + } + ], + "currency": "NOK" + } + ] +} \ No newline at end of file diff --git a/adapters/adnuntius/adnuntiustest/supplemental/check-gdpr.json b/adapters/adnuntius/adnuntiustest/supplemental/check-gdpr.json index 44e59316a7d..296aa4894a4 100644 --- a/adapters/adnuntius/adnuntiustest/supplemental/check-gdpr.json +++ b/adapters/adnuntius/adnuntiustest/supplemental/check-gdpr.json @@ -38,7 +38,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "http://gdpr.url?consentString=CONSENT_STRING&format=json&gdpr=1&tzo=0", + "uri": "http://gdpr.url?consentString=CONSENT_STRING&format=prebid&gdpr=1&tzo=0", "body": { "adUnits": [ { diff --git a/adapters/adnuntius/adnuntiustest/supplemental/check-gross-bids.json b/adapters/adnuntius/adnuntiustest/supplemental/check-gross-bids.json index 7e533098fb5..95c77e464a9 100644 --- a/adapters/adnuntius/adnuntiustest/supplemental/check-gross-bids.json +++ b/adapters/adnuntius/adnuntiustest/supplemental/check-gross-bids.json @@ -31,7 +31,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "http://whatever.url?format=json&tzo=0", + "uri": "http://whatever.url?format=prebid&tzo=0", "body": { "adUnits": [ { diff --git a/adapters/adnuntius/adnuntiustest/supplemental/check-net-bids.json b/adapters/adnuntius/adnuntiustest/supplemental/check-net-bids.json index 301a1f60fec..236d9f6d489 100644 --- a/adapters/adnuntius/adnuntiustest/supplemental/check-net-bids.json +++ b/adapters/adnuntius/adnuntiustest/supplemental/check-net-bids.json @@ -31,7 +31,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "http://whatever.url?format=json&tzo=0", + "uri": "http://whatever.url?format=prebid&tzo=0", "body": { "adUnits": [ { diff --git a/adapters/adnuntius/adnuntiustest/supplemental/check-noCookies-parameter.json b/adapters/adnuntius/adnuntiustest/supplemental/check-noCookies-parameter.json index 5ac10a86ce5..7104b6b0580 100644 --- a/adapters/adnuntius/adnuntiustest/supplemental/check-noCookies-parameter.json +++ b/adapters/adnuntius/adnuntiustest/supplemental/check-noCookies-parameter.json @@ -31,7 +31,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "http://whatever.url?format=json&noCookies=true&tzo=0", + "uri": "http://whatever.url?format=prebid&noCookies=true&tzo=0", "body": { "adUnits": [ { diff --git a/adapters/adnuntius/adnuntiustest/supplemental/check-noCookies.json b/adapters/adnuntius/adnuntiustest/supplemental/check-noCookies.json index 7080ef678d2..f60f7a636a9 100644 --- a/adapters/adnuntius/adnuntiustest/supplemental/check-noCookies.json +++ b/adapters/adnuntius/adnuntiustest/supplemental/check-noCookies.json @@ -35,7 +35,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "http://whatever.url?format=json&noCookies=true&tzo=0", + "uri": "http://whatever.url?format=prebid&noCookies=true&tzo=0", "body": { "adUnits": [ { diff --git a/adapters/adnuntius/adnuntiustest/supplemental/check-order-multi-imp.json b/adapters/adnuntius/adnuntiustest/supplemental/check-order-multi-imp.json index 75b08f73716..2269297d9cd 100644 --- a/adapters/adnuntius/adnuntiustest/supplemental/check-order-multi-imp.json +++ b/adapters/adnuntius/adnuntiustest/supplemental/check-order-multi-imp.json @@ -47,11 +47,11 @@ } ] }, - + "httpCalls": [ { "expectedRequest": { - "uri": "http://whatever.url?format=json&tzo=0", + "uri": "http://whatever.url?format=prebid&tzo=0", "body": { "adUnits": [ { @@ -159,6 +159,6 @@ ], "currency": "NOK" } - + ] } diff --git a/adapters/adnuntius/adnuntiustest/supplemental/check-price-type-error.json b/adapters/adnuntius/adnuntiustest/supplemental/check-price-type-error.json index 89016087a43..35129b1ee54 100644 --- a/adapters/adnuntius/adnuntiustest/supplemental/check-price-type-error.json +++ b/adapters/adnuntius/adnuntiustest/supplemental/check-price-type-error.json @@ -31,7 +31,7 @@ "httpCalls": [], "expectedMakeRequestsErrors": [ { - "value": "Error unmarshalling ExtImpValues: json: cannot unmarshal number into Go struct field ImpExtAdnunitus.bidType of type string", + "value": "Error unmarshalling ExtImpValues: cannot unmarshal openrtb_ext.ImpExtAdnunitus.BidType: expects \" or n, but found 1", "comparison": "literal" } ] diff --git a/adapters/adnuntius/adnuntiustest/supplemental/check-userId.json b/adapters/adnuntius/adnuntiustest/supplemental/check-userId.json index eb2f71111a7..2263798d3e5 100644 --- a/adapters/adnuntius/adnuntiustest/supplemental/check-userId.json +++ b/adapters/adnuntius/adnuntiustest/supplemental/check-userId.json @@ -30,7 +30,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "http://whatever.url?format=json&tzo=0", + "uri": "http://whatever.url?format=prebid&tzo=0", "body": { "adUnits": [ { diff --git a/adapters/adnuntius/adnuntiustest/supplemental/empty-regs-ext.json b/adapters/adnuntius/adnuntiustest/supplemental/empty-regs-ext.json index d0b7b1450ea..211416294ce 100644 --- a/adapters/adnuntius/adnuntiustest/supplemental/empty-regs-ext.json +++ b/adapters/adnuntius/adnuntiustest/supplemental/empty-regs-ext.json @@ -33,7 +33,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "http://whatever.url?format=json&tzo=0", + "uri": "http://whatever.url?format=prebid&tzo=0", "body": { "adUnits": [ { diff --git a/adapters/adnuntius/adnuntiustest/supplemental/empty-regs.json b/adapters/adnuntius/adnuntiustest/supplemental/empty-regs.json index 79571562c7f..2d3d0c861d0 100644 --- a/adapters/adnuntius/adnuntiustest/supplemental/empty-regs.json +++ b/adapters/adnuntius/adnuntiustest/supplemental/empty-regs.json @@ -32,7 +32,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "http://whatever.url?format=json&tzo=0", + "uri": "http://whatever.url?format=prebid&tzo=0", "body": { "adUnits": [ { diff --git a/adapters/adnuntius/adnuntiustest/supplemental/height-error.json b/adapters/adnuntius/adnuntiustest/supplemental/height-error.json index c58d27eba3e..4f066aa7e1f 100644 --- a/adapters/adnuntius/adnuntiustest/supplemental/height-error.json +++ b/adapters/adnuntius/adnuntiustest/supplemental/height-error.json @@ -30,7 +30,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "http://whatever.url?format=json&tzo=0", + "uri": "http://whatever.url?format=prebid&tzo=0", "body": { "adUnits": [ { @@ -82,7 +82,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal number into Go struct field Ad.AdUnits.Ads.CreativeHeight of type string", + "value": "cannot unmarshal adnuntius.Ad.CreativeHeight: expects \" or n, but found 2", "comparison": "literal" } ] diff --git a/adapters/adnuntius/adnuntiustest/supplemental/invalid-regs-ext.json b/adapters/adnuntius/adnuntiustest/supplemental/invalid-regs-ext.json new file mode 100644 index 00000000000..27e043de1cb --- /dev/null +++ b/adapters/adnuntius/adnuntiustest/supplemental/invalid-regs-ext.json @@ -0,0 +1,46 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "user": { + "id": "1kjh3429kjh295jkl" + }, + "site": { + "ext":{ + "data" : { + "key": ["value"] + } + } + }, + "regs": { + "ext": "" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "auId": "123" + } + } + } + ] + }, + "expectedMakeRequestsErrors": [ + { + "value": "failed to parse URL: [failed to parse Adnuntius endpoint: failed to parse ExtRegs in Adnuntius GDPR check: expect { or n, but found \"]", + "comparison": "literal" + } + ] +} diff --git a/adapters/adnuntius/adnuntiustest/supplemental/max-deals-test.json b/adapters/adnuntius/adnuntiustest/supplemental/max-deals-test.json index 7f480d8cd08..9a2f24bdc45 100644 --- a/adapters/adnuntius/adnuntiustest/supplemental/max-deals-test.json +++ b/adapters/adnuntius/adnuntiustest/supplemental/max-deals-test.json @@ -28,11 +28,11 @@ } ] }, - + "httpCalls": [ { "expectedRequest": { - "uri": "http://whatever.url?format=json&tzo=0", + "uri": "http://whatever.url?format=prebid&tzo=0", "body": { "adUnits": [ { diff --git a/adapters/adnuntius/adnuntiustest/supplemental/send-header-information.json b/adapters/adnuntius/adnuntiustest/supplemental/send-header-information.json index 8d2b60da238..2383cd4e3e7 100644 --- a/adapters/adnuntius/adnuntiustest/supplemental/send-header-information.json +++ b/adapters/adnuntius/adnuntiustest/supplemental/send-header-information.json @@ -50,7 +50,7 @@ "Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Mobile Safari/537.36" ] }, - "uri": "http://whatever.url?format=json&tzo=0", + "uri": "http://whatever.url?format=prebid&tzo=0", "body": { "adUnits": [ { diff --git a/adapters/adnuntius/adnuntiustest/supplemental/site-ext.json b/adapters/adnuntius/adnuntiustest/supplemental/site-ext.json index 8213ac1787f..ddf37962054 100644 --- a/adapters/adnuntius/adnuntiustest/supplemental/site-ext.json +++ b/adapters/adnuntius/adnuntiustest/supplemental/site-ext.json @@ -37,7 +37,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "http://whatever.url?format=json&tzo=0", + "uri": "http://whatever.url?format=prebid&tzo=0", "body": { "adUnits": [ { @@ -111,4 +111,4 @@ "currency": "NOK" } ] -} \ No newline at end of file +} diff --git a/adapters/adnuntius/adnuntiustest/supplemental/size-check.json b/adapters/adnuntius/adnuntiustest/supplemental/size-check.json index da17af1497d..f39586d9b9f 100644 --- a/adapters/adnuntius/adnuntiustest/supplemental/size-check.json +++ b/adapters/adnuntius/adnuntiustest/supplemental/size-check.json @@ -28,7 +28,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "http://whatever.url?format=json&noCookies=true&tzo=0", + "uri": "http://whatever.url?format=prebid&noCookies=true&tzo=0", "body": { "adUnits": [ { diff --git a/adapters/adnuntius/adnuntiustest/supplemental/status-400.json b/adapters/adnuntius/adnuntiustest/supplemental/status-400.json index ca54a2057e8..695aeb36e0d 100644 --- a/adapters/adnuntius/adnuntiustest/supplemental/status-400.json +++ b/adapters/adnuntius/adnuntiustest/supplemental/status-400.json @@ -27,7 +27,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "http://whatever.url?format=json&tzo=0", + "uri": "http://whatever.url?format=prebid&tzo=0", "body": { "adUnits": [ { diff --git a/adapters/adnuntius/adnuntiustest/supplemental/test-networks.json b/adapters/adnuntius/adnuntiustest/supplemental/test-networks.json index 6e608b28a39..b81e51cd3d9 100644 --- a/adapters/adnuntius/adnuntiustest/supplemental/test-networks.json +++ b/adapters/adnuntius/adnuntiustest/supplemental/test-networks.json @@ -32,7 +32,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "http://whatever.url?format=json&tzo=0", + "uri": "http://whatever.url?format=prebid&tzo=0", "body": { "adUnits": [ { diff --git a/adapters/adnuntius/adnuntiustest/supplemental/user-ext.json b/adapters/adnuntius/adnuntiustest/supplemental/user-ext.json index 0d852386b9e..2c2dcac1575 100644 --- a/adapters/adnuntius/adnuntiustest/supplemental/user-ext.json +++ b/adapters/adnuntius/adnuntiustest/supplemental/user-ext.json @@ -4,11 +4,11 @@ "user": { "ext":{ "eids" : [ - { - "source": "idProvider", + { + "source": "idProvider", "uids": [ { "id": "userId", "atype": 1, "ext": { "stype": "ppuid" } } - ] + ] } ] } @@ -39,7 +39,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "http://whatever.url?format=json&tzo=0", + "uri": "http://whatever.url?format=prebid&tzo=0", "body": { "adUnits": [ { @@ -110,4 +110,4 @@ "currency": "NOK" } ] -} \ No newline at end of file +} diff --git a/adapters/adnuntius/adnuntiustest/supplemental/width-error.json b/adapters/adnuntius/adnuntiustest/supplemental/width-error.json index 870cdbc3f87..96d98a98b85 100644 --- a/adapters/adnuntius/adnuntiustest/supplemental/width-error.json +++ b/adapters/adnuntius/adnuntiustest/supplemental/width-error.json @@ -30,7 +30,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "http://whatever.url?format=json&tzo=0", + "uri": "http://whatever.url?format=prebid&tzo=0", "body": { "adUnits": [ { @@ -82,7 +82,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal number into Go struct field Ad.AdUnits.Ads.CreativeWidth of type string", + "value": "cannot unmarshal adnuntius.Ad.CreativeWidth: expects \" or n, but found 9", "comparison": "literal" } ] diff --git a/adapters/adnuntius/params_test.go b/adapters/adnuntius/params_test.go index 259b5145801..92db0b9e5ad 100644 --- a/adapters/adnuntius/params_test.go +++ b/adapters/adnuntius/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/adnuntius.json diff --git a/adapters/adocean/adocean.go b/adapters/adocean/adocean.go index 560df4893b9..82f32001596 100644 --- a/adapters/adocean/adocean.go +++ b/adapters/adocean/adocean.go @@ -1,7 +1,6 @@ package adocean import ( - "encoding/json" "errors" "fmt" "math/rand" @@ -14,11 +13,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) const adapterVersion = "1.3.0" @@ -91,7 +91,7 @@ func (a *AdOceanAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *ada consentString := "" if request.User != nil { var extUser openrtb_ext.ExtUser - if err := json.Unmarshal(request.User.Ext, &extUser); err == nil { + if err := jsonutil.Unmarshal(request.User.Ext, &extUser); err == nil { consentString = extUser.Consent } } @@ -126,14 +126,14 @@ func (a *AdOceanAdapter) addNewBid( consentString string, ) ([]*requestData, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return requestsData, &errortypes.BadInput{ Message: "Error parsing bidderExt object", } } var adOceanExt openrtb_ext.ExtImpAdOcean - if err := json.Unmarshal(bidderExt.Bidder, &adOceanExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &adOceanExt); err != nil { return requestsData, &errortypes.BadInput{ Message: "Error parsing adOceanExt parameters", } @@ -349,7 +349,7 @@ func (a *AdOceanAdapter) MakeBids( auctionIDs := queryParams["aid"] bidResponses := make([]ResponseAdUnit, 0) - if err := json.Unmarshal(response.Body, &bidResponses); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResponses); err != nil { return nil, []error{err} } diff --git a/adapters/adocean/adocean_test.go b/adapters/adocean/adocean_test.go index d7fe33b8de5..4fb784bfc01 100644 --- a/adapters/adocean/adocean_test.go +++ b/adapters/adocean/adocean_test.go @@ -3,9 +3,9 @@ package adocean import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/adocean/adoceantest/supplemental/app.json b/adapters/adocean/adoceantest/supplemental/app.json index b68798d362c..28c67bdf818 100644 --- a/adapters/adocean/adoceantest/supplemental/app.json +++ b/adapters/adocean/adoceantest/supplemental/app.json @@ -65,7 +65,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type []adocean.ResponseAdUnit", + "value": "decode slice: expect [ or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/adocean/adoceantest/supplemental/bad-response.json b/adapters/adocean/adoceantest/supplemental/bad-response.json index 9bf3ab16069..eb1bcb6ef0c 100644 --- a/adapters/adocean/adoceantest/supplemental/bad-response.json +++ b/adapters/adocean/adoceantest/supplemental/bad-response.json @@ -60,7 +60,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type []adocean.ResponseAdUnit", + "value": "decode slice: expect [ or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/adocean/params_test.go b/adapters/adocean/params_test.go index f35dc1aaf87..0840d10847c 100644 --- a/adapters/adocean/params_test.go +++ b/adapters/adocean/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/adoppler/adoppler.go b/adapters/adoppler/adoppler.go index ff588991493..ace52b93b1d 100644 --- a/adapters/adoppler/adoppler.go +++ b/adapters/adoppler/adoppler.go @@ -9,11 +9,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) const DefaultClient = "app" @@ -121,7 +122,7 @@ func (ads *AdopplerAdapter) MakeBids( } var bidResp openrtb2.BidResponse - err := json.Unmarshal(resp.Body, &bidResp) + err := jsonutil.Unmarshal(resp.Body, &bidResp) if err != nil { err := &errortypes.BadServerResponse{ Message: fmt.Sprintf("invalid body: %s", err.Error()), @@ -206,13 +207,13 @@ func (ads *AdopplerAdapter) bidUri(ext *openrtb_ext.ExtImpAdoppler) (string, err func unmarshalExt(ext json.RawMessage) (*openrtb_ext.ExtImpAdoppler, error) { var bext adapters.ExtImpBidder - err := json.Unmarshal(ext, &bext) + err := jsonutil.Unmarshal(ext, &bext) if err != nil { return nil, err } var adsExt openrtb_ext.ExtImpAdoppler - err = json.Unmarshal(bext.Bidder, &adsExt) + err = jsonutil.Unmarshal(bext.Bidder, &adsExt) if err != nil { return nil, err } @@ -228,7 +229,7 @@ func unmarshalAdsExt(ext json.RawMessage) (*adsImpExt, error) { var e struct { Ads *adsImpExt `json:"ads"` } - err := json.Unmarshal(ext, &e) + err := jsonutil.Unmarshal(ext, &e) return e.Ads, err } diff --git a/adapters/adoppler/adoppler_test.go b/adapters/adoppler/adoppler_test.go index d05118c4800..3c6888f3124 100644 --- a/adapters/adoppler/adoppler_test.go +++ b/adapters/adoppler/adoppler_test.go @@ -3,9 +3,9 @@ package adoppler import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/adoppler/adopplertest/supplemental/invalid-response.json b/adapters/adoppler/adopplertest/supplemental/invalid-response.json index 14853d68bdc..84342feaa0e 100644 --- a/adapters/adoppler/adopplertest/supplemental/invalid-response.json +++ b/adapters/adoppler/adopplertest/supplemental/invalid-response.json @@ -50,7 +50,7 @@ ], "expectedMakeBidsErrors":[ { - "value":"invalid body: json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value":"invalid body: expect { or n, but found \"", "comparison":"literal" } ] diff --git a/adapters/adoppler/adopplertest/supplemental/invalid-video-ext.json b/adapters/adoppler/adopplertest/supplemental/invalid-video-ext.json index 84af94e2e3f..6bab4036c5c 100644 --- a/adapters/adoppler/adopplertest/supplemental/invalid-video-ext.json +++ b/adapters/adoppler/adopplertest/supplemental/invalid-video-ext.json @@ -140,7 +140,7 @@ "comparison":"literal" }, { - "value":"json: cannot unmarshal string into Go value of type struct { Ads *adoppler.adsImpExt \"json:\\\"ads\\\"\" }", + "value":"expect { or n, but found \"", "comparison":"literal" } ] diff --git a/adapters/adot/adot.go b/adapters/adot/adot.go index f86281bf79e..fc32ef6cae4 100644 --- a/adapters/adot/adot.go +++ b/adapters/adot/adot.go @@ -8,10 +8,11 @@ import ( "strings" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -84,7 +85,7 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } @@ -116,7 +117,7 @@ func getMediaTypeForBid(bid *openrtb2.Bid) (openrtb_ext.BidType, error) { } var impExt adotBidExt - if err := json.Unmarshal(bid.Ext, &impExt); err == nil { + if err := jsonutil.Unmarshal(bid.Ext, &impExt); err == nil { switch impExt.Adot.MediaType { case string(openrtb_ext.BidTypeBanner): return openrtb_ext.BidTypeBanner, nil @@ -144,11 +145,11 @@ func resolveMacros(bid *openrtb2.Bid) { func getImpAdotExt(imp *openrtb2.Imp) *openrtb_ext.ExtImpAdot { var extImpAdot openrtb_ext.ExtImpAdot var extBidder adapters.ExtImpBidder - err := json.Unmarshal(imp.Ext, &extBidder) + err := jsonutil.Unmarshal(imp.Ext, &extBidder) if err != nil { return nil } - err = json.Unmarshal(extBidder.Bidder, &extImpAdot) + err = jsonutil.Unmarshal(extBidder.Bidder, &extImpAdot) if err != nil { return nil } diff --git a/adapters/adot/adot_test.go b/adapters/adot/adot_test.go index 236287fffa0..d5d5afc6c47 100644 --- a/adapters/adot/adot_test.go +++ b/adapters/adot/adot_test.go @@ -5,10 +5,10 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/adot/adottest/supplemental/unmarshal_error.json b/adapters/adot/adottest/supplemental/unmarshal_error.json index c9c6db88ea7..68154164f47 100644 --- a/adapters/adot/adottest/supplemental/unmarshal_error.json +++ b/adapters/adot/adottest/supplemental/unmarshal_error.json @@ -56,7 +56,7 @@ "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/adot/params_test.go b/adapters/adot/params_test.go index a47ff2ff4eb..99f8c9d932c 100644 --- a/adapters/adot/params_test.go +++ b/adapters/adot/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/adot.json diff --git a/adapters/adpone/adpone.go b/adapters/adpone/adpone.go index c4965f927a9..bdf72398897 100644 --- a/adapters/adpone/adpone.go +++ b/adapters/adpone/adpone.go @@ -6,11 +6,12 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) // Builder builds a new instance of the Adpone adapter for the given bidder with the given config. @@ -35,11 +36,11 @@ func (adapter *adponeAdapter) MakeRequests( if len(openRTBRequest.Imp) > 0 { var imp = &openRTBRequest.Imp[0] var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { errs = append(errs, newBadInputError(err.Error())) } var ttxExt openrtb_ext.ExtAdpone - if err := json.Unmarshal(bidderExt.Bidder, &ttxExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &ttxExt); err != nil { errs = append(errs, newBadInputError(err.Error())) } } @@ -101,7 +102,7 @@ func (adapter *adponeAdapter) MakeBids( } var openRTBBidderResponse openrtb2.BidResponse - if err := json.Unmarshal(bidderRawResponse.Body, &openRTBBidderResponse); err != nil { + if err := jsonutil.Unmarshal(bidderRawResponse.Body, &openRTBBidderResponse); err != nil { return nil, []error{err} } diff --git a/adapters/adpone/adpone_test.go b/adapters/adpone/adpone_test.go index bd4f5ed514e..e90055b2e65 100644 --- a/adapters/adpone/adpone_test.go +++ b/adapters/adpone/adpone_test.go @@ -3,9 +3,9 @@ package adpone import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) const testsDir = "adponetest" diff --git a/adapters/adpone/adponetest/supplemental/bad_response.json b/adapters/adpone/adponetest/supplemental/bad_response.json index 38714ea78b4..2200f89ecd4 100644 --- a/adapters/adpone/adponetest/supplemental/bad_response.json +++ b/adapters/adpone/adponetest/supplemental/bad_response.json @@ -57,7 +57,7 @@ "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/adprime/adprime.go b/adapters/adprime/adprime.go index 2c6c319ef05..a4c041ae325 100644 --- a/adapters/adprime/adprime.go +++ b/adapters/adprime/adprime.go @@ -7,10 +7,11 @@ import ( "strings" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) // AdprimeAdapter struct @@ -40,13 +41,13 @@ func (a *AdprimeAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *ada for _, imp := range request.Imp { reqCopy.Imp = []openrtb2.Imp{imp} - err = json.Unmarshal(reqCopy.Imp[0].Ext, &bidderExt) + err = jsonutil.Unmarshal(reqCopy.Imp[0].Ext, &bidderExt) if err != nil { errs = append(errs, err) return nil, errs } - err = json.Unmarshal(bidderExt.Bidder, &adprimeExt) + err = jsonutil.Unmarshal(bidderExt.Bidder, &adprimeExt) if err != nil { errs = append(errs, err) return nil, errs @@ -141,7 +142,7 @@ func (a *AdprimeAdapter) MakeBids(internalRequest *openrtb2.BidRequest, external var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } diff --git a/adapters/adprime/adprime_test.go b/adapters/adprime/adprime_test.go index 34dde15d1ba..0b238b5bee0 100644 --- a/adapters/adprime/adprime_test.go +++ b/adapters/adprime/adprime_test.go @@ -3,9 +3,9 @@ package adprime import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/adprime/adprimetest/supplemental/bad-imp-ext.json b/adapters/adprime/adprimetest/supplemental/bad-imp-ext.json index 39cd3cd02ce..d2ce5d82cb2 100644 --- a/adapters/adprime/adprimetest/supplemental/bad-imp-ext.json +++ b/adapters/adprime/adprimetest/supplemental/bad-imp-ext.json @@ -35,8 +35,8 @@ }, "expectedMakeRequestsErrors": [ { - "value": "unexpected end of JSON input", - "comparison": "literal" + "value": "expect { or n, but found", + "comparison": "startswith" } ] } \ No newline at end of file diff --git a/adapters/adprime/adprimetest/supplemental/bad_response.json b/adapters/adprime/adprimetest/supplemental/bad_response.json index f28c8864d8e..9893a1a6684 100644 --- a/adapters/adprime/adprimetest/supplemental/bad_response.json +++ b/adapters/adprime/adprimetest/supplemental/bad_response.json @@ -81,7 +81,7 @@ }], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/adprime/adprimetest/supplemental/no-imp-ext-1.json b/adapters/adprime/adprimetest/supplemental/no-imp-ext-1.json index 5ba65925a70..ef5c3009a34 100644 --- a/adapters/adprime/adprimetest/supplemental/no-imp-ext-1.json +++ b/adapters/adprime/adprimetest/supplemental/no-imp-ext-1.json @@ -31,7 +31,7 @@ }, "expectedMakeRequestsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type adapters.ExtImpBidder", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/adprime/adprimetest/supplemental/no-imp-ext-2.json b/adapters/adprime/adprimetest/supplemental/no-imp-ext-2.json index e08f5385b88..f9378c48881 100644 --- a/adapters/adprime/adprimetest/supplemental/no-imp-ext-2.json +++ b/adapters/adprime/adprimetest/supplemental/no-imp-ext-2.json @@ -31,8 +31,8 @@ }, "expectedMakeRequestsErrors": [ { - "value": "unexpected end of JSON input", - "comparison": "literal" + "value": "expect { or n, but found", + "comparison": "startswith" } ] } \ No newline at end of file diff --git a/adapters/adprime/params_test.go b/adapters/adprime/params_test.go index 67bbebf0086..18556d990ec 100644 --- a/adapters/adprime/params_test.go +++ b/adapters/adprime/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // TestValidParams makes sure that the adprime schema accepts all imp.ext fields which we intend to support. diff --git a/adapters/adquery/adquery.go b/adapters/adquery/adquery.go index f615c6ad27d..41813700058 100644 --- a/adapters/adquery/adquery.go +++ b/adapters/adquery/adquery.go @@ -9,10 +9,11 @@ import ( "strings" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) const ( @@ -160,13 +161,13 @@ func buildRequest(bidReq *openrtb2.BidRequest, imp *openrtb2.Imp, ext *openrtb_e func parseExt(ext json.RawMessage) (*openrtb_ext.ImpExtAdQuery, error) { var bext adapters.ExtImpBidder - err := json.Unmarshal(ext, &bext) + err := jsonutil.Unmarshal(ext, &bext) if err != nil { return nil, err } var adsExt openrtb_ext.ImpExtAdQuery - err = json.Unmarshal(bext.Bidder, &adsExt) + err = jsonutil.Unmarshal(bext.Bidder, &adsExt) if err != nil { return nil, err } @@ -177,7 +178,7 @@ func parseExt(ext json.RawMessage) (*openrtb_ext.ImpExtAdQuery, error) { func parseResponseJson(respBody []byte) (*ResponseData, float64, int64, int64, []error) { var response ResponseAdQuery - if err := json.Unmarshal(respBody, &response); err != nil { + if err := jsonutil.Unmarshal(respBody, &response); err != nil { return nil, 0, 0, 0, []error{err} } diff --git a/adapters/adquery/adquery_test.go b/adapters/adquery/adquery_test.go index 792e7c553a8..913e5781950 100644 --- a/adapters/adquery/adquery_test.go +++ b/adapters/adquery/adquery_test.go @@ -3,9 +3,9 @@ package adquery import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/adquery/adquerytest/supplemental/malformed-ext.json b/adapters/adquery/adquerytest/supplemental/malformed-ext.json index 46aaaed431d..aa035c5852b 100644 --- a/adapters/adquery/adquerytest/supplemental/malformed-ext.json +++ b/adapters/adquery/adquerytest/supplemental/malformed-ext.json @@ -32,7 +32,7 @@ "bidder": "adquery" }, "expectedMakeRequestsErrors": [{ - "value": "json: cannot unmarshal array into Go struct field ImpExtAdQuery.placementId of type string", + "value": "cannot unmarshal openrtb_ext.ImpExtAdQuery.PlacementID: expects \" or n, but found [", "comparison": "literal" }] } \ No newline at end of file diff --git a/adapters/adquery/adquerytest/supplemental/malformed-resp.json b/adapters/adquery/adquerytest/supplemental/malformed-resp.json index c65c32cb4fb..f485f394c87 100644 --- a/adapters/adquery/adquerytest/supplemental/malformed-resp.json +++ b/adapters/adquery/adquerytest/supplemental/malformed-resp.json @@ -105,8 +105,8 @@ ], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go struct field ResponseData.data.creationId of type int64", - "comparison": "literal" + "value": "cannot unmarshal adquery.ResponseData.CrID: unexpected character", + "comparison": "startswith" } ] } diff --git a/adapters/adquery/params_test.go b/adapters/adquery/params_test.go index e72b0b02ea3..5619f59cb5e 100644 --- a/adapters/adquery/params_test.go +++ b/adapters/adquery/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/adquery/types.go b/adapters/adquery/types.go index dab9619a7f5..62692bb0d02 100644 --- a/adapters/adquery/types.go +++ b/adapters/adquery/types.go @@ -1,6 +1,6 @@ package adquery -import "github.com/prebid/prebid-server/v2/openrtb_ext" +import "github.com/prebid/prebid-server/v3/openrtb_ext" type BidderRequest struct { V string `json:"v"` diff --git a/adapters/adrino/adrino.go b/adapters/adrino/adrino.go index 830d7d3aca3..9139d01789a 100644 --- a/adapters/adrino/adrino.go +++ b/adapters/adrino/adrino.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -58,7 +59,7 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } diff --git a/adapters/adrino/adrino_test.go b/adapters/adrino/adrino_test.go index e969868c135..48875bed7cc 100644 --- a/adapters/adrino/adrino_test.go +++ b/adapters/adrino/adrino_test.go @@ -5,9 +5,9 @@ import ( "github.com/stretchr/testify/assert" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/adrino/params_test.go b/adapters/adrino/params_test.go index 0ad36e6e4d6..a160113fbd1 100644 --- a/adapters/adrino/params_test.go +++ b/adapters/adrino/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/adrino.json diff --git a/adapters/adsinteractive/adsinteractive.go b/adapters/adsinteractive/adsinteractive.go index c1b521be9f2..1969ceb7cc9 100644 --- a/adapters/adsinteractive/adsinteractive.go +++ b/adapters/adsinteractive/adsinteractive.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -60,7 +61,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } diff --git a/adapters/adsinteractive/adsinteractive_test.go b/adapters/adsinteractive/adsinteractive_test.go index bed577c6003..ae83c615fe8 100644 --- a/adapters/adsinteractive/adsinteractive_test.go +++ b/adapters/adsinteractive/adsinteractive_test.go @@ -3,9 +3,9 @@ package adsinteractive import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) const testsDir = "adsinteractivetest" diff --git a/adapters/adsinteractive/adsinteractivetest/supplemental/bad-response.json b/adapters/adsinteractive/adsinteractivetest/supplemental/bad-response.json index 1539e000094..3f40cfa3512 100644 --- a/adapters/adsinteractive/adsinteractivetest/supplemental/bad-response.json +++ b/adapters/adsinteractive/adsinteractivetest/supplemental/bad-response.json @@ -57,7 +57,7 @@ "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/adsinteractive/params_test.go b/adapters/adsinteractive/params_test.go index caff03a2697..6b377d6aa36 100644 --- a/adapters/adsinteractive/params_test.go +++ b/adapters/adsinteractive/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/adsinteractive.json diff --git a/adapters/adtarget/adtarget.go b/adapters/adtarget/adtarget.go index 8c5d11704a5..c78ffe830f6 100644 --- a/adapters/adtarget/adtarget.go +++ b/adapters/adtarget/adtarget.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type AdtargetAdapter struct { @@ -92,7 +93,7 @@ func (a *AdtargetAdapter) MakeBids(bidReq *openrtb2.BidRequest, unused *adapters }} } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(httpRes.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(httpRes.Body, &bidResp); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: fmt.Sprintf("error while decoding response, err: %s", err), }} @@ -154,14 +155,14 @@ func validateImpressionAndSetExt(imp *openrtb2.Imp) (int, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return 0, &errortypes.BadInput{ Message: fmt.Sprintf("ignoring imp id=%s, error while decoding extImpBidder, err: %s", imp.ID, err), } } impExt := openrtb_ext.ExtImpAdtarget{} - err := json.Unmarshal(bidderExt.Bidder, &impExt) + err := jsonutil.Unmarshal(bidderExt.Bidder, &impExt) if err != nil { return 0, &errortypes.BadInput{ Message: fmt.Sprintf("ignoring imp id=%s, error while decoding impExt, err: %s", imp.ID, err), @@ -185,7 +186,13 @@ func validateImpressionAndSetExt(imp *openrtb2.Imp) (int, error) { imp.Ext = impExtBuffer - return impExt.SourceId, nil + aid, err := impExt.SourceId.Int64() + if err != nil { + return 0, &errortypes.BadInput{ + Message: fmt.Sprintf("ignoring imp id=%s, aid parsing err: %s", imp.ID, err), + } + } + return int(aid), nil } // Builder builds a new instance of the Adtarget adapter for the given bidder with the given config. diff --git a/adapters/adtarget/adtarget_test.go b/adapters/adtarget/adtarget_test.go index 2813ea2c195..23cb51fdfad 100644 --- a/adapters/adtarget/adtarget_test.go +++ b/adapters/adtarget/adtarget_test.go @@ -3,9 +3,9 @@ package adtarget import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/adtarget/adtargettest/supplemental/wrong-impression-ext.json b/adapters/adtarget/adtargettest/supplemental/wrong-impression-ext.json index 1986dfaf13f..7f2b1e3cfcb 100644 --- a/adapters/adtarget/adtargettest/supplemental/wrong-impression-ext.json +++ b/adapters/adtarget/adtargettest/supplemental/wrong-impression-ext.json @@ -19,7 +19,7 @@ "expectedMakeRequestsErrors": [ { - "value": "ignoring imp id=unsupported-native-imp, error while decoding impExt, err: json: cannot unmarshal string into Go struct field ExtImpAdtarget.aid of type int", + "value": "ignoring imp id=unsupported-native-imp, error while encoding impExt, err: json: invalid number literal \"some string instead of int\"", "comparison": "literal" } ] diff --git a/adapters/adtarget/params_test.go b/adapters/adtarget/params_test.go index d0993215086..cb5a8c94791 100644 --- a/adapters/adtarget/params_test.go +++ b/adapters/adtarget/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/adtarget.json @@ -33,16 +33,21 @@ func TestInvalidParams(t *testing.T) { for _, invalidParam := range invalidParams { if err := validator.Validate(openrtb_ext.BidderAdtarget, json.RawMessage(invalidParam)); err == nil { - t.Errorf("Schema allowed unexpected params: %s", invalidParam) + ext := openrtb_ext.ExtImpAdtarget{} + err = json.Unmarshal([]byte(invalidParam), &ext) + if err == nil { + t.Errorf("Schema allowed unexpected params: %s", invalidParam) + } } } } var validParams = []string{ `{"aid":123}`, + `{"aid":"123"}`, `{"aid":123,"placementId":1234}`, `{"aid":123,"siteId":4321}`, - `{"aid":123,"siteId":0,"bidFloor":0}`, + `{"aid":"123","siteId":0,"bidFloor":0}`, } var invalidParams = []string{ @@ -53,8 +58,7 @@ var invalidParams = []string{ `4.2`, `[]`, `{}`, - `{"aid":"123"}`, - `{"aid":"0"}`, + `{"aid":"qwerty"}`, `{"aid":"123","placementId":"123"}`, `{"aid":123, "placementId":"123", "siteId":"321"}`, } diff --git a/adapters/adtelligent/adtelligent.go b/adapters/adtelligent/adtelligent.go index 492de0a364b..f56a39736a3 100644 --- a/adapters/adtelligent/adtelligent.go +++ b/adapters/adtelligent/adtelligent.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type AdtelligentAdapter struct { @@ -93,7 +94,7 @@ func (a *AdtelligentAdapter) MakeBids(bidReq *openrtb2.BidRequest, unused *adapt } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(httpRes.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(httpRes.Body, &bidResp); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: fmt.Sprintf("error while decoding response, err: %s", err), }} @@ -155,14 +156,14 @@ func validateImpression(imp *openrtb2.Imp) (int, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return 0, &errortypes.BadInput{ Message: fmt.Sprintf("ignoring imp id=%s, error while decoding extImpBidder, err: %s", imp.ID, err), } } impExt := openrtb_ext.ExtImpAdtelligent{} - err := json.Unmarshal(bidderExt.Bidder, &impExt) + err := jsonutil.Unmarshal(bidderExt.Bidder, &impExt) if err != nil { return 0, &errortypes.BadInput{ Message: fmt.Sprintf("ignoring imp id=%s, error while decoding impExt, err: %s", imp.ID, err), @@ -187,7 +188,13 @@ func validateImpression(imp *openrtb2.Imp) (int, error) { imp.Ext = impExtBuffer - return impExt.SourceId, nil + aid, err := impExt.SourceId.Int64() + if err != nil { + return 0, &errortypes.BadInput{ + Message: fmt.Sprintf("ignoring imp id=%s, aid parsing err: %s", imp.ID, err), + } + } + return int(aid), nil } // Builder builds a new instance of the Adtelligent adapter for the given bidder with the given config. diff --git a/adapters/adtelligent/adtelligent_test.go b/adapters/adtelligent/adtelligent_test.go index 905ce013840..64a4573ac19 100644 --- a/adapters/adtelligent/adtelligent_test.go +++ b/adapters/adtelligent/adtelligent_test.go @@ -3,9 +3,9 @@ package adtelligent import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/adtelligent/adtelligenttest/supplemental/wrong-impression-ext.json b/adapters/adtelligent/adtelligenttest/supplemental/wrong-impression-ext.json index 63c587ed742..3d7508d2103 100644 --- a/adapters/adtelligent/adtelligenttest/supplemental/wrong-impression-ext.json +++ b/adapters/adtelligent/adtelligenttest/supplemental/wrong-impression-ext.json @@ -19,7 +19,7 @@ "expectedMakeRequestsErrors": [ { - "value": "ignoring imp id=unsupported-native-imp, error while decoding impExt, err: json: cannot unmarshal string into Go struct field ExtImpAdtelligent.aid of type int", + "value": "ignoring imp id=unsupported-native-imp, error while marshaling impExt, err: json: invalid number literal \"some string instead of int\"", "comparison": "literal" } ] diff --git a/adapters/adtelligent/params_test.go b/adapters/adtelligent/params_test.go index f86a7641af9..bd3a2b85833 100644 --- a/adapters/adtelligent/params_test.go +++ b/adapters/adtelligent/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/adtelligent.json @@ -33,16 +33,21 @@ func TestInvalidParams(t *testing.T) { for _, invalidParam := range invalidParams { if err := validator.Validate(openrtb_ext.BidderAdtelligent, json.RawMessage(invalidParam)); err == nil { - t.Errorf("Schema allowed unexpected params: %s", invalidParam) + ext := openrtb_ext.ExtImpAdtelligent{} + err = json.Unmarshal([]byte(invalidParam), &ext) + if err == nil { + t.Errorf("Schema allowed unexpected params: %s", invalidParam) + } } } } var validParams = []string{ `{"aid":123}`, + `{"aid":"123"}`, `{"aid":123,"placementId":1234}`, `{"aid":123,"siteId":4321}`, - `{"aid":123,"siteId":0,"bidFloor":0}`, + `{"aid":"123","siteId":0,"bidFloor":0}`, } var invalidParams = []string{ @@ -53,8 +58,7 @@ var invalidParams = []string{ `4.2`, `[]`, `{}`, - `{"aid":"123"}`, - `{"aid":"0"}`, + `{"aid":"qwerty"}`, `{"aid":"123","placementId":"123"}`, `{"aid":123, "placementId":"123", "siteId":"321"}`, } diff --git a/adapters/adtonos/adtonos.go b/adapters/adtonos/adtonos.go new file mode 100644 index 00000000000..e3c20cd9322 --- /dev/null +++ b/adapters/adtonos/adtonos.go @@ -0,0 +1,143 @@ +package adtonos + +import ( + "encoding/json" + "fmt" + "net/http" + "text/template" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" +) + +type adapter struct { + endpointTemplate *template.Template +} + +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + template, err := template.New("endpointTemplate").Parse(config.Endpoint) + if err != nil { + return nil, fmt.Errorf("unable to parse endpoint url template: %v", err) + } + + bidder := &adapter{ + endpointTemplate: template, + } + return bidder, nil +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + var bidderExt adapters.ExtImpBidder + if err := jsonutil.Unmarshal(request.Imp[0].Ext, &bidderExt); err != nil { + return nil, []error{&errortypes.BadInput{ + Message: fmt.Sprintf("Invalid imp.ext for impression index %d. Error Infomation: %s", 0, err.Error()), + }} + } + var impExt openrtb_ext.ImpExtAdTonos + if err := jsonutil.Unmarshal(bidderExt.Bidder, &impExt); err != nil { + return nil, []error{&errortypes.BadInput{ + Message: fmt.Sprintf("Invalid imp.ext.bidder for impression index %d. Error Infomation: %s", 0, err.Error()), + }} + } + + endpoint, err := a.buildEndpointURL(&impExt) + if err != nil { + return nil, []error{err} + } + + requestJson, err := json.Marshal(request) + if err != nil { + return nil, []error{err} + } + + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + headers.Add("Accept", "application/json") + + requestData := &adapters.RequestData{ + Method: "POST", + Uri: endpoint, + Body: requestJson, + Headers: headers, + ImpIDs: openrtb_ext.GetImpIDs(request.Imp), + } + + return []*adapters.RequestData{requestData}, nil +} + +func (a *adapter) buildEndpointURL(params *openrtb_ext.ImpExtAdTonos) (string, error) { + endpointParams := macros.EndpointTemplateParams{PublisherID: params.SupplierID} + return macros.ResolveMacros(a.endpointTemplate, endpointParams) +} + +func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if adapters.IsResponseStatusCodeNoContent(responseData) { + return nil, nil + } + + if err := adapters.CheckResponseStatusCodeForErrors(responseData); err != nil { + return nil, []error{err} + } + + var response openrtb2.BidResponse + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { + return nil, []error{err} + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) + bidResponse.Currency = response.Cur + var errors []error + for _, seatBid := range response.SeatBid { + for i := range seatBid.Bid { + bidType, err := getMediaTypeForBid(seatBid.Bid[i], request.Imp) + if err != nil { + errors = append(errors, err) + continue + } + b := &adapters.TypedBid{ + Bid: &seatBid.Bid[i], + BidType: bidType, + } + bidResponse.Bids = append(bidResponse.Bids, b) + } + } + return bidResponse, errors +} + +func getMediaTypeForBid(bid openrtb2.Bid, requestImps []openrtb2.Imp) (openrtb_ext.BidType, error) { + if bid.MType != 0 { + // If present, use explicit markup type annotation from the bidder: + switch bid.MType { + case openrtb2.MarkupAudio: + return openrtb_ext.BidTypeAudio, nil + case openrtb2.MarkupVideo: + return openrtb_ext.BidTypeVideo, nil + case openrtb2.MarkupBanner: + return openrtb_ext.BidTypeBanner, nil + case openrtb2.MarkupNative: + return openrtb_ext.BidTypeNative, nil + } + } + // As a fallback, guess markup type based on requested type - AdTonos is an audio company so we prioritize that. + for _, requestImp := range requestImps { + if requestImp.ID == bid.ImpID { + if requestImp.Audio != nil { + return openrtb_ext.BidTypeAudio, nil + } else if requestImp.Video != nil { + return openrtb_ext.BidTypeVideo, nil + } else { + return "", &errortypes.BadInput{ + Message: fmt.Sprintf("Unsupported bidtype for bid: \"%s\"", bid.ImpID), + } + } + } + } + return "", &errortypes.BadInput{ + Message: fmt.Sprintf("Failed to find impression: \"%s\"", bid.ImpID), + } +} diff --git a/adapters/adtonos/adtonos_test.go b/adapters/adtonos/adtonos_test.go new file mode 100644 index 00000000000..683ce3e4458 --- /dev/null +++ b/adapters/adtonos/adtonos_test.go @@ -0,0 +1,30 @@ +package adtonos + +import ( + "testing" + + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/stretchr/testify/assert" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderAdTonos, config.Adapter{ + Endpoint: "http://exchange.example.com/bid/{{.PublisherID}}"}, + config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "adtonostest", bidder) +} + +func TestEndpointTemplateMalformed(t *testing.T) { + _, buildErr := Builder(openrtb_ext.BidderAdTonos, config.Adapter{ + Endpoint: "{{Malformed}}"}, + config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + assert.Error(t, buildErr) +} diff --git a/adapters/adtonos/adtonostest/exemplary/simple-audio-with-mtype.json b/adapters/adtonos/adtonostest/exemplary/simple-audio-with-mtype.json new file mode 100644 index 00000000000..c9103e37ee4 --- /dev/null +++ b/adapters/adtonos/adtonostest/exemplary/simple-audio-with-mtype.json @@ -0,0 +1,115 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "tmax": 1000, + "imp": [ + { + "id": "some-impression-id", + "bidfloor": 4.2, + "ext": { + "bidder": { + "supplierId": "777XYZ123" + } + }, + "audio": { + "mimes": [ + "audio/mpeg" + ] + } + } + ], + "test": 1, + "site": { + "publisher": { + "id": "1" + }, + "page": "http://www.example.com", + "domain": "www.example.com" + }, + "device": {} + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://exchange.example.com/bid/777XYZ123", + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ] + }, + "body": { + "id": "some-request-id", + "tmax": 1000, + "imp": [ + { + "id": "some-impression-id", + "bidfloor": 4.2, + "ext": { + "bidder": { + "supplierId": "777XYZ123" + } + }, + "audio": { + "mimes": [ + "audio/mpeg" + ] + } + } + ], + "site": { + "publisher": { + "id": "1" + }, + "page": "http://www.example.com", + "domain": "www.example.com" + }, + "device": {}, + "test": 1 + }, + "impIDs":["some-impression-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "some-request-id", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "1", + "impid": "some-impression-id", + "crid": "some-creative-id", + "adm": "TAG", + "price": 6.5, + "mtype": 3 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "1", + "impid": "some-impression-id", + "crid": "some-creative-id", + "adm": "TAG", + "price": 6.5, + "mtype": 3 + }, + "type": "audio" + } + ] + } + ] +} diff --git a/adapters/adtonos/adtonostest/exemplary/simple-audio.json b/adapters/adtonos/adtonostest/exemplary/simple-audio.json new file mode 100644 index 00000000000..61cac002660 --- /dev/null +++ b/adapters/adtonos/adtonostest/exemplary/simple-audio.json @@ -0,0 +1,113 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "tmax": 1000, + "imp": [ + { + "id": "some-impression-id", + "bidfloor": 4.2, + "ext": { + "bidder": { + "supplierId": "777XYZ123" + } + }, + "audio": { + "mimes": [ + "audio/mpeg" + ] + } + } + ], + "test": 1, + "site": { + "publisher": { + "id": "1" + }, + "page": "http://www.example.com", + "domain": "www.example.com" + }, + "device": {} + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://exchange.example.com/bid/777XYZ123", + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ] + }, + "body": { + "id": "some-request-id", + "tmax": 1000, + "imp": [ + { + "id": "some-impression-id", + "bidfloor": 4.2, + "ext": { + "bidder": { + "supplierId": "777XYZ123" + } + }, + "audio": { + "mimes": [ + "audio/mpeg" + ] + } + } + ], + "site": { + "publisher": { + "id": "1" + }, + "page": "http://www.example.com", + "domain": "www.example.com" + }, + "device": {}, + "test": 1 + }, + "impIDs":["some-impression-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "some-request-id", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "1", + "impid": "some-impression-id", + "crid": "some-creative-id", + "adm": "TAG", + "price": 6.5 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "1", + "impid": "some-impression-id", + "crid": "some-creative-id", + "adm": "TAG", + "price": 6.5 + }, + "type": "audio" + } + ] + } + ] +} diff --git a/adapters/adtonos/adtonostest/exemplary/simple-video.json b/adapters/adtonos/adtonostest/exemplary/simple-video.json new file mode 100644 index 00000000000..f00089b4008 --- /dev/null +++ b/adapters/adtonos/adtonostest/exemplary/simple-video.json @@ -0,0 +1,113 @@ +{ + "mockBidRequest": { + "id": "video-request-id", + "tmax": 1000, + "imp": [ + { + "id": "some-impression-id", + "bidfloor": 4.2, + "ext": { + "bidder": { + "supplierId": "777XYZ123" + } + }, + "video": { + "mimes": [ + "video/mp4" + ] + } + } + ], + "test": 1, + "site": { + "publisher": { + "id": "1" + }, + "page": "http://www.example.com", + "domain": "www.example.com" + }, + "device": {} + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://exchange.example.com/bid/777XYZ123", + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ] + }, + "body": { + "id": "video-request-id", + "tmax": 1000, + "imp": [ + { + "id": "some-impression-id", + "bidfloor": 4.2, + "ext": { + "bidder": { + "supplierId": "777XYZ123" + } + }, + "video": { + "mimes": [ + "video/mp4" + ] + } + } + ], + "site": { + "publisher": { + "id": "1" + }, + "page": "http://www.example.com", + "domain": "www.example.com" + }, + "device": {}, + "test": 1 + }, + "impIDs":["some-impression-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "video-request-id", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "1", + "impid": "some-impression-id", + "crid": "some-creative-id", + "adm": "TAG", + "price": 6.5 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "1", + "impid": "some-impression-id", + "crid": "some-creative-id", + "adm": "TAG", + "price": 6.5 + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/adtonos/adtonostest/supplemental/wrong-impression-mapping.json b/adapters/adtonos/adtonostest/supplemental/wrong-impression-mapping.json new file mode 100644 index 00000000000..6fa20e3d3c3 --- /dev/null +++ b/adapters/adtonos/adtonostest/supplemental/wrong-impression-mapping.json @@ -0,0 +1,103 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "tmax": 1000, + "imp": [ + { + "id": "correct-impression-id", + "bidfloor": 4.2, + "ext": { + "bidder": { + "supplierId": "777XYZ123" + } + }, + "audio": { + "mimes": [ + "audio/mpeg" + ] + } + } + ], + "test": 1, + "site": { + "publisher": { + "id": "1" + }, + "page": "http://www.example.com", + "domain": "www.example.com" + }, + "device": {} + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://exchange.example.com/bid/777XYZ123", + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ] + }, + "body": { + "id": "some-request-id", + "tmax": 1000, + "imp": [ + { + "id": "correct-impression-id", + "bidfloor": 4.2, + "ext": { + "bidder": { + "supplierId": "777XYZ123" + } + }, + "audio": { + "mimes": [ + "audio/mpeg" + ] + } + } + ], + "site": { + "publisher": { + "id": "1" + }, + "page": "http://www.example.com", + "domain": "www.example.com" + }, + "device": {}, + "test": 1 + }, + "impIDs":["correct-impression-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "some-request-id", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "1", + "impid": "unexpected-impression-id", + "crid": "some-creative-id", + "adm": "TAG", + "price": 6.5 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [{"currency":"USD","bids":[]}], + "expectedMakeBidsErrors": [ + { + "value": "Failed to find impression: \"unexpected-impression-id\"", + "comparison": "literal" + } + ] +} diff --git a/adapters/adtonos/params_test.go b/adapters/adtonos/params_test.go new file mode 100644 index 00000000000..703446c9def --- /dev/null +++ b/adapters/adtonos/params_test.go @@ -0,0 +1,43 @@ +package adtonos + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v3/openrtb_ext" +) + +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json schema. %v", err) + } + + for _, p := range validParams { + if err := validator.Validate(openrtb_ext.BidderAdTonos, json.RawMessage(p)); err != nil { + t.Errorf("Schema rejected valid params: %s", p) + } + } +} + +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json schema. %v", err) + } + + for _, p := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderAdTonos, json.RawMessage(p)); err == nil { + t.Errorf("Schema allowed invalid params: %s", p) + } + } +} + +var validParams = []string{ + `{"supplierId": ""}`, + `{"supplierId": "7YZxxxdJMSXWv7SwY"}`, +} + +var invalidParams = []string{ + `{"supplierId": 42}`, +} diff --git a/adapters/adtrgtme/adtrgtme.go b/adapters/adtrgtme/adtrgtme.go index f2fc09cb322..a592cfc7c43 100644 --- a/adapters/adtrgtme/adtrgtme.go +++ b/adapters/adtrgtme/adtrgtme.go @@ -7,10 +7,11 @@ import ( "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -67,13 +68,13 @@ func (v *adapter) MakeRequests( func getSiteIDFromImp(imp *openrtb2.Imp) (uint64, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return 0, &errortypes.BadInput{ Message: "ext.bidder not provided", } } var ext openrtb_ext.ExtImpAdtrgtme - if err := json.Unmarshal(bidderExt.Bidder, &ext); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &ext); err != nil { return 0, &errortypes.BadInput{ Message: "ext.bidder not provided", } @@ -147,7 +148,7 @@ func (v *adapter) MakeBids( } var response openrtb2.BidResponse - if err := json.Unmarshal(bidderRawResponse.Body, &response); err != nil { + if err := jsonutil.Unmarshal(bidderRawResponse.Body, &response); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: "Bad Server Response", }} diff --git a/adapters/adtrgtme/adtrgtme_test.go b/adapters/adtrgtme/adtrgtme_test.go index 07bfea3c652..d57b5943af1 100644 --- a/adapters/adtrgtme/adtrgtme_test.go +++ b/adapters/adtrgtme/adtrgtme_test.go @@ -3,9 +3,9 @@ package adtrgtme import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/adtrgtme/params_test.go b/adapters/adtrgtme/params_test.go index 4745c323887..19acaedc880 100644 --- a/adapters/adtrgtme/params_test.go +++ b/adapters/adtrgtme/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/advangelists/advangelists.go b/adapters/advangelists/advangelists.go index bddb9706c5b..1d4cd4fb648 100644 --- a/adapters/advangelists/advangelists.go +++ b/adapters/advangelists/advangelists.go @@ -7,11 +7,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type AdvangelistsAdapter struct { @@ -129,13 +130,13 @@ func compatBannerImpression(imp *openrtb2.Imp) error { func getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpAdvangelists, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: err.Error(), } } var advangelistsExt openrtb_ext.ExtImpAdvangelists - if err := json.Unmarshal(bidderExt.Bidder, &advangelistsExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &advangelistsExt); err != nil { return nil, &errortypes.BadInput{ Message: err.Error(), } @@ -208,7 +209,7 @@ func (adapter *AdvangelistsAdapter) MakeBids(internalRequest *openrtb2.BidReques return nil, []error{&errortypes.BadServerResponse{Message: msg}} } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { msg = fmt.Sprintf("Bad server response: %d", err) return nil, []error{&errortypes.BadServerResponse{Message: msg}} } diff --git a/adapters/advangelists/advangelists_test.go b/adapters/advangelists/advangelists_test.go index 5165ef1f3a7..64ae4c89fa1 100644 --- a/adapters/advangelists/advangelists_test.go +++ b/adapters/advangelists/advangelists_test.go @@ -3,9 +3,9 @@ package advangelists import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/advangelists/params_test.go b/adapters/advangelists/params_test.go index 966967ba312..8286f7f84ac 100644 --- a/adapters/advangelists/params_test.go +++ b/adapters/advangelists/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/adview/adview.go b/adapters/adview/adview.go index 69e1f27ac9d..55bf2284504 100644 --- a/adapters/adview/adview.go +++ b/adapters/adview/adview.go @@ -8,11 +8,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -45,7 +46,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte requestCopy := *request for _, imp := range request.Imp { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { errors = append(errors, &errortypes.BadInput{ Message: fmt.Sprintf("invalid imp.ext, %s", err.Error()), }) @@ -53,7 +54,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte } //use adview var advImpExt openrtb_ext.ExtImpAdView - if err := json.Unmarshal(bidderExt.Bidder, &advImpExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &advImpExt); err != nil { errors = append(errors, &errortypes.BadInput{ Message: fmt.Sprintf("invalid bidderExt.Bidder, %s", err.Error()), }) @@ -132,7 +133,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } diff --git a/adapters/adview/adview_test.go b/adapters/adview/adview_test.go index 2045586e97d..08e824a097b 100644 --- a/adapters/adview/adview_test.go +++ b/adapters/adview/adview_test.go @@ -3,9 +3,9 @@ package adview import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/adview/adviewtest/supplemental/unparsable-response.json b/adapters/adview/adviewtest/supplemental/unparsable-response.json index af126dab8e7..76f95d1cd6d 100644 --- a/adapters/adview/adviewtest/supplemental/unparsable-response.json +++ b/adapters/adview/adviewtest/supplemental/unparsable-response.json @@ -46,7 +46,7 @@ "expectedBidResponses": [], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/adview/params_test.go b/adapters/adview/params_test.go index d5e498645e0..9dd1c57c2ad 100644 --- a/adapters/adview/params_test.go +++ b/adapters/adview/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/adxcg/adxcg.go b/adapters/adxcg/adxcg.go index 3bccf806902..3b5e290ca30 100644 --- a/adapters/adxcg/adxcg.go +++ b/adapters/adxcg/adxcg.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) // Builder builds a new instance of the Adxcg adapter for the given bidder with the given config. @@ -81,7 +82,7 @@ func (adapter *adapter) MakeBids( } var openRTBBidderResponse openrtb2.BidResponse - if err := json.Unmarshal(bidderRawResponse.Body, &openRTBBidderResponse); err != nil { + if err := jsonutil.Unmarshal(bidderRawResponse.Body, &openRTBBidderResponse); err != nil { return nil, []error{err} } diff --git a/adapters/adxcg/adxcg_test.go b/adapters/adxcg/adxcg_test.go index f117f7b2ba1..0d947213923 100644 --- a/adapters/adxcg/adxcg_test.go +++ b/adapters/adxcg/adxcg_test.go @@ -3,9 +3,9 @@ package adxcg import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) const testsDir = "adxcgtest" diff --git a/adapters/adxcg/adxcgtest/supplemental/bad_response.json b/adapters/adxcg/adxcgtest/supplemental/bad_response.json index b8ce74b28a6..e887a114408 100644 --- a/adapters/adxcg/adxcgtest/supplemental/bad_response.json +++ b/adapters/adxcg/adxcgtest/supplemental/bad_response.json @@ -55,7 +55,7 @@ "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/adyoulike/adyoulike.go b/adapters/adyoulike/adyoulike.go index babc7627949..dbc76f3f75b 100644 --- a/adapters/adyoulike/adyoulike.go +++ b/adapters/adyoulike/adyoulike.go @@ -8,10 +8,11 @@ import ( "github.com/buger/jsonparser" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { @@ -120,7 +121,7 @@ func (a *adapter) MakeBids( } var openRTBBidderResponse openrtb2.BidResponse - if err := json.Unmarshal(bidderRawResponse.Body, &openRTBBidderResponse); err != nil { + if err := jsonutil.Unmarshal(bidderRawResponse.Body, &openRTBBidderResponse); err != nil { return nil, []error{err} } diff --git a/adapters/adyoulike/adyoulike_test.go b/adapters/adyoulike/adyoulike_test.go index 2cf7a2b49ec..5a6c91b1c87 100644 --- a/adapters/adyoulike/adyoulike_test.go +++ b/adapters/adyoulike/adyoulike_test.go @@ -3,9 +3,9 @@ package adyoulike import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) const testsBidderEndpoint = "https://localhost/bid/4" diff --git a/adapters/adyoulike/adyouliketest/supplemental/invalid-bid-response.json b/adapters/adyoulike/adyouliketest/supplemental/invalid-bid-response.json index 2d68274da1a..1b0959a471d 100644 --- a/adapters/adyoulike/adyouliketest/supplemental/invalid-bid-response.json +++ b/adapters/adyoulike/adyouliketest/supplemental/invalid-bid-response.json @@ -60,7 +60,7 @@ "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/adyoulike/params_test.go b/adapters/adyoulike/params_test.go index 6eb9e09a3cb..7c6630fbef3 100644 --- a/adapters/adyoulike/params_test.go +++ b/adapters/adyoulike/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/adyoulike.json diff --git a/adapters/aidem/aidem.go b/adapters/aidem/aidem.go index fe1259450ca..d644d83cdf2 100644 --- a/adapters/aidem/aidem.go +++ b/adapters/aidem/aidem.go @@ -7,11 +7,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -61,7 +62,7 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: fmt.Sprintf("JSON parsing error: %v", err), }} @@ -122,13 +123,13 @@ func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) { func getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpAidem, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: err.Error(), } } var AIDEMExt openrtb_ext.ExtImpAidem - if err := json.Unmarshal(bidderExt.Bidder, &AIDEMExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &AIDEMExt); err != nil { return nil, &errortypes.BadInput{ Message: err.Error(), } diff --git a/adapters/aidem/aidem_test.go b/adapters/aidem/aidem_test.go index 558b1c040de..395bd2ca78b 100644 --- a/adapters/aidem/aidem_test.go +++ b/adapters/aidem/aidem_test.go @@ -5,9 +5,9 @@ import ( "github.com/stretchr/testify/assert" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/aidem/params_test.go b/adapters/aidem/params_test.go index 4d2c5c14cbc..bea1d26e3d1 100644 --- a/adapters/aidem/params_test.go +++ b/adapters/aidem/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/aidem.json TODO: MUST BE CREATED diff --git a/adapters/aja/aja.go b/adapters/aja/aja.go index e65ab357fb3..82007b02d0b 100644 --- a/adapters/aja/aja.go +++ b/adapters/aja/aja.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type AJAAdapter struct { @@ -61,13 +62,13 @@ func parseExtAJA(imp openrtb2.Imp) (openrtb_ext.ExtImpAJA, error) { extAJA openrtb_ext.ExtImpAJA ) - if err := json.Unmarshal(imp.Ext, &extImp); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &extImp); err != nil { return extAJA, &errortypes.BadInput{ Message: fmt.Sprintf("Failed to unmarshal ext impID: %s err: %s", imp.ID, err), } } - if err := json.Unmarshal(extImp.Bidder, &extAJA); err != nil { + if err := jsonutil.Unmarshal(extImp.Bidder, &extAJA); err != nil { return extAJA, &errortypes.BadInput{ Message: fmt.Sprintf("Failed to unmarshal ext.bidder impID: %s err: %s", imp.ID, err), } @@ -92,7 +93,7 @@ func (a *AJAAdapter) MakeBids(bidReq *openrtb2.BidRequest, adapterReq *adapters. } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(adapterResp.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(adapterResp.Body, &bidResp); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: fmt.Sprintf("Failed to unmarshal bid response: %s", err.Error()), }} diff --git a/adapters/aja/aja_test.go b/adapters/aja/aja_test.go index de4f1d13dab..ab4165d09ab 100644 --- a/adapters/aja/aja_test.go +++ b/adapters/aja/aja_test.go @@ -3,9 +3,9 @@ package aja import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) const testsBidderEndpoint = "https://localhost/bid/4" diff --git a/adapters/aja/ajatest/supplemental/invalid-ext-bidder.json b/adapters/aja/ajatest/supplemental/invalid-ext-bidder.json index b12b431b0ed..54a774b3240 100644 --- a/adapters/aja/ajatest/supplemental/invalid-ext-bidder.json +++ b/adapters/aja/ajatest/supplemental/invalid-ext-bidder.json @@ -28,7 +28,7 @@ "expectedMakeRequestsErrors": [ { - "value": "Failed to unmarshal ext.bidder impID: test-imp-id err: json: cannot unmarshal number into Go struct field ExtImpAJA.asi of type string", + "value": "Failed to unmarshal ext.bidder impID: test-imp-id err: cannot unmarshal openrtb_ext.ExtImpAJA.AdSpotID: expects \" or n, but found 1", "comparison": "literal" } diff --git a/adapters/aja/ajatest/supplemental/invalid-ext.json b/adapters/aja/ajatest/supplemental/invalid-ext.json index 478222d0ee9..4562da9eea1 100644 --- a/adapters/aja/ajatest/supplemental/invalid-ext.json +++ b/adapters/aja/ajatest/supplemental/invalid-ext.json @@ -24,7 +24,7 @@ "expectedMakeRequestsErrors": [ { - "value": "Failed to unmarshal ext impID: test-imp-id err: json: cannot unmarshal number into Go value of type adapters.ExtImpBidder", + "value": "Failed to unmarshal ext impID: test-imp-id err: expect { or n, but found 1", "comparison": "literal" } diff --git a/adapters/algorix/algorix.go b/adapters/algorix/algorix.go index 28a1a560829..f6848e58e3c 100644 --- a/adapters/algorix/algorix.go +++ b/adapters/algorix/algorix.go @@ -8,11 +8,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -88,11 +89,11 @@ func (a *adapter) makeRequest(request *openrtb2.BidRequest) (*adapters.RequestDa func getImpAlgoriXExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpAlgorix, error) { var extImpAlgoriX openrtb_ext.ExtImpAlgorix var extBidder adapters.ExtImpBidder - err := json.Unmarshal(imp.Ext, &extBidder) + err := jsonutil.Unmarshal(imp.Ext, &extBidder) if err != nil { return nil, err } - err = json.Unmarshal(extBidder.Bidder, &extImpAlgoriX) + err = jsonutil.Unmarshal(extBidder.Bidder, &extImpAlgoriX) if err != nil { return nil, err } @@ -134,7 +135,7 @@ func preProcess(request *openrtb2.BidRequest) { } if request.Imp[i].Video != nil { var impExt adapters.ExtImpBidder - err := json.Unmarshal(request.Imp[i].Ext, &impExt) + err := jsonutil.Unmarshal(request.Imp[i].Ext, &impExt) if err != nil { continue } @@ -169,7 +170,7 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } @@ -195,7 +196,7 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest func getBidType(bid openrtb2.Bid, imps []openrtb2.Imp) (openrtb_ext.BidType, error) { var bidExt algorixResponseBidExt - err := json.Unmarshal(bid.Ext, &bidExt) + err := jsonutil.Unmarshal(bid.Ext, &bidExt) if err == nil { switch bidExt.MediaType { case "banner": diff --git a/adapters/algorix/algorix_test.go b/adapters/algorix/algorix_test.go index a401713d290..6b6d21e4d15 100644 --- a/adapters/algorix/algorix_test.go +++ b/adapters/algorix/algorix_test.go @@ -5,9 +5,9 @@ import ( "github.com/stretchr/testify/assert" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/algorix/algorixtest/supplemental/bad_response.json b/adapters/algorix/algorixtest/supplemental/bad_response.json index 9c5a44b2f14..6a99f748df2 100644 --- a/adapters/algorix/algorixtest/supplemental/bad_response.json +++ b/adapters/algorix/algorixtest/supplemental/bad_response.json @@ -52,7 +52,7 @@ "expectedMakeBidsErrors": [ { "comparison": "literal", - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse" + "value": "expect { or n, but found \"" } ] } diff --git a/adapters/algorix/params_test.go b/adapters/algorix/params_test.go index 7017a43c730..6b5570c9ad9 100644 --- a/adapters/algorix/params_test.go +++ b/adapters/algorix/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/alkimi/alkimi.go b/adapters/alkimi/alkimi.go index 88703073402..4f924bb15e6 100644 --- a/adapters/alkimi/alkimi.go +++ b/adapters/alkimi/alkimi.go @@ -8,13 +8,14 @@ import ( "strconv" "strings" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/floors" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/floors" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) const price_macro = "${AUCTION_PRICE}" @@ -69,12 +70,12 @@ func updateImps(bidRequest openrtb2.BidRequest) ([]openrtb2.Imp, []error) { var bidderExt adapters.ExtImpBidder var extImpAlkimi openrtb_ext.ExtImpAlkimi - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { errs = append(errs, err) continue } - if err := json.Unmarshal(bidderExt.Bidder, &extImpAlkimi); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &extImpAlkimi); err != nil { errs = append(errs, err) continue } @@ -134,7 +135,7 @@ func (adapter *adapter) MakeBids(request *openrtb2.BidRequest, externalRequest * } var bidResp openrtb2.BidResponse - err := json.Unmarshal(response.Body, &bidResp) + err := jsonutil.Unmarshal(response.Body, &bidResp) if err != nil { return nil, []error{err} } diff --git a/adapters/alkimi/alkimi_test.go b/adapters/alkimi/alkimi_test.go index b745f0feb95..65f296a58e6 100644 --- a/adapters/alkimi/alkimi_test.go +++ b/adapters/alkimi/alkimi_test.go @@ -3,10 +3,10 @@ package alkimi import ( "testing" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/alkimi/alkimitest/supplemental/bad_response.json b/adapters/alkimi/alkimitest/supplemental/bad_response.json index 92b8d658968..df66e1eba76 100644 --- a/adapters/alkimi/alkimitest/supplemental/bad_response.json +++ b/adapters/alkimi/alkimitest/supplemental/bad_response.json @@ -95,7 +95,7 @@ }], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/alkimi/params_test.go b/adapters/alkimi/params_test.go index 69142af8f33..0ed0be05c61 100644 --- a/adapters/alkimi/params_test.go +++ b/adapters/alkimi/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/amx/amx.go b/adapters/amx/amx.go index a738efe11f3..38e0f4512e6 100644 --- a/adapters/amx/amx.go +++ b/adapters/amx/amx.go @@ -7,10 +7,11 @@ import ( "net/url" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) const nbrHeaderName = "x-nbr" @@ -63,7 +64,7 @@ func (adapter *AMXAdapter) MakeRequests(request *openrtb2.BidRequest, req *adapt var publisherID string for idx, imp := range reqCopy.Imp { var params amxExt - if err := json.Unmarshal(imp.Ext, ¶ms); err == nil { + if err := jsonutil.Unmarshal(imp.Ext, ¶ms); err == nil { if params.Bidder.TagID != "" { publisherID = params.Bidder.TagID } @@ -112,8 +113,10 @@ func (adapter *AMXAdapter) MakeRequests(request *openrtb2.BidRequest, req *adapt } type amxBidExt struct { - StartDelay *int `json:"startdelay,omitempty"` - CreativeType *int `json:"ct,omitempty"` + StartDelay *int `json:"startdelay,omitempty"` + CreativeType *int `json:"ct,omitempty"` + DemandSource *string `json:"ds,omitempty"` + BidderCode *string `json:"bc,omitempty"` } // MakeBids will parse the bids from the AMX server @@ -139,7 +142,7 @@ func (adapter *AMXAdapter) MakeBids(request *openrtb2.BidRequest, externalReques } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } @@ -154,12 +157,25 @@ func (adapter *AMXAdapter) MakeBids(request *openrtb2.BidRequest, externalReques continue } + demandSource := "" + if bidExt.DemandSource != nil { + demandSource = *bidExt.DemandSource + } + bidType := getMediaTypeForBid(bidExt) b := &adapters.TypedBid{ - Bid: &bid, + Bid: &bid, + BidMeta: &openrtb_ext.ExtBidPrebidMeta{ + AdvertiserDomains: bid.ADomain, + DemandSource: demandSource, + }, BidType: bidType, } + if bidExt.BidderCode != nil { + b.Seat = openrtb_ext.BidderName(*bidExt.BidderCode) + } + bidResponse.Bids = append(bidResponse.Bids, b) } } @@ -173,7 +189,7 @@ func getBidExt(ext json.RawMessage) (amxBidExt, error) { } var bidExt amxBidExt - err := json.Unmarshal(ext, &bidExt) + err := jsonutil.Unmarshal(ext, &bidExt) return bidExt, err } diff --git a/adapters/amx/amx_test.go b/adapters/amx/amx_test.go index d8c73a6141f..152fcf2b40d 100644 --- a/adapters/amx/amx_test.go +++ b/adapters/amx/amx_test.go @@ -6,12 +6,12 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" ) const ( @@ -182,19 +182,24 @@ func TestMakeBids(t *testing.T) { } type testCase struct { - bidType openrtb_ext.BidType - adm string - extRaw string - valid bool + bidType openrtb_ext.BidType + adm string + extRaw string + seatName string + demandSource string + valid bool } tests := []testCase{ - {openrtb_ext.BidTypeNative, `{"assets":[]}`, `{"ct":10}`, true}, - {openrtb_ext.BidTypeBanner, sampleDisplayADM, `{"ct": 1}`, true}, - {openrtb_ext.BidTypeBanner, sampleDisplayADM, `{"ct": "invalid"}`, false}, - {openrtb_ext.BidTypeBanner, sampleDisplayADM, `{}`, true}, - {openrtb_ext.BidTypeVideo, sampleVastADM, `{"startdelay": 1}`, true}, - {openrtb_ext.BidTypeBanner, sampleVastADM, `{"ct": 1}`, true}, // the server shouldn't do this + {openrtb_ext.BidTypeNative, `{"assets":[]}`, `{"ct":10}`, "", "", true}, + {openrtb_ext.BidTypeBanner, sampleDisplayADM, `{"ct": 1}`, "", "", true}, + {openrtb_ext.BidTypeBanner, sampleDisplayADM, `{"ct": "invalid"}`, "", "", false}, + {openrtb_ext.BidTypeBanner, sampleDisplayADM, `{}`, "", "", true}, + {openrtb_ext.BidTypeBanner, sampleDisplayADM, `{"bc": "amx-pmp"}`, "amx-pmp", "", true}, + {openrtb_ext.BidTypeBanner, sampleDisplayADM, `{"ds": "pmp-1"}`, "", "pmp-1", true}, + {openrtb_ext.BidTypeBanner, sampleDisplayADM, `{"bc": "amx-pmp", "ds": "pmp-1"}`, "amx-pmp", "pmp-1", true}, + {openrtb_ext.BidTypeVideo, sampleVastADM, `{"startdelay": 1}`, "", "", true}, + {openrtb_ext.BidTypeBanner, sampleVastADM, `{"ct": 1}`, "", "", true}, // the server shouldn't do this } for _, test := range tests { @@ -233,6 +238,10 @@ func TestMakeBids(t *testing.T) { assert.Len(t, bids.Bids, 1) assert.Equal(t, test.bidType, bids.Bids[0].BidType) + + br := bids.Bids[0] + assert.Equal(t, openrtb_ext.BidderName(test.seatName), br.Seat) + assert.Equal(t, test.demandSource, br.BidMeta.DemandSource) } } diff --git a/adapters/amx/amxtest/exemplary/display-multiple.json b/adapters/amx/amxtest/exemplary/display-multiple.json index 330bc00d77b..76d97b17042 100644 --- a/adapters/amx/amxtest/exemplary/display-multiple.json +++ b/adapters/amx/amxtest/exemplary/display-multiple.json @@ -214,6 +214,7 @@ "cid": "668", "crid": "253510977", "ext": { + "bc": "amx-pmp" }, "h": 250, "id": "8911104898220857797", @@ -258,7 +259,9 @@ ], "cid": "668", "crid": "253510977", - "ext": {}, + "ext": { + "bc": "amx-pmp" + }, "h": 250, "id": "8911104898220857797", "impid": "6a362d3a9db4eba300x250", @@ -266,6 +269,7 @@ "price": 0.50, "w": 300 }, + "seat": "amx-pmp", "type": "banner" }, { diff --git a/adapters/amx/params_test.go b/adapters/amx/params_test.go index 4d9d646e426..e44f8a7bbf4 100644 --- a/adapters/amx/params_test.go +++ b/adapters/amx/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/apacdex/apacdex.go b/adapters/apacdex/apacdex.go index 8eee996c7bd..698c204e25c 100644 --- a/adapters/apacdex/apacdex.go +++ b/adapters/apacdex/apacdex.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -76,14 +77,14 @@ func preprocess(request *openrtb2.BidRequest) error { var imp = &request.Imp[i] var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return &errortypes.BadInput{ Message: err.Error(), } } var extImp openrtb_ext.ExtImpApacdex - if err := json.Unmarshal(bidderExt.Bidder, &extImp); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &extImp); err != nil { return &errortypes.BadInput{ Message: err.Error(), } @@ -116,7 +117,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: err.Error(), }} @@ -150,7 +151,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) { if bid.Ext != nil { var bidExt openrtb_ext.ExtBid - err := json.Unmarshal(bid.Ext, &bidExt) + err := jsonutil.Unmarshal(bid.Ext, &bidExt) if err == nil && bidExt.Prebid != nil { return openrtb_ext.ParseBidType(string(bidExt.Prebid.Type)) } diff --git a/adapters/apacdex/apacdex_test.go b/adapters/apacdex/apacdex_test.go index ba5f1e7a3e6..4e9e2f4b0ed 100644 --- a/adapters/apacdex/apacdex_test.go +++ b/adapters/apacdex/apacdex_test.go @@ -3,9 +3,9 @@ package apacdex import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/apacdex/apacdextest/supplemental/invalid-response-unmarshall-error.json b/adapters/apacdex/apacdextest/supplemental/invalid-response-unmarshall-error.json index 7c162cbfbad..95c471f2e39 100644 --- a/adapters/apacdex/apacdextest/supplemental/invalid-response-unmarshall-error.json +++ b/adapters/apacdex/apacdextest/supplemental/invalid-response-unmarshall-error.json @@ -60,8 +60,8 @@ ], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go struct field Bid(\\.seatbid\\.bid)?\\.w of type int64", - "comparison": "regex" + "value": "cannot unmarshal openrtb2.Bid.W: unexpected character", + "comparison": "startswith" } ] } \ No newline at end of file diff --git a/adapters/apacdex/apacdextest/supplemental/wrong-impression-ext.json b/adapters/apacdex/apacdextest/supplemental/wrong-impression-ext.json index 09efa59563d..fcb76ddcbf1 100644 --- a/adapters/apacdex/apacdextest/supplemental/wrong-impression-ext.json +++ b/adapters/apacdex/apacdextest/supplemental/wrong-impression-ext.json @@ -19,7 +19,7 @@ "expectedMakeRequestsErrors": [ { - "value": "json: cannot unmarshal number into Go struct field ExtImpApacdex.siteId of type string", + "value": "cannot unmarshal openrtb_ext.ExtImpApacdex.SiteID: expects \" or n, but found 1", "comparison": "literal" } ] diff --git a/adapters/apacdex/params_test.go b/adapters/apacdex/params_test.go index a7dcf7bcb04..ba680ea6818 100644 --- a/adapters/apacdex/params_test.go +++ b/adapters/apacdex/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/apacdex.json diff --git a/adapters/appnexus/appnexus.go b/adapters/appnexus/appnexus.go index 5f0187ec4c4..eb7b71272cf 100644 --- a/adapters/appnexus/appnexus.go +++ b/adapters/appnexus/appnexus.go @@ -13,14 +13,15 @@ import ( "github.com/buger/jsonparser" "github.com/prebid/openrtb/v20/adcom1" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/util/ptrutil" - "github.com/prebid/prebid-server/v2/util/randomutil" - - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/metrics" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/util/ptrutil" + "github.com/prebid/prebid-server/v3/util/randomutil" + + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/metrics" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) const ( @@ -34,6 +35,12 @@ type adapter struct { randomGenerator randomutil.RandomGenerator } +// impExtIncoming defines the incoming data contract from the Prebid Server request. +type impExtIncoming struct { + Bidder openrtb_ext.ExtImpAppnexus `json:"bidder"` + GPID string `json:"gpid"` +} + // Builder builds a new instance of the AppNexus adapter for the given bidder with the given config. func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { uri, err := url.Parse(config.Endpoint) @@ -72,18 +79,18 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E validImps := []openrtb2.Imp{} for i := 0; i < len(request.Imp); i++ { - appnexusExt, err := validateAndBuildAppNexusExt(&request.Imp[i]) + impExtIncoming, err := validateAndBuildImpExt(&request.Imp[i]) if err != nil { errs = append(errs, err) continue } - if err := buildRequestImp(&request.Imp[i], &appnexusExt, displayManagerVer); err != nil { + if err := buildRequestImp(&request.Imp[i], impExtIncoming, displayManagerVer); err != nil { errs = append(errs, err) continue } - memberId := appnexusExt.Member + memberId := impExtIncoming.Bidder.Member if memberId != "" { // The Appnexus API requires a Member ID in the URL. This means the request may fail if // different impressions have different member IDs. @@ -96,7 +103,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E } } - shouldGenerateAdPodIdForImp := appnexusExt.AdPodId + shouldGenerateAdPodIdForImp := impExtIncoming.Bidder.AdPodId if shouldGenerateAdPodId == nil { shouldGenerateAdPodId = &shouldGenerateAdPodIdForImp } else if *shouldGenerateAdPodId != shouldGenerateAdPodIdForImp { @@ -165,7 +172,7 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest } var appnexusResponse openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &appnexusResponse); err != nil { + if err := jsonutil.Unmarshal(response.Body, &appnexusResponse); err != nil { return nil, []error{err} } @@ -176,7 +183,7 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest bid := sb.Bid[i] var bidExt bidExt - if err := json.Unmarshal(bid.Ext, &bidExt); err != nil { + if err := jsonutil.Unmarshal(bid.Ext, &bidExt); err != nil { errs = append(errs, err) continue } @@ -215,7 +222,7 @@ func getRequestExt(ext json.RawMessage) (map[string]json.RawMessage, error) { extMap := make(map[string]json.RawMessage) if len(ext) > 0 { - if err := json.Unmarshal(ext, &extMap); err != nil { + if err := jsonutil.Unmarshal(ext, &extMap); err != nil { return nil, err } } @@ -227,7 +234,7 @@ func (a *adapter) getAppnexusExt(extMap map[string]json.RawMessage, isAMP int, i var appnexusExt bidReqExtAppnexus if appnexusExtJson, exists := extMap["appnexus"]; exists && len(appnexusExtJson) > 0 { - if err := json.Unmarshal(appnexusExtJson, &appnexusExt); err != nil { + if err := jsonutil.Unmarshal(appnexusExtJson, &appnexusExt); err != nil { return appnexusExt, err } } @@ -250,24 +257,19 @@ func (a *adapter) getAppnexusExt(extMap map[string]json.RawMessage, isAMP int, i return appnexusExt, nil } -func validateAndBuildAppNexusExt(imp *openrtb2.Imp) (openrtb_ext.ExtImpAppnexus, error) { - var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { - return openrtb_ext.ExtImpAppnexus{}, err - } - - var appnexusExt openrtb_ext.ExtImpAppnexus - if err := json.Unmarshal(bidderExt.Bidder, &appnexusExt); err != nil { - return openrtb_ext.ExtImpAppnexus{}, err +func validateAndBuildImpExt(imp *openrtb2.Imp) (impExtIncoming, error) { + var ext impExtIncoming + if err := jsonutil.Unmarshal(imp.Ext, &ext); err != nil { + return impExtIncoming{}, err } - handleLegacyParams(&appnexusExt) + handleLegacyParams(&ext.Bidder) - if err := validateAppnexusExt(&appnexusExt); err != nil { - return openrtb_ext.ExtImpAppnexus{}, err + if err := validateAppnexusExt(&ext.Bidder); err != nil { + return impExtIncoming{}, err } - return appnexusExt, nil + return ext, nil } func handleLegacyParams(appnexusExt *openrtb_ext.ExtImpAppnexus) { @@ -285,6 +287,15 @@ func handleLegacyParams(appnexusExt *openrtb_ext.ExtImpAppnexus) { } } +func validateAppnexusExt(appnexusExt *openrtb_ext.ExtImpAppnexus) error { + if appnexusExt.PlacementId == 0 && (appnexusExt.InvCode == "" || appnexusExt.Member == "") { + return &errortypes.BadInput{ + Message: "No placement or member+invcode provided", + } + } + return nil +} + func groupByPods(imps []openrtb2.Imp) map[string]([]openrtb2.Imp) { // find number of pods in response podImps := make(map[string][]openrtb2.Imp) @@ -350,29 +361,21 @@ func splitRequests(imps []openrtb2.Imp, request *openrtb2.BidRequest, requestExt return resArr, errs } -func validateAppnexusExt(appnexusExt *openrtb_ext.ExtImpAppnexus) error { - if appnexusExt.PlacementId == 0 && (appnexusExt.InvCode == "" || appnexusExt.Member == "") { - return &errortypes.BadInput{ - Message: "No placement or member+invcode provided", - } - } - return nil -} - -func buildRequestImp(imp *openrtb2.Imp, appnexusExt *openrtb_ext.ExtImpAppnexus, displayManagerVer string) error { - if appnexusExt.InvCode != "" { - imp.TagID = appnexusExt.InvCode +func buildRequestImp(imp *openrtb2.Imp, ext impExtIncoming, displayManagerVer string) error { + if ext.Bidder.InvCode != "" { + imp.TagID = ext.Bidder.InvCode } - if imp.BidFloor <= 0 && appnexusExt.Reserve > 0 { - imp.BidFloor = appnexusExt.Reserve // This will be broken for non-USD currency. + if imp.BidFloor <= 0 && ext.Bidder.Reserve > 0 { + imp.BidFloor = ext.Bidder.Reserve // This will be broken for non-USD currency. } if imp.Banner != nil { bannerCopy := *imp.Banner - if appnexusExt.Position == "above" { + + if ext.Bidder.Position == "above" { bannerCopy.Pos = adcom1.PositionAboveFold.Ptr() - } else if appnexusExt.Position == "below" { + } else if ext.Bidder.Position == "below" { bannerCopy.Pos = adcom1.PositionBelowFold.Ptr() } @@ -389,18 +392,21 @@ func buildRequestImp(imp *openrtb2.Imp, appnexusExt *openrtb_ext.ExtImpAppnexus, imp.DisplayManagerVer = displayManagerVer } - impExt := impExt{Appnexus: impExtAppnexus{ - PlacementID: int(appnexusExt.PlacementId), - TrafficSourceCode: appnexusExt.TrafficSourceCode, - Keywords: appnexusExt.Keywords.String(), - UsePmtRule: appnexusExt.UsePaymentRule, - PrivateSizes: appnexusExt.PrivateSizes, - ExtInvCode: appnexusExt.ExtInvCode, - ExternalImpID: appnexusExt.ExternalImpId, - }} + impExt := impExt{ + Appnexus: impExtAppnexus{ + PlacementID: int(ext.Bidder.PlacementId), + TrafficSourceCode: ext.Bidder.TrafficSourceCode, + Keywords: ext.Bidder.Keywords.String(), + UsePmtRule: ext.Bidder.UsePaymentRule, + PrivateSizes: ext.Bidder.PrivateSizes, + ExtInvCode: ext.Bidder.ExtInvCode, + ExternalImpID: ext.Bidder.ExternalImpId, + }, + GPID: ext.GPID, + } var err error - imp.Ext, err = json.Marshal(&impExt) + imp.Ext, err = json.Marshal(impExt) return err } @@ -458,7 +464,7 @@ func moveSupplyChain(request *openrtb2.BidRequest, extMap map[string]json.RawMes } sourceExtMap := make(map[string]json.RawMessage) - if err := json.Unmarshal(request.Source.Ext, &sourceExtMap); err != nil { + if err := jsonutil.Unmarshal(request.Source.Ext, &sourceExtMap); err != nil { return err } diff --git a/adapters/appnexus/appnexus_test.go b/adapters/appnexus/appnexus_test.go index 72937b25927..c570dfcab91 100644 --- a/adapters/appnexus/appnexus_test.go +++ b/adapters/appnexus/appnexus_test.go @@ -4,9 +4,9 @@ import ( "net/url" "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/adapters/appnexus/appnexustest/supplemental/gpid.json b/adapters/appnexus/appnexustest/supplemental/gpid.json new file mode 100644 index 00000000000..a1c59e3d39d --- /dev/null +++ b/adapters/appnexus/appnexustest/supplemental/gpid.json @@ -0,0 +1,154 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "bidfloor": 0.3, + "ext": { + "bidder": { + "placement_id": 1, + "reserve": 0.4 + }, + "gpid": "anyGPID" + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://ib.adnxs.com/openrtb2", + "body": { + "id": "test-request-id", + "ext": { + "appnexus": { + "hb_source": 5 + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ], + "w": 300, + "h": 250 + }, + "bidfloor": 0.3, + "ext": { + "appnexus": { + "placement_id": 1 + }, + "gpid": "anyGPID" + } + } + ] + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "958", + "bid": [ + { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.500000, + "adid": "29681110", + "adm": "some-test-ad", + "adomain": [ + "appnexus.com" + ], + "iurl": "http://nym1-ib.adnxs.com/cr?id=29681110", + "cid": "958", + "crid": "29681110", + "h": 250, + "w": 300, + "ext": { + "appnexus": { + "brand_id": 1, + "brand_category_id": 1, + "auction_id": 8189378542222915032, + "bid_ad_type": 0, + "bidder_id": 2, + "ranking_price": 0.000000, + "deal_priority": 5 + } + } + } + ] + } + ], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "adid": "29681110", + "adomain": [ + "appnexus.com" + ], + "iurl": "http://nym1-ib.adnxs.com/cr?id=29681110", + "cid": "958", + "crid": "29681110", + "w": 300, + "h": 250, + "cat": [ + "IAB20-3" + ], + "ext": { + "appnexus": { + "brand_id": 1, + "brand_category_id": 1, + "auction_id": 8189378542222915032, + "bid_ad_type": 0, + "bidder_id": 2, + "ranking_price": 0.000000, + "deal_priority": 5 + } + } + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/appnexus/models.go b/adapters/appnexus/models.go index c70f89faa6c..6f3da0e2763 100644 --- a/adapters/appnexus/models.go +++ b/adapters/appnexus/models.go @@ -4,6 +4,12 @@ import ( "encoding/json" ) +// impExt defines the outgoing data contract. +type impExt struct { + Appnexus impExtAppnexus `json:"appnexus"` + GPID string `json:"gpid,omitempty"` +} + type impExtAppnexus struct { PlacementID int `json:"placement_id,omitempty"` Keywords string `json:"keywords,omitempty"` @@ -14,10 +20,6 @@ type impExtAppnexus struct { ExternalImpID string `json:"external_imp_id,omitempty"` } -type impExt struct { - Appnexus impExtAppnexus `json:"appnexus"` -} - type bidExtVideo struct { Duration int `json:"duration"` } diff --git a/adapters/appnexus/params_test.go b/adapters/appnexus/params_test.go index 12e43f8659b..e828bf57da7 100644 --- a/adapters/appnexus/params_test.go +++ b/adapters/appnexus/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/appnexus.json diff --git a/adapters/appush/appush.go b/adapters/appush/appush.go index df15f716866..c78e0b872c6 100644 --- a/adapters/appush/appush.go +++ b/adapters/appush/appush.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -44,10 +45,10 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E var bidderExt adapters.ExtImpBidder var appushExt openrtb_ext.ImpExtAppush - if err = json.Unmarshal(reqCopy.Imp[0].Ext, &bidderExt); err != nil { + if err = jsonutil.Unmarshal(reqCopy.Imp[0].Ext, &bidderExt); err != nil { return nil, []error{err} } - if err = json.Unmarshal(bidderExt.Bidder, &appushExt); err != nil { + if err = jsonutil.Unmarshal(bidderExt.Bidder, &appushExt); err != nil { return nil, []error{err} } @@ -111,7 +112,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } diff --git a/adapters/appush/appush_test.go b/adapters/appush/appush_test.go index 92f458f1525..1fe49f87d1c 100644 --- a/adapters/appush/appush_test.go +++ b/adapters/appush/appush_test.go @@ -3,9 +3,9 @@ package appush import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/appush/appushtest/supplemental/bad_response.json b/adapters/appush/appushtest/supplemental/bad_response.json index c732ba92c67..5cc4a338ac3 100644 --- a/adapters/appush/appushtest/supplemental/bad_response.json +++ b/adapters/appush/appushtest/supplemental/bad_response.json @@ -78,7 +78,7 @@ }], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/appush/params_test.go b/adapters/appush/params_test.go index 725882cb2ac..b877eb7bfde 100644 --- a/adapters/appush/params_test.go +++ b/adapters/appush/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/aso/aso.go b/adapters/aso/aso.go index 3664b49af2e..6df776949a5 100644 --- a/adapters/aso/aso.go +++ b/adapters/aso/aso.go @@ -9,11 +9,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -41,7 +42,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte for _, imp := range request.Imp { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { errors = append(errors, &errortypes.BadInput{ Message: fmt.Sprintf("invalid imp.ext, %s", err.Error()), }) @@ -49,7 +50,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte } var impExt openrtb_ext.ExtImpAso - if err := json.Unmarshal(bidderExt.Bidder, &impExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &impExt); err != nil { errors = append(errors, &errortypes.BadInput{ Message: fmt.Sprintf("invalid bidderExt.Bidder, %s", err.Error()), }) @@ -96,7 +97,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } @@ -132,7 +133,7 @@ func (a *adapter) buildEndpointURL(params *openrtb_ext.ExtImpAso) (string, error func getMediaType(bid openrtb2.Bid) (openrtb_ext.BidType, error) { if bid.Ext != nil { var bidExt openrtb_ext.ExtBid - err := json.Unmarshal(bid.Ext, &bidExt) + err := jsonutil.Unmarshal(bid.Ext, &bidExt) if err == nil && bidExt.Prebid != nil { return openrtb_ext.ParseBidType(string(bidExt.Prebid.Type)) } diff --git a/adapters/aso/aso_test.go b/adapters/aso/aso_test.go index 603afaff900..41d8e650483 100644 --- a/adapters/aso/aso_test.go +++ b/adapters/aso/aso_test.go @@ -1,12 +1,13 @@ package aso import ( - "github.com/stretchr/testify/assert" "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/stretchr/testify/assert" + + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/aso/asotest/supplemental/bad-request-no-bidder.json b/adapters/aso/asotest/supplemental/bad-request-no-bidder.json index c19a7c62a44..711637104eb 100644 --- a/adapters/aso/asotest/supplemental/bad-request-no-bidder.json +++ b/adapters/aso/asotest/supplemental/bad-request-no-bidder.json @@ -18,8 +18,8 @@ "expectedBidResponses": [], "expectedMakeRequestsErrors": [ { - "value": "invalid bidderExt.Bidder, unexpected end of JSON input", - "comparison": "literal" + "value": "invalid bidderExt.Bidder, expect { or n, but found", + "comparison": "startswith" } ] } diff --git a/adapters/aso/asotest/supplemental/bad-request-no-ext.json b/adapters/aso/asotest/supplemental/bad-request-no-ext.json index 9911931d521..1528d1220dd 100644 --- a/adapters/aso/asotest/supplemental/bad-request-no-ext.json +++ b/adapters/aso/asotest/supplemental/bad-request-no-ext.json @@ -15,8 +15,8 @@ "expectedBidResponses": [], "expectedMakeRequestsErrors": [ { - "value": "invalid imp.ext, unexpected end of JSON input", - "comparison": "literal" + "value": "invalid imp.ext, expect { or n, but found", + "comparison": "startswith" } ] } diff --git a/adapters/aso/asotest/supplemental/unparsable-response.json b/adapters/aso/asotest/supplemental/unparsable-response.json index c05b1f4c5e8..7fa10a78219 100644 --- a/adapters/aso/asotest/supplemental/unparsable-response.json +++ b/adapters/aso/asotest/supplemental/unparsable-response.json @@ -42,7 +42,7 @@ "expectedBidResponses": [], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/aso/params_test.go b/adapters/aso/params_test.go index caf86acc01b..4d303220d1b 100644 --- a/adapters/aso/params_test.go +++ b/adapters/aso/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/audienceNetwork/audienceNetworktest/supplemental/invalid-adm.json b/adapters/audienceNetwork/audienceNetworktest/supplemental/invalid-adm.json index f79c88e3e3c..2aef3f5381c 100644 --- a/adapters/audienceNetwork/audienceNetworktest/supplemental/invalid-adm.json +++ b/adapters/audienceNetwork/audienceNetworktest/supplemental/invalid-adm.json @@ -99,7 +99,7 @@ }], "expectedBidResponses": [{"currency":"USD","bids":[]}], "expectedMakeBidsErrors": [{ - "value": "invalid character 'm' looking for beginning of value", + "value": "expect { or n, but found m", "comparison": "literal" }] } diff --git a/adapters/audienceNetwork/facebook.go b/adapters/audienceNetwork/facebook.go index 807fe337cf2..2a59e3c1699 100644 --- a/adapters/audienceNetwork/facebook.go +++ b/adapters/audienceNetwork/facebook.go @@ -13,13 +13,13 @@ import ( "github.com/buger/jsonparser" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/jsonutil" - "github.com/prebid/prebid-server/v2/util/maputil" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/maputil" + "github.com/prebid/prebid-server/v3/util/ptrutil" ) var supportedBannerHeights = map[int64]struct{}{ @@ -216,14 +216,14 @@ func modifyImp(out *openrtb2.Imp) error { func extractPlacementAndPublisher(out *openrtb2.Imp) (string, string, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(out.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(out.Ext, &bidderExt); err != nil { return "", "", &errortypes.BadInput{ Message: err.Error(), } } var fbExt openrtb_ext.ExtImpFacebook - if err := json.Unmarshal(bidderExt.Bidder, &fbExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &fbExt); err != nil { return "", "", &errortypes.BadInput{ Message: err.Error(), } @@ -274,7 +274,7 @@ func modifyImpCustom(jsonData []byte, imp *openrtb2.Imp) ([]byte, error) { } var jsonMap map[string]interface{} - if err := json.Unmarshal(jsonData, &jsonMap); err != nil { + if err := jsonutil.Unmarshal(jsonData, &jsonMap); err != nil { return jsonData, err } @@ -338,7 +338,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, adapterRequest *adapter } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } @@ -357,7 +357,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, adapterRequest *adapter } var obj facebookAdMarkup - if err := json.Unmarshal([]byte(bid.AdM), &obj); err != nil { + if err := jsonutil.Unmarshal([]byte(bid.AdM), &obj); err != nil { errs = append(errs, &errortypes.BadServerResponse{ Message: err.Error(), }) diff --git a/adapters/audienceNetwork/facebook_test.go b/adapters/audienceNetwork/facebook_test.go index e2320c1eaea..6fdc121f948 100644 --- a/adapters/audienceNetwork/facebook_test.go +++ b/adapters/audienceNetwork/facebook_test.go @@ -4,10 +4,10 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/automatad/automatad.go b/adapters/automatad/automatad.go index cbb5d2ef2cc..cfe5f5089b6 100644 --- a/adapters/automatad/automatad.go +++ b/adapters/automatad/automatad.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -60,7 +61,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } diff --git a/adapters/automatad/automatad_test.go b/adapters/automatad/automatad_test.go index 790b2b42c67..515025c862a 100644 --- a/adapters/automatad/automatad_test.go +++ b/adapters/automatad/automatad_test.go @@ -3,9 +3,9 @@ package automatad import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/automatad/params_test.go b/adapters/automatad/params_test.go index 468624c1eb3..7f8d6e789eb 100644 --- a/adapters/automatad/params_test.go +++ b/adapters/automatad/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/avocet/avocet.go b/adapters/avocet/avocet.go index 76ce8195219..8bf2b7d89a1 100644 --- a/adapters/avocet/avocet.go +++ b/adapters/avocet/avocet.go @@ -7,10 +7,11 @@ import ( "github.com/prebid/openrtb/v20/adcom1" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) // AvocetAdapter implements a adapters.Bidder compatible with the Avocet advertising platform. @@ -71,7 +72,7 @@ func (a *AvocetAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalR } var br openrtb2.BidResponse - err := json.Unmarshal(response.Body, &br) + err := jsonutil.Unmarshal(response.Body, &br) if err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: err.Error(), @@ -84,7 +85,7 @@ func (a *AvocetAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalR for j := range br.SeatBid[i].Bid { var ext avocetBidExt if len(br.SeatBid[i].Bid[j].Ext) > 0 { - err := json.Unmarshal(br.SeatBid[i].Bid[j].Ext, &ext) + err := jsonutil.Unmarshal(br.SeatBid[i].Bid[j].Ext, &ext) if err != nil { errs = append(errs, err) continue diff --git a/adapters/avocet/avocet_test.go b/adapters/avocet/avocet_test.go index d7356e2cb80..082a7c1ee65 100644 --- a/adapters/avocet/avocet_test.go +++ b/adapters/avocet/avocet_test.go @@ -8,11 +8,11 @@ import ( "github.com/prebid/openrtb/v20/adcom1" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/axis/axis.go b/adapters/axis/axis.go index 4d15e19a4ea..d28eca6a8ad 100644 --- a/adapters/axis/axis.go +++ b/adapters/axis/axis.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -38,7 +39,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E request.Imp = []openrtb2.Imp{currImp} var bidderExt reqBodyExt - if err := json.Unmarshal(currImp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(currImp.Ext, &bidderExt); err != nil { continue } @@ -94,7 +95,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } diff --git a/adapters/axis/axis_test.go b/adapters/axis/axis_test.go index 451141d8458..24048f1856b 100644 --- a/adapters/axis/axis_test.go +++ b/adapters/axis/axis_test.go @@ -3,9 +3,9 @@ package axis import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/axis/axistest/supplemental/bad_response.json b/adapters/axis/axistest/supplemental/bad_response.json index fa1b7579f25..bb2d515ec0e 100644 --- a/adapters/axis/axistest/supplemental/bad_response.json +++ b/adapters/axis/axistest/supplemental/bad_response.json @@ -79,7 +79,7 @@ }], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/axis/params_test.go b/adapters/axis/params_test.go index 1c0391d6954..ad5cec52fd2 100644 --- a/adapters/axis/params_test.go +++ b/adapters/axis/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/axonix/axonix.go b/adapters/axonix/axonix.go index b57e44057d7..81e5937a146 100644 --- a/adapters/axonix/axonix.go +++ b/adapters/axonix/axonix.go @@ -10,11 +10,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -43,7 +44,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte var errors []error var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(request.Imp[0].Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(request.Imp[0].Ext, &bidderExt); err != nil { errors = append(errors, &errortypes.BadInput{ Message: err.Error(), }) @@ -52,7 +53,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte } var axonixExt openrtb_ext.ExtImpAxonix - if err := json.Unmarshal(bidderExt.Bidder, &axonixExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &axonixExt); err != nil { errors = append(errors, &errortypes.BadInput{ Message: err.Error(), }) @@ -99,7 +100,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } diff --git a/adapters/axonix/axonix_test.go b/adapters/axonix/axonix_test.go index 9634a54fe65..1d398c53516 100644 --- a/adapters/axonix/axonix_test.go +++ b/adapters/axonix/axonix_test.go @@ -5,9 +5,9 @@ import ( "github.com/stretchr/testify/assert" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/axonix/axonixtest/supplemental/bad-response-no-body.json b/adapters/axonix/axonixtest/supplemental/bad-response-no-body.json index 8fafaa38fed..18f2915f270 100644 --- a/adapters/axonix/axonixtest/supplemental/bad-response-no-body.json +++ b/adapters/axonix/axonixtest/supplemental/bad-response-no-body.json @@ -51,8 +51,8 @@ ], "expectedMakeBidsErrors": [ { - "value": "unexpected end of JSON input", - "comparison": "literal" + "value": "expect { or n, but found", + "comparison": "startswith" } ] } diff --git a/adapters/axonix/params_test.go b/adapters/axonix/params_test.go index 59b62220746..b839bcb20f5 100644 --- a/adapters/axonix/params_test.go +++ b/adapters/axonix/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/axonix.json diff --git a/adapters/beachfront/beachfront.go b/adapters/beachfront/beachfront.go index 154a14286cd..8e293837f16 100644 --- a/adapters/beachfront/beachfront.go +++ b/adapters/beachfront/beachfront.go @@ -10,11 +10,12 @@ import ( "github.com/prebid/openrtb/v20/adcom1" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/ptrutil" ) const Seat = "beachfront" @@ -273,7 +274,7 @@ func getAppId(ext openrtb_ext.ExtImpBeachfront, media openrtb_ext.BidType) (stri func getSchain(request *openrtb2.BidRequest) (openrtb_ext.ExtRequestPrebidSChain, error) { var schain openrtb_ext.ExtRequestPrebidSChain - return schain, json.Unmarshal(request.Source.Ext, &schain) + return schain, jsonutil.Unmarshal(request.Source.Ext, &schain) } func getBannerRequest(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) (beachfrontBannerRequest, []error) { @@ -540,7 +541,7 @@ func (a *BeachfrontAdapter) MakeBids(internalRequest *openrtb2.BidRequest, exter var errs = make([]error, 0) var xtrnal openrtb2.BidRequest - if err := json.Unmarshal(externalRequest.Body, &xtrnal); err != nil { + if err := jsonutil.Unmarshal(externalRequest.Body, &xtrnal); err != nil { errs = append(errs, err) } else { bids, errs = postprocess(response, xtrnal, externalRequest.Uri, internalRequest.ID) @@ -555,7 +556,7 @@ func (a *BeachfrontAdapter) MakeBids(internalRequest *openrtb2.BidRequest, exter for i := 0; i < len(bids); i++ { - if err := json.Unmarshal(bids[i].Ext, &dur); err == nil && dur.Duration > 0 { + if err := jsonutil.Unmarshal(bids[i].Ext, &dur); err == nil && dur.Duration > 0 { impVideo := openrtb_ext.ExtBidPrebidVideo{ Duration: int(dur.Duration), @@ -642,9 +643,9 @@ func postprocess(response *adapters.ResponseData, xtrnal openrtb2.BidRequest, ur var openrtbResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &openrtbResp); err != nil || len(openrtbResp.SeatBid) == 0 { + if err := jsonutil.Unmarshal(response.Body, &openrtbResp); err != nil || len(openrtbResp.SeatBid) == 0 { - if err := json.Unmarshal(response.Body, &beachfrontResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &beachfrontResp); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: "server response failed to unmarshal as valid rtb. Run with request.debug = 1 for more info", }} @@ -715,13 +716,13 @@ func getBeachfrontExtension(imp openrtb2.Imp) (openrtb_ext.ExtImpBeachfront, err var bidderExt adapters.ExtImpBidder var beachfrontExt openrtb_ext.ExtImpBeachfront - if err = json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err = jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return beachfrontExt, &errortypes.BadInput{ Message: fmt.Sprintf("ignoring imp id=%s, error while decoding extImpBidder, err: %s", imp.ID, err), } } - if err = json.Unmarshal(bidderExt.Bidder, &beachfrontExt); err != nil { + if err = jsonutil.Unmarshal(bidderExt.Bidder, &beachfrontExt); err != nil { return beachfrontExt, &errortypes.BadInput{ Message: fmt.Sprintf("ignoring imp id=%s, error while decoding extImpBeachfront, err: %s", imp.ID, err), } @@ -783,7 +784,7 @@ func getExtraInfo(v string) (ExtraInfo, error) { } var extraInfo ExtraInfo - if err := json.Unmarshal([]byte(v), &extraInfo); err != nil { + if err := jsonutil.Unmarshal([]byte(v), &extraInfo); err != nil { return extraInfo, fmt.Errorf("invalid extra info: %v", err) } diff --git a/adapters/beachfront/beachfront_test.go b/adapters/beachfront/beachfront_test.go index 23c4dcf6a9e..304747503fb 100644 --- a/adapters/beachfront/beachfront_test.go +++ b/adapters/beachfront/beachfront_test.go @@ -3,9 +3,9 @@ package beachfront import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/beachfront/beachfronttest/supplemental/unmarshal-error-banner.json b/adapters/beachfront/beachfronttest/supplemental/unmarshal-error-banner.json index 8d07852b1f1..31f313bde64 100644 --- a/adapters/beachfront/beachfronttest/supplemental/unmarshal-error-banner.json +++ b/adapters/beachfront/beachfronttest/supplemental/unmarshal-error-banner.json @@ -28,7 +28,7 @@ "expectedMakeRequestsErrors": [ { - "value": "ignoring imp id=fail, error while decoding extImpBeachfront, err: json: cannot unmarshal number into Go struct field ExtImpBeachfront.appId of type string", + "value": "ignoring imp id=fail, error while decoding extImpBeachfront, err: cannot unmarshal openrtb_ext.ExtImpBeachfront.AppId: expects \" or n, but found 1", "comparison": "literal" } ] diff --git a/adapters/beachfront/beachfronttest/supplemental/unmarshal-error-video.json b/adapters/beachfront/beachfronttest/supplemental/unmarshal-error-video.json index 73ac2032c16..e075697cfb4 100644 --- a/adapters/beachfront/beachfronttest/supplemental/unmarshal-error-video.json +++ b/adapters/beachfront/beachfronttest/supplemental/unmarshal-error-video.json @@ -34,7 +34,7 @@ "expectedMakeRequestsErrors": [ { - "value": "ignoring imp id=looser, error while decoding extImpBeachfront, err: json: cannot unmarshal string into Go struct field ExtImpBeachfront.bidfloor of type float64", + "value": "ignoring imp id=looser, error while decoding extImpBeachfront, err: cannot unmarshal openrtb_ext.ExtImpBeachfront.BidFloor: invalid number", "comparison": "literal" } ] diff --git a/adapters/beachfront/params_test.go b/adapters/beachfront/params_test.go index 23e9ae7f492..3bfbeba6351 100644 --- a/adapters/beachfront/params_test.go +++ b/adapters/beachfront/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/beintoo/beintoo.go b/adapters/beintoo/beintoo.go index 500e0e4a9df..18290e6df44 100644 --- a/adapters/beintoo/beintoo.go +++ b/adapters/beintoo/beintoo.go @@ -8,10 +8,11 @@ import ( "strconv" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type BeintooAdapter struct { @@ -67,14 +68,14 @@ func (a *BeintooAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *ada func unpackImpExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpBeintoo, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: err.Error(), } } var beintooExt openrtb_ext.ExtImpBeintoo - if err := json.Unmarshal(bidderExt.Bidder, &beintooExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &beintooExt); err != nil { return nil, &errortypes.BadInput{ Message: fmt.Sprintf("ignoring imp id=%s, invalid ImpExt", imp.ID), } @@ -192,7 +193,7 @@ func (a *BeintooAdapter) MakeBids(internalRequest *openrtb2.BidRequest, external var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: fmt.Sprintf("Unable to unpackage bid response. Error: %s", err.Error()), }} diff --git a/adapters/beintoo/beintoo_test.go b/adapters/beintoo/beintoo_test.go index 11ef7ec9e7b..8dfb257b3d4 100644 --- a/adapters/beintoo/beintoo_test.go +++ b/adapters/beintoo/beintoo_test.go @@ -3,9 +3,9 @@ package beintoo import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/beintoo/beintootest/supplemental/invalid-response-unmarshall-error.json b/adapters/beintoo/beintootest/supplemental/invalid-response-unmarshall-error.json index eb8840d3404..01cc697dbd6 100644 --- a/adapters/beintoo/beintootest/supplemental/invalid-response-unmarshall-error.json +++ b/adapters/beintoo/beintootest/supplemental/invalid-response-unmarshall-error.json @@ -57,8 +57,8 @@ "expectedMakeBidsErrors": [ { - "value": "Unable to unpackage bid response\\. Error: json: cannot unmarshal string into Go struct field (Bid\\.seatbid\\.bid\\.w|Bid\\.w) of type int64", - "comparison": "regex" + "value": "Unable to unpackage bid response. Error: cannot unmarshal openrtb2.Bid.W: unexpected character", + "comparison": "startswith" } ] } diff --git a/adapters/beintoo/params_test.go b/adapters/beintoo/params_test.go index 0392e08bb9b..211912a8cbd 100644 --- a/adapters/beintoo/params_test.go +++ b/adapters/beintoo/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/bematterfull/bematterfull.go b/adapters/bematterfull/bematterfull.go index 337bbc1b60c..89b984c5eb1 100644 --- a/adapters/bematterfull/bematterfull.go +++ b/adapters/bematterfull/bematterfull.go @@ -7,11 +7,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type bidType struct { @@ -41,14 +42,14 @@ func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server co func (a *adapter) buildEndpointFromRequest(imp *openrtb2.Imp) (string, error) { var impExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &impExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &impExt); err != nil { return "", &errortypes.BadInput{ Message: fmt.Sprintf("Failed to deserialize bidder impression extension: %v", err), } } var bematterfullExt openrtb_ext.ExtBematterfull - if err := json.Unmarshal(impExt.Bidder, &bematterfullExt); err != nil { + if err := jsonutil.Unmarshal(impExt.Bidder, &bematterfullExt); err != nil { return "", &errortypes.BadInput{ Message: fmt.Sprintf("Failed to deserialize Bematterfull extension: %v", err), } @@ -116,7 +117,7 @@ func (a *adapter) MakeBids(openRTBRequest *openrtb2.BidRequest, requestToBidder } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(bidderRawResponse.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(bidderRawResponse.Body, &bidResp); err != nil { return nil, []error{err} } @@ -136,7 +137,7 @@ func prepareBidResponse(seats []openrtb2.SeatBid) (*adapters.BidderResponse, []e for _, seatBid := range seats { for bidId, bid := range seatBid.Bid { var bidExt bidExt - if err := json.Unmarshal(bid.Ext, &bidExt); err != nil { + if err := jsonutil.Unmarshal(bid.Ext, &bidExt); err != nil { errs = append(errs, &errortypes.BadServerResponse{ Message: fmt.Sprintf("Failed to parse Bid[%d].Ext: %s", bidId, err.Error()), }) diff --git a/adapters/bematterfull/bematterfulltest/supplemental/bad-response.json b/adapters/bematterfull/bematterfulltest/supplemental/bad-response.json index 942c73e7d30..1ef0d08931b 100644 --- a/adapters/bematterfull/bematterfulltest/supplemental/bad-response.json +++ b/adapters/bematterfull/bematterfulltest/supplemental/bad-response.json @@ -99,7 +99,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ], diff --git a/adapters/bematterfull/bematterfulltest/supplemental/invalid-ext-bidder-object.json b/adapters/bematterfull/bematterfulltest/supplemental/invalid-ext-bidder-object.json index 67778fd4b8e..1b4ed00392a 100644 --- a/adapters/bematterfull/bematterfulltest/supplemental/invalid-ext-bidder-object.json +++ b/adapters/bematterfull/bematterfulltest/supplemental/invalid-ext-bidder-object.json @@ -42,7 +42,7 @@ "httpCalls": [], "expectedMakeRequestsErrors": [ { - "value": "Failed to deserialize Bematterfull extension: json: cannot unmarshal array into Go value of type openrtb_ext.ExtBematterfull", + "value": "Failed to deserialize Bematterfull extension: expect { or n, but found [", "comparison": "literal" } ] diff --git a/adapters/bematterfull/bematterfulltest/supplemental/invalid-ext-object.json b/adapters/bematterfull/bematterfulltest/supplemental/invalid-ext-object.json index aa215eb3e34..16cf58bbe54 100644 --- a/adapters/bematterfull/bematterfulltest/supplemental/invalid-ext-object.json +++ b/adapters/bematterfull/bematterfulltest/supplemental/invalid-ext-object.json @@ -40,7 +40,7 @@ "httpCalls": [], "expectedMakeRequestsErrors": [ { - "value": "Failed to deserialize bidder impression extension: json: cannot unmarshal string into Go value of type adapters.ExtImpBidder", + "value": "Failed to deserialize bidder impression extension: expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/bematterfull/bematterfulltest_test.go b/adapters/bematterfull/bematterfulltest_test.go index 36198bc4f2a..92296231b05 100644 --- a/adapters/bematterfull/bematterfulltest_test.go +++ b/adapters/bematterfull/bematterfulltest_test.go @@ -3,9 +3,9 @@ package bematterfull import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/bematterfull/params_test.go b/adapters/bematterfull/params_test.go index a093edbe6ac..769195f6f0f 100644 --- a/adapters/bematterfull/params_test.go +++ b/adapters/bematterfull/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/between/between.go b/adapters/between/between.go index a639c219561..fe20978285b 100644 --- a/adapters/between/between.go +++ b/adapters/between/between.go @@ -9,11 +9,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type BetweenAdapter struct { @@ -69,14 +70,14 @@ func (a *BetweenAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *ada func unpackImpExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpBetween, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: fmt.Sprintf("ignoring imp id=%s, invalid BidderExt", imp.ID), } } var betweenExt openrtb_ext.ExtImpBetween - if err := json.Unmarshal(bidderExt.Bidder, &betweenExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &betweenExt); err != nil { return nil, &errortypes.BadInput{ Message: fmt.Sprintf("ignoring imp id=%s, invalid ImpExt", imp.ID), } @@ -183,7 +184,7 @@ func (a *BetweenAdapter) MakeBids(internalRequest *openrtb2.BidRequest, external }} } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: fmt.Sprintf("Unable to unpackage bid response. Error %s", err.Error()), }} diff --git a/adapters/between/between_test.go b/adapters/between/between_test.go index 332ba00b5d0..61f759126be 100644 --- a/adapters/between/between_test.go +++ b/adapters/between/between_test.go @@ -3,9 +3,9 @@ package between import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/between/betweentest/supplemental/bad-response-body.json b/adapters/between/betweentest/supplemental/bad-response-body.json index 2998f11a2f9..b35d6cec165 100644 --- a/adapters/between/betweentest/supplemental/bad-response-body.json +++ b/adapters/between/betweentest/supplemental/bad-response-body.json @@ -70,7 +70,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "Unable to unpackage bid response. Error json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "Unable to unpackage bid response. Error expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/between/params_test.go b/adapters/between/params_test.go index 5772c218bc0..5e30dba116d 100644 --- a/adapters/between/params_test.go +++ b/adapters/between/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/between.json diff --git a/adapters/beyondmedia/beyondmedia.go b/adapters/beyondmedia/beyondmedia.go index bc1e8ea4b69..bafa5791d86 100644 --- a/adapters/beyondmedia/beyondmedia.go +++ b/adapters/beyondmedia/beyondmedia.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -43,10 +44,10 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E var bidderExt adapters.ExtImpBidder var beyondMediaExt openrtb_ext.ImpExtBeyondMedia - if err = json.Unmarshal(reqCopy.Imp[0].Ext, &bidderExt); err != nil { + if err = jsonutil.Unmarshal(reqCopy.Imp[0].Ext, &bidderExt); err != nil { return nil, []error{err} } - if err = json.Unmarshal(bidderExt.Bidder, &beyondMediaExt); err != nil { + if err = jsonutil.Unmarshal(bidderExt.Bidder, &beyondMediaExt); err != nil { return nil, []error{err} } @@ -104,7 +105,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } diff --git a/adapters/beyondmedia/beyondmedia_test.go b/adapters/beyondmedia/beyondmedia_test.go index 1f828e50b3a..94eb5bd741a 100644 --- a/adapters/beyondmedia/beyondmedia_test.go +++ b/adapters/beyondmedia/beyondmedia_test.go @@ -3,9 +3,9 @@ package beyondmedia import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/beyondmedia/beyondmediatest/supplemental/bad_response.json b/adapters/beyondmedia/beyondmediatest/supplemental/bad_response.json index 906fe1cadaf..65d1a117c98 100644 --- a/adapters/beyondmedia/beyondmediatest/supplemental/bad_response.json +++ b/adapters/beyondmedia/beyondmediatest/supplemental/bad_response.json @@ -78,7 +78,7 @@ }], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/beyondmedia/params_test.go b/adapters/beyondmedia/params_test.go index 8796b200ede..2f6d969f1ab 100644 --- a/adapters/beyondmedia/params_test.go +++ b/adapters/beyondmedia/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/bidder.go b/adapters/bidder.go index 47c71d78df6..0818120b783 100644 --- a/adapters/bidder.go +++ b/adapters/bidder.go @@ -6,10 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/currency" - "github.com/prebid/prebid-server/v2/metrics" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/currency" + "github.com/prebid/prebid-server/v3/metrics" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // Bidder describes how to connect to external demand. diff --git a/adapters/bidmachine/bidmachine.go b/adapters/bidmachine/bidmachine.go index 3ff85b1dd79..81a72cdac5b 100644 --- a/adapters/bidmachine/bidmachine.go +++ b/adapters/bidmachine/bidmachine.go @@ -12,11 +12,12 @@ import ( "github.com/prebid/openrtb/v20/adcom1" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -54,14 +55,14 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, _ *adapters.ExtraRe } var bidderExt adapters.ExtImpBidder - err := json.Unmarshal(impression.Ext, &bidderExt) + err := jsonutil.Unmarshal(impression.Ext, &bidderExt) if err != nil { errs = append(errs, err) continue } var impressionExt openrtb_ext.ExtImpBidmachine - err = json.Unmarshal(bidderExt.Bidder, &impressionExt) + err = jsonutil.Unmarshal(bidderExt.Bidder, &impressionExt) if err != nil { errs = append(errs, err) continue @@ -137,7 +138,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, _ *adapters.RequestData } var bidResponse openrtb2.BidResponse - err := json.Unmarshal(responseData.Body, &bidResponse) + err := jsonutil.Unmarshal(responseData.Body, &bidResponse) if err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: err.Error(), diff --git a/adapters/bidmachine/bidmachine_test.go b/adapters/bidmachine/bidmachine_test.go index 282241c3d72..dc26633c4fc 100644 --- a/adapters/bidmachine/bidmachine_test.go +++ b/adapters/bidmachine/bidmachine_test.go @@ -3,9 +3,9 @@ package bidmachine import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/bidmachine/params_test.go b/adapters/bidmachine/params_test.go index d396ee09cd3..319fef89029 100644 --- a/adapters/bidmachine/params_test.go +++ b/adapters/bidmachine/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/bidmatic/bidmatic.go b/adapters/bidmatic/bidmatic.go new file mode 100644 index 00000000000..32b7a2ee886 --- /dev/null +++ b/adapters/bidmatic/bidmatic.go @@ -0,0 +1,207 @@ +package bidmatic + +import ( + "encoding/json" + "fmt" + "net/http" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" +) + +type adapter struct { + endpoint string +} + +type bidmaticImpExt struct { + Bidmatic openrtb_ext.ExtImpBidmatic `json:"bidmatic"` +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + totalImps := len(request.Imp) + errors := make([]error, 0, totalImps) + imp2source := make(map[int][]int) + + for i := 0; i < totalImps; i++ { + sourceId, err := validateImpression(&request.Imp[i]) + if err != nil { + errors = append(errors, err) + continue + } + + if _, ok := imp2source[sourceId]; !ok { + imp2source[sourceId] = make([]int, 0, totalImps-i) + } + + imp2source[sourceId] = append(imp2source[sourceId], i) + } + + totalReqs := len(imp2source) + if totalReqs == 0 { + return nil, errors + } + + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + headers.Add("Accept", "application/json") + + reqs := make([]*adapters.RequestData, 0, totalReqs) + + imps := request.Imp + request.Imp = make([]openrtb2.Imp, 0, len(imps)) + for sourceId, impIds := range imp2source { + request.Imp = request.Imp[:0] + + for i := 0; i < len(impIds); i++ { + request.Imp = append(request.Imp, imps[impIds[i]]) + } + + body, err := json.Marshal(request) + if err != nil { + errors = append(errors, fmt.Errorf("error while encoding bidRequest, err: %s", err)) + return nil, errors + } + + reqs = append(reqs, &adapters.RequestData{ + Method: "POST", + Uri: a.endpoint + fmt.Sprintf("?source=%d", sourceId), + Body: body, + Headers: headers, + ImpIDs: openrtb_ext.GetImpIDs(request.Imp), + }) + } + + if len(reqs) == 0 { + return nil, errors + } + + return reqs, errors +} + +func (a *adapter) MakeBids(bidReq *openrtb2.BidRequest, unused *adapters.RequestData, httpRes *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if adapters.IsResponseStatusCodeNoContent(httpRes) { + return nil, nil + } + if err := adapters.CheckResponseStatusCodeForErrors(httpRes); err != nil { + return nil, []error{err} + } + + var bidResp openrtb2.BidResponse + if err := jsonutil.Unmarshal(httpRes.Body, &bidResp); err != nil { + return nil, []error{&errortypes.BadServerResponse{ + Message: fmt.Sprintf("error while decoding response, err: %s", err), + }} + } + + bidResponse := adapters.NewBidderResponse() + var errors []error + + var impOK bool + for _, sb := range bidResp.SeatBid { + for i := 0; i < len(sb.Bid); i++ { + + bid := sb.Bid[i] + + impOK = false + mediaType := openrtb_ext.BidTypeBanner + bid.MType = openrtb2.MarkupBanner + loop: + for _, imp := range bidReq.Imp { + if imp.ID == bid.ImpID { + + impOK = true + + switch { + case imp.Video != nil: + mediaType = openrtb_ext.BidTypeVideo + bid.MType = openrtb2.MarkupVideo + break loop + case imp.Banner != nil: + mediaType = openrtb_ext.BidTypeBanner + bid.MType = openrtb2.MarkupBanner + break loop + case imp.Audio != nil: + mediaType = openrtb_ext.BidTypeAudio + bid.MType = openrtb2.MarkupAudio + break loop + case imp.Native != nil: + mediaType = openrtb_ext.BidTypeNative + bid.MType = openrtb2.MarkupNative + break loop + } + } + } + + if !impOK { + errors = append(errors, &errortypes.BadServerResponse{ + Message: fmt.Sprintf("ignoring bid id=%s, request doesn't contain any impression with id=%s", bid.ID, bid.ImpID), + }) + continue + } + + bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ + Bid: &bid, + BidType: mediaType, + }) + } + } + + return bidResponse, errors +} + +func validateImpression(imp *openrtb2.Imp) (int, error) { + if len(imp.Ext) == 0 { + return 0, &errortypes.BadInput{ + Message: fmt.Sprintf("ignoring imp id=%s, extImpBidder is empty", imp.ID), + } + } + + var bidderExt adapters.ExtImpBidder + + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { + return 0, &errortypes.BadInput{ + Message: fmt.Sprintf("ignoring imp id=%s, error while decoding extImpBidder, err: %s", imp.ID, err), + } + } + + impExt := openrtb_ext.ExtImpBidmatic{} + err := jsonutil.Unmarshal(bidderExt.Bidder, &impExt) + if err != nil { + return 0, &errortypes.BadInput{ + Message: fmt.Sprintf("ignoring imp id=%s, error while decoding impExt, err: %s", imp.ID, err), + } + } + + // common extension for all impressions + var impExtBuffer []byte + + impExtBuffer, err = json.Marshal(&bidmaticImpExt{ + Bidmatic: impExt, + }) + if err != nil { + return 0, &errortypes.BadInput{ + Message: fmt.Sprintf("ignoring imp id=%s, error while marshaling impExt, err: %s", imp.ID, err), + } + } + + if impExt.BidFloor > 0 { + imp.BidFloor = impExt.BidFloor + } + + imp.Ext = impExtBuffer + + source, err := impExt.SourceId.Int64() // jsonutil.Unmarshal returns err if it isn't valid + if err != nil { + return 0, err + } + return int(source), nil +} + +// Builder builds a new instance of the bidmatic adapter for the given bidder with the given config. +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + return &adapter{endpoint: config.Endpoint}, nil +} diff --git a/adapters/bidmatic/bidmatic_test.go b/adapters/bidmatic/bidmatic_test.go new file mode 100644 index 00000000000..b546eca545e --- /dev/null +++ b/adapters/bidmatic/bidmatic_test.go @@ -0,0 +1,23 @@ +package bidmatic + +import ( + "testing" + + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder( + openrtb_ext.BidderBidmatic, + config.Adapter{Endpoint: "http://adapter.bidmatic.io/pbs/ortb"}, + config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}, + ) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "bidmatictest", bidder) +} diff --git a/adapters/openweb/openwebtest/supplemental/status-400.json b/adapters/bidmatic/bidmatictest/exemplary/media-type-mapping.json similarity index 50% rename from adapters/openweb/openwebtest/supplemental/status-400.json rename to adapters/bidmatic/bidmatictest/exemplary/media-type-mapping.json index 20500de2b4a..57f1215af43 100644 --- a/adapters/openweb/openwebtest/supplemental/status-400.json +++ b/adapters/bidmatic/bidmatictest/exemplary/media-type-mapping.json @@ -14,7 +14,7 @@ }, "ext": { "bidder": { - "aid": 1000 + "source": 1000 } } } @@ -24,7 +24,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "http://ghb.spotim.market/pbs/ortb?aid=1000", + "uri": "http://adapter.bidmatic.io/pbs/ortb?source=1000", "body": { "id": "test-request-id", "imp": [ @@ -39,8 +39,8 @@ ] }, "ext": { - "openweb": { - "aid": 1000 + "bidmatic": { + "source": 1000 } } } @@ -49,18 +49,43 @@ "impIDs":["test-imp-id"] }, "mockResponse": { - "status": 400, - "body": "Bad request" + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test-bid-id", + "impid": "test-imp-id", + "mtype": 2, + "price": 3.5, + "w": 900, + "h": 250 + } + ] + } + ] + } } } ], - - "expectedMakeBidsErrors": [ + "expectedBidResponses": [ { - "value": "Remote server error: \"Bad request\"", - "comparison": "literal" + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "mtype": 2, + "price": 3.5, + "w": 900, + "h": 250 + }, + "type": "video" + } + ] } - ], - - "expectedBidResponses": [] -} + ] +} \ No newline at end of file diff --git a/adapters/bidmatic/bidmatictest/exemplary/simple-banner.json b/adapters/bidmatic/bidmatictest/exemplary/simple-banner.json new file mode 100644 index 00000000000..d3c41278231 --- /dev/null +++ b/adapters/bidmatic/bidmatictest/exemplary/simple-banner.json @@ -0,0 +1,98 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "source": 1000, + "siteId": 1234, + "bidFloor": 20 + } + } + } + ] + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://adapter.bidmatic.io/pbs/ortb?source=1000", + "body": { + "id": "test-request-id", + "imp": [ + { + "id":"test-imp-id", + "banner": { + "format": [ + {"w":300,"h":250}, + {"w":300,"h":600} + ] + }, + "bidfloor": 20, + "ext": { + "bidmatic": { + "source": 1000, + "siteId": 1234, + "bidFloor": 20 + } + } + } + ] + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test-bid-id", + "impid": "test-imp-id", + "mtype": 2, + "price": 3.5, + "w": 900, + "h": 250 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "mtype": 1, + "price": 3.5, + "w": 900, + "h": 250 + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/openweb/openwebtest/supplemental/status-204.json b/adapters/bidmatic/bidmatictest/exemplary/simple-video.json similarity index 82% rename from adapters/openweb/openwebtest/supplemental/status-204.json rename to adapters/bidmatic/bidmatictest/exemplary/simple-video.json index 637c2113fc5..a9bcb6a141e 100644 --- a/adapters/openweb/openwebtest/supplemental/status-204.json +++ b/adapters/bidmatic/bidmatictest/exemplary/simple-video.json @@ -14,7 +14,7 @@ }, "ext": { "bidder": { - "aid": 1000 + "source": 1000 } } } @@ -24,7 +24,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "http://ghb.spotim.market/pbs/ortb?aid=1000", + "uri": "http://adapter.bidmatic.io/pbs/ortb?source=1000", "body": { "id": "test-request-id", "imp": [ @@ -39,8 +39,8 @@ ] }, "ext": { - "openweb": { - "aid": 1000 + "bidmatic": { + "source": 1000 } } } @@ -52,5 +52,6 @@ "status": 204 } } - ] -} + ], + "expectedBidResponses": [] +} \ No newline at end of file diff --git a/adapters/bidmatic/bidmatictest/supplemental/explicit-dimensions.json b/adapters/bidmatic/bidmatictest/supplemental/explicit-dimensions.json new file mode 100644 index 00000000000..b1f2f6ea510 --- /dev/null +++ b/adapters/bidmatic/bidmatictest/supplemental/explicit-dimensions.json @@ -0,0 +1,60 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 100, + "h": 400 + }, + "ext": { + "bidder": { + "source": 1000 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://adapter.bidmatic.io/pbs/ortb?source=1000", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 100, + "h": 400 + }, + "ext": { + "bidmatic": { + "source": 1000 + } + } + } + ] + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 204 + } + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/bidmatic/bidmatictest/supplemental/imp-ext-empty.json b/adapters/bidmatic/bidmatictest/supplemental/imp-ext-empty.json new file mode 100644 index 00000000000..0607da05fb9 --- /dev/null +++ b/adapters/bidmatic/bidmatictest/supplemental/imp-ext-empty.json @@ -0,0 +1,21 @@ +{ + "mockBidRequest": { + "id": "unsupported-native-request", + "imp": [ + { + "id": "unsupported-native-imp", + "video": { + "w": 100, + "h": 200 + } + } + ] + }, + + "expectedMakeRequestsErrors": [ + { + "value": "ignoring imp id=unsupported-native-imp, extImpBidder is empty", + "comparison": "literal" + } + ] +} diff --git a/adapters/bidmatic/bidmatictest/supplemental/wrong-impression-ext.json b/adapters/bidmatic/bidmatictest/supplemental/wrong-impression-ext.json new file mode 100644 index 00000000000..c471560932c --- /dev/null +++ b/adapters/bidmatic/bidmatictest/supplemental/wrong-impression-ext.json @@ -0,0 +1,26 @@ +{ + "mockBidRequest": { + "id": "unsupported-native-request", + "imp": [ + { + "id": "unsupported-native-imp", + "video": { + "w": 100, + "h": 200 + }, + "ext": { + "bidder": { + "source": "some string instead of int" + } + } + } + ] + }, + + "expectedMakeRequestsErrors": [ + { + "value": "ignoring imp id=unsupported-native-imp, error while marshaling impExt, err: json: invalid number literal \"some string instead of int\"", + "comparison": "literal" + } + ] +} diff --git a/adapters/openweb/openwebtest/supplemental/wrong-impression-mapping.json b/adapters/bidmatic/bidmatictest/supplemental/wrong-impression-mapping.json similarity index 90% rename from adapters/openweb/openwebtest/supplemental/wrong-impression-mapping.json rename to adapters/bidmatic/bidmatictest/supplemental/wrong-impression-mapping.json index f83ec46da6f..05679082aa3 100644 --- a/adapters/openweb/openwebtest/supplemental/wrong-impression-mapping.json +++ b/adapters/bidmatic/bidmatictest/supplemental/wrong-impression-mapping.json @@ -14,7 +14,7 @@ }, "ext": { "bidder": { - "aid": 1000 + "source": 1000 } } } @@ -24,7 +24,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "http://ghb.spotim.market/pbs/ortb?aid=1000", + "uri": "http://adapter.bidmatic.io/pbs/ortb?source=1000", "body": { "id": "test-request-id", "imp": [ @@ -39,8 +39,8 @@ ] }, "ext": { - "openweb": { - "aid": 1000 + "bidmatic": { + "source": 1000 } } } diff --git a/adapters/bidmatic/bidmatictest/supplemental/wrong-response.json b/adapters/bidmatic/bidmatictest/supplemental/wrong-response.json new file mode 100644 index 00000000000..5daadf6e1e1 --- /dev/null +++ b/adapters/bidmatic/bidmatictest/supplemental/wrong-response.json @@ -0,0 +1,65 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 100, + "h": 400 + }, + "ext": { + "bidder": { + "source": 1000 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://adapter.bidmatic.io/pbs/ortb?source=1000", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 100, + "h": 400 + }, + "ext": { + "bidmatic": { + "source": 1000 + } + } + } + ] + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200 + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "error while decoding response, err: expect { or n, but found", + "comparison": "startswith" + } + ] +} diff --git a/adapters/bidmatic/params_test.go b/adapters/bidmatic/params_test.go new file mode 100644 index 00000000000..bfea9fddaef --- /dev/null +++ b/adapters/bidmatic/params_test.go @@ -0,0 +1,64 @@ +package bidmatic + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v3/openrtb_ext" +) + +// This file actually intends to test static/bidder-params/bidmatic.json +// These also validate the format of the external API: request.imp[i].ext.prebid.bidder.bidmatic +// TestValidParams makes sure that the bidmatic schema accepts all imp.ext fields which we intend to support. + +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schemas. %v", err) + } + + for _, validParam := range validParams { + if err := validator.Validate(openrtb_ext.BidderBidmatic, json.RawMessage(validParam)); err != nil { + t.Errorf("Schema rejected bidmatic params: %s", validParam) + } + } +} + +// TestInvalidParams makes sure that the bidmatic schema rejects all the imp.ext fields we don't support. +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schemas. %v", err) + } + + for _, invalidParam := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderBidmatic, json.RawMessage(invalidParam)); err == nil { + ext := openrtb_ext.ExtImpBidmatic{} + err = json.Unmarshal([]byte(invalidParam), &ext) + if err == nil { + t.Errorf("Schema allowed unexpected params: %s", invalidParam) + } + } + } +} + +var validParams = []string{ + `{"source":123}`, + `{"source":"123"}`, + `{"source":123,"placementId":1234}`, + `{"source":123,"siteId":4321}`, + `{"source":"123","siteId":0,"bidFloor":0}`, +} + +var invalidParams = []string{ + ``, + `null`, + `true`, + `5`, + `4.2`, + `[]`, + `{}`, + `{"source":"qwerty"}`, + `{"source":"123","placementId":"123"}`, + `{"source":123, "placementId":"123", "siteId":"321"}`, +} diff --git a/adapters/bidmyadz/bidmyadz.go b/adapters/bidmyadz/bidmyadz.go index 8b9b4cc841b..b2f8cda564a 100644 --- a/adapters/bidmyadz/bidmyadz.go +++ b/adapters/bidmyadz/bidmyadz.go @@ -7,10 +7,11 @@ import ( "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -111,7 +112,7 @@ func (a *adapter) MakeBids( responseBody := bidderRawResponse.Body var bidResp openrtb2.BidResponse - if err := json.Unmarshal(responseBody, &bidResp); err != nil { + if err := jsonutil.Unmarshal(responseBody, &bidResp); err != nil { return nil, []error{err} } @@ -136,7 +137,7 @@ func (a *adapter) MakeBids( var bidExt bidExt var bidType openrtb_ext.BidType - if err := json.Unmarshal(bid.Ext, &bidExt); err != nil { + if err := jsonutil.Unmarshal(bid.Ext, &bidExt); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: fmt.Sprintf("BidExt parsing error. %s", err.Error()), }} diff --git a/adapters/bidmyadz/bidmyadz_test.go b/adapters/bidmyadz/bidmyadz_test.go index 41badb559af..f01af44cffb 100644 --- a/adapters/bidmyadz/bidmyadz_test.go +++ b/adapters/bidmyadz/bidmyadz_test.go @@ -5,9 +5,9 @@ import ( "github.com/stretchr/testify/assert" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/bidmyadz/bidmyadztest/supplemental/missing-mediatype.json b/adapters/bidmyadz/bidmyadztest/supplemental/missing-mediatype.json index f787bd20cbc..923576a9ba5 100644 --- a/adapters/bidmyadz/bidmyadztest/supplemental/missing-mediatype.json +++ b/adapters/bidmyadz/bidmyadztest/supplemental/missing-mediatype.json @@ -116,8 +116,8 @@ "expectedMakeBidsErrors": [ { - "value": "BidExt parsing error. unexpected end of JSON input", - "comparison": "literal" + "value": "BidExt parsing error. expect { or n, but found", + "comparison": "startswith" } ] } \ No newline at end of file diff --git a/adapters/bidmyadz/params_test.go b/adapters/bidmyadz/params_test.go index 262dcf0880d..fca34b10245 100644 --- a/adapters/bidmyadz/params_test.go +++ b/adapters/bidmyadz/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/bidscube/bidscube.go b/adapters/bidscube/bidscube.go index c16d01b5a33..8ccd794f869 100644 --- a/adapters/bidscube/bidscube.go +++ b/adapters/bidscube/bidscube.go @@ -9,10 +9,11 @@ import ( "github.com/buger/jsonparser" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -29,7 +30,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, _ *adapters.ExtraRe for _, impression := range impressions { var impExt map[string]json.RawMessage - if err := json.Unmarshal(impression.Ext, &impExt); err != nil { + if err := jsonutil.Unmarshal(impression.Ext, &impExt); err != nil { errs = append(errs, err) continue } @@ -79,7 +80,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, _ *adapters.RequestData } var bidResponse openrtb2.BidResponse - err := json.Unmarshal(responseData.Body, &bidResponse) + err := jsonutil.Unmarshal(responseData.Body, &bidResponse) if err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: err.Error(), diff --git a/adapters/bidscube/bidscube_test.go b/adapters/bidscube/bidscube_test.go index e64ccdbef63..5396ccd4261 100644 --- a/adapters/bidscube/bidscube_test.go +++ b/adapters/bidscube/bidscube_test.go @@ -3,9 +3,9 @@ package bidscube import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/bidscube/bidscubetest/supplemental/bad_response.json b/adapters/bidscube/bidscubetest/supplemental/bad_response.json index a6087b506a4..2eaaba4d21a 100644 --- a/adapters/bidscube/bidscubetest/supplemental/bad_response.json +++ b/adapters/bidscube/bidscubetest/supplemental/bad_response.json @@ -77,7 +77,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/bidscube/bidscubetest/supplemental/imp_ext_string.json b/adapters/bidscube/bidscubetest/supplemental/imp_ext_string.json index ad6c2ede6e8..935764f46d9 100644 --- a/adapters/bidscube/bidscubetest/supplemental/imp_ext_string.json +++ b/adapters/bidscube/bidscubetest/supplemental/imp_ext_string.json @@ -30,7 +30,7 @@ }, "expectedMakeRequestsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type map[string]json.RawMessage", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/bidscube/params_test.go b/adapters/bidscube/params_test.go index 9337c4dfb40..9f368f939a2 100644 --- a/adapters/bidscube/params_test.go +++ b/adapters/bidscube/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // TestValidParams makes sure that the bidscube schema accepts all imp.ext fields which we intend to support. diff --git a/adapters/bidstack/bidstack.go b/adapters/bidstack/bidstack.go index c4396153211..555abff0c72 100644 --- a/adapters/bidstack/bidstack.go +++ b/adapters/bidstack/bidstack.go @@ -9,9 +9,10 @@ import ( "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) const ( @@ -84,7 +85,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, _ *adapters.RequestData } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{fmt.Errorf("bid response unmarshal: %v", err)} } @@ -117,10 +118,10 @@ func prepareHeaders(request *openrtb2.BidRequest) (headers http.Header, err erro func getBidderExt(imp openrtb2.Imp) (bidderImpExt openrtb_ext.ImpExtBidstack, err error) { var impExt adapters.ExtImpBidder - if err = json.Unmarshal(imp.Ext, &impExt); err != nil { + if err = jsonutil.Unmarshal(imp.Ext, &impExt); err != nil { return bidderImpExt, fmt.Errorf("imp ext: %v", err) } - if err = json.Unmarshal(impExt.Bidder, &bidderImpExt); err != nil { + if err = jsonutil.Unmarshal(impExt.Bidder, &bidderImpExt); err != nil { return bidderImpExt, fmt.Errorf("bidder ext: %v", err) } return bidderImpExt, nil diff --git a/adapters/bidstack/bidstack_test.go b/adapters/bidstack/bidstack_test.go index 3c160583729..9010ce5014b 100644 --- a/adapters/bidstack/bidstack_test.go +++ b/adapters/bidstack/bidstack_test.go @@ -7,9 +7,9 @@ import ( "github.com/prebid/openrtb/v20/openrtb2" "github.com/stretchr/testify/assert" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/bidstack/params_test.go b/adapters/bidstack/params_test.go index d7dc18e4a03..3cca0f447b1 100644 --- a/adapters/bidstack/params_test.go +++ b/adapters/bidstack/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/bigoad/bigoad.go b/adapters/bigoad/bigoad.go new file mode 100644 index 00000000000..e968139d599 --- /dev/null +++ b/adapters/bigoad/bigoad.go @@ -0,0 +1,157 @@ +package bigoad + +import ( + "encoding/json" + "fmt" + "net/http" + "text/template" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" +) + +type adapter struct { + endpoint *template.Template +} + +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + template, err := template.New("endpointTemplate").Parse(config.Endpoint) + if err != nil { + return nil, fmt.Errorf("unable to parse endpoint url template: %v", err) + } + + bidder := &adapter{ + endpoint: template, + } + + return bidder, nil +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + bigoadExt, err := getImpExt(&request.Imp[0]) + if err != nil { + return nil, []error{err} + } + + resolvedUrl, err := a.buildEndpointURL(bigoadExt) + if err != nil { + return nil, []error{err} + } + + requestJSON, err := json.Marshal(request) + if err != nil { + return nil, []error{err} + } + + requestData := &adapters.RequestData{ + Method: "POST", + Uri: resolvedUrl, + Body: requestJSON, + Headers: getHeaders(request), + ImpIDs: openrtb_ext.GetImpIDs(request.Imp), + } + + return []*adapters.RequestData{requestData}, nil +} + +func getHeaders(request *openrtb2.BidRequest) http.Header { + headers := http.Header{} + addNonEmptyHeaders(&headers, map[string]string{ + "Content-Type": "application/json;charset=utf-8", + "Accept": "application/json", + "x-openrtb-version": "2.5", + }) + return headers +} + +func addNonEmptyHeaders(headers *http.Header, headerValues map[string]string) { + for key, value := range headerValues { + if len(value) > 0 { + headers.Add(key, value) + } + } +} + +func getImpExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpBigoAd, error) { + var bidderExt adapters.ExtImpBidder + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { + return nil, &errortypes.BadInput{ + Message: fmt.Sprintf("imp %s: unable to unmarshal ext", imp.ID), + } + } + var bigoadExt openrtb_ext.ExtImpBigoAd + if err := jsonutil.Unmarshal(bidderExt.Bidder, &bigoadExt); err != nil { + return nil, &errortypes.BadInput{ + Message: fmt.Sprintf("imp %s: unable to unmarshal ext.bidder: %v", imp.ID, err), + } + } + imp.Ext = bidderExt.Bidder + return &bigoadExt, nil +} + +func (a *adapter) buildEndpointURL(params *openrtb_ext.ExtImpBigoAd) (string, error) { + endpointParams := macros.EndpointTemplateParams{SspId: params.SspId} + return macros.ResolveMacros(a.endpoint, endpointParams) +} + +func (a *adapter) MakeBids(request *openrtb2.BidRequest, _ *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if adapters.IsResponseStatusCodeNoContent(responseData) { + return nil, nil + } + + if err := adapters.CheckResponseStatusCodeForErrors(responseData); err != nil { + return nil, []error{err} + } + + var bidResponse openrtb2.BidResponse + if err := jsonutil.Unmarshal(responseData.Body, &bidResponse); err != nil { + return nil, []error{&errortypes.BadServerResponse{ + Message: fmt.Sprintf("Bad server response: %d", err), + }} + } + + if len(bidResponse.SeatBid) == 0 { + return nil, []error{&errortypes.BadServerResponse{ + Message: "Empty SeatBid array", + }} + } + + bidResponseWithCapacity := adapters.NewBidderResponseWithBidsCapacity(len(bidResponse.SeatBid[0].Bid)) + + var errors []error + seatBid := bidResponse.SeatBid[0] + for i := range seatBid.Bid { + bid := seatBid.Bid[i] + bidType, err := getBidType(request.Imp[0], bid) + if err != nil { + errors = append(errors, err) + continue + } + bidResponseWithCapacity.Bids = append(bidResponseWithCapacity.Bids, &adapters.TypedBid{ + Bid: &bid, + BidType: bidType, + }) + } + + return bidResponseWithCapacity, errors +} + +func getBidType(imp openrtb2.Imp, 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 + case openrtb2.MarkupVideo: + return openrtb_ext.BidTypeVideo, nil + } + + return "", &errortypes.BadInput{ + Message: fmt.Sprintf("unrecognized bid type in response from bigoad %s", imp.ID), + } +} diff --git a/adapters/bigoad/bigoad_test.go b/adapters/bigoad/bigoad_test.go new file mode 100644 index 00000000000..7c51c8f80d5 --- /dev/null +++ b/adapters/bigoad/bigoad_test.go @@ -0,0 +1,29 @@ +package bigoad + +import ( + "testing" + + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/stretchr/testify/assert" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderBigoAd, + config.Adapter{Endpoint: "https://api.imotech.tech/Ad/GetAdOut?sspid={{.SspId}}"}, + config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "bigoadtest", bidder) +} + +func TestEndpointTemplateMalformed(t *testing.T) { + _, buildErr := Builder(openrtb_ext.BidderBigoAd, config.Adapter{ + Endpoint: "{{Malformed}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + assert.Error(t, buildErr) +} diff --git a/adapters/bigoad/bigoadtest/exemplary/banner_app.json b/adapters/bigoad/bigoadtest/exemplary/banner_app.json new file mode 100644 index 00000000000..69782a0e78d --- /dev/null +++ b/adapters/bigoad/bigoadtest/exemplary/banner_app.json @@ -0,0 +1,186 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "id": "123456789", + "bundle": "com.prebid", + "domain": "prebid.com", + "ver": "3.3.2", + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ] + }, + "device": { + "ifa": "87857b31-8942-4646-ae80-ab9c95bf3fab", + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "geo": { + "lon": 16.0, + "country": "KWT", + "city": "deli" + } + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "tagid", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "sspid": "sspid" + } + } + } + ], + "tmax": 1000 + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://api.imotech.tech/Ad/GetAdOut?sspid=sspid", + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "body": { + "id": "test-request-id", + "app": { + "id": "123456789", + "bundle": "com.prebid", + "domain": "prebid.com", + "ver": "3.3.2", + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ] + }, + "device": { + "ifa": "87857b31-8942-4646-ae80-ab9c95bf3fab", + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "geo": { + "lon": 16.0, + "country": "KWT", + "city": "deli" + } + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "tagid", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "sspid": "sspid" + } + } + ], + "tmax": 1000 + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "bigoad", + "type": "banner", + "bid": [ + { + "id": "test-imp-id", + "impid": "test-imp-id", + "adid": "11110126", + "mtype": 1, + "price": 0.42632559, + "adm": "some-test-ad", + "adomain": [ + "www.lazada.com" + ], + "crid": "test-crid", + "cat": [ + "IAB22", + "IAB8-5" + ], + "attr": [ + 4 + ], + "h": 250, + "w": 300, + "ext": { + "dsp": "bigo" + } + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-imp-id", + "impid": "test-imp-id", + "adid": "11110126", + "price": 0.42632559, + "adm": "some-test-ad", + "mtype": 1, + "adomain": [ + "www.lazada.com" + ], + "crid": "test-crid", + "cat": [ + "IAB22", + "IAB8-5" + ], + "attr": [ + 4 + ], + "h": 250, + "w": 300, + "ext": { + "dsp": "bigo" + } + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/bigoad/bigoadtest/exemplary/banner_web.json b/adapters/bigoad/bigoadtest/exemplary/banner_web.json new file mode 100644 index 00000000000..3da662178fe --- /dev/null +++ b/adapters/bigoad/bigoadtest/exemplary/banner_web.json @@ -0,0 +1,135 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "site": { + "domain": "com.prebid", + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "imp": [ + { + "id": "some-impression-id1", + "tagid": "tagid", + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "sspid": "sspid" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "uri": "https://api.imotech.tech/Ad/GetAdOut?sspid=sspid", + "body": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "some-impression-id1", + "tagid": "tagid", + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "sspid": "sspid" + } + } + ], + "site": { + "domain": "com.prebid", + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "tmax": 1000 + }, + "impIDs": [ + "some-impression-id1" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "awesome-resp-id", + "seatbid": [ + { + "bid": [ + { + "id": "some-impression-id1", + "impid": "some-impression-id1", + "mtype": 1, + "price": 3.5, + "adm": "test_adm", + "adomain": [ + "com.prebid" + ], + "crid": "20", + "w": 320, + "h": 50 + } + ], + "type": "banner", + "seat": "bigoad" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "some-impression-id1", + "impid": "some-impression-id1", + "mtype": 1, + "price": 3.5, + "adm": "test_adm", + "crid": "20", + "adomain": [ + "com.prebid" + ], + "w": 320, + "h": 50 + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/bigoad/bigoadtest/exemplary/native_app.json b/adapters/bigoad/bigoadtest/exemplary/native_app.json new file mode 100644 index 00000000000..22be64e8a38 --- /dev/null +++ b/adapters/bigoad/bigoadtest/exemplary/native_app.json @@ -0,0 +1,147 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "app": { + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ], + "bundle": "com.app.awesome", + "name": "Awesome App", + "domain": "awesomeapp.com", + "id": "123456789" + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "native": { + "ver": "1.1", + "request": "{\"adunit\":2,\"assets\":[{\"id\":3,\"img\":{\"h\":120,\"hmin\":0,\"type\":3,\"w\":180,\"wmin\":0},\"required\":1},{\"id\":0,\"required\":1,\"title\":{\"len\":25}},{\"data\":{\"len\":25,\"type\":1},\"id\":4,\"required\":1},{\"data\":{\"len\":140,\"type\":2},\"id\":6,\"required\":1}],\"context\":1,\"layout\":1,\"contextsubtype\":11,\"plcmtcnt\":1,\"plcmttype\":2,\"ver\":\"1.1\",\"ext\":{\"banner\":{\"w\":320,\"h\":50}}}" + }, + "ext": { + "bidder": { + "sspid": "sspid" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "uri": "https://api.imotech.tech/Ad/GetAdOut?sspid=sspid", + "body": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "some-impression-id", + "native": { + "ver": "1.1", + "request": "{\"adunit\":2,\"assets\":[{\"id\":3,\"img\":{\"h\":120,\"hmin\":0,\"type\":3,\"w\":180,\"wmin\":0},\"required\":1},{\"id\":0,\"required\":1,\"title\":{\"len\":25}},{\"data\":{\"len\":25,\"type\":1},\"id\":4,\"required\":1},{\"data\":{\"len\":140,\"type\":2},\"id\":6,\"required\":1}],\"context\":1,\"layout\":1,\"contextsubtype\":11,\"plcmtcnt\":1,\"plcmttype\":2,\"ver\":\"1.1\",\"ext\":{\"banner\":{\"w\":320,\"h\":50}}}" + }, + "tagid": "ogTAGID", + "ext": { + "sspid": "sspid" + } + } + ], + "app": { + "id": "123456789", + "name": "Awesome App", + "bundle": "com.app.awesome", + "domain": "awesomeapp.com", + "cat": [ + "IAB22-1" + ], + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + }, + "impIDs": [ + "some-impression-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "awesome-resp-id", + "seatbid": [ + { + "bid": [ + { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id", + "price": 3.5, + "adm": "awesome-markup", + "adomain": [ + "awesome.com" + ], + "crid": "20", + "mtype": 4 + } + ], + "type": "native", + "seat": "bigoad" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id", + "price": 3.5, + "adm": "awesome-markup", + "crid": "20", + "mtype": 4, + "adomain": [ + "awesome.com" + ] + }, + "type": "native" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/bigoad/bigoadtest/exemplary/native_web.json b/adapters/bigoad/bigoadtest/exemplary/native_web.json new file mode 100644 index 00000000000..61857ca5671 --- /dev/null +++ b/adapters/bigoad/bigoadtest/exemplary/native_web.json @@ -0,0 +1,134 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ipv6": "2607:fb90:f27:4512:d800:cb23:a603:e245", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "native": { + "ver": "1.1", + "request": "{\"adunit\":2,\"assets\":[{\"id\":3,\"img\":{\"h\":120,\"hmin\":0,\"type\":3,\"w\":180,\"wmin\":0},\"required\":1},{\"id\":0,\"required\":1,\"title\":{\"len\":25}},{\"data\":{\"len\":25,\"type\":1},\"id\":4,\"required\":1},{\"data\":{\"len\":140,\"type\":2},\"id\":6,\"required\":1}],\"context\":1,\"layout\":1,\"contextsubtype\":11,\"plcmtcnt\":1,\"plcmttype\":2,\"ver\":\"1.1\",\"ext\":{\"banner\":{\"w\":320,\"h\":50}}}" + }, + "ext": { + "bidder": { + "sspid": "sspid" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "uri": "https://api.imotech.tech/Ad/GetAdOut?sspid=sspid", + "body": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ipv6": "2607:fb90:f27:4512:d800:cb23:a603:e245", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "native": { + "ver": "1.1", + "request": "{\"adunit\":2,\"assets\":[{\"id\":3,\"img\":{\"h\":120,\"hmin\":0,\"type\":3,\"w\":180,\"wmin\":0},\"required\":1},{\"id\":0,\"required\":1,\"title\":{\"len\":25}},{\"data\":{\"len\":25,\"type\":1},\"id\":4,\"required\":1},{\"data\":{\"len\":140,\"type\":2},\"id\":6,\"required\":1}],\"context\":1,\"layout\":1,\"contextsubtype\":11,\"plcmtcnt\":1,\"plcmttype\":2,\"ver\":\"1.1\",\"ext\":{\"banner\":{\"w\":320,\"h\":50}}}" + }, + "ext": { + "sspid": "sspid" + } + } + ], + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + }, + "impIDs": [ + "some-impression-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "awesome-resp-id", + "seatbid": [ + { + "bid": [ + { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id", + "mtype": 4, + "price": 3.5, + "adm": "awesome-markup", + "adomain": [ + "awesome.com" + ], + "crid": "20" + } + ], + "seat": "bigoad" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id", + "mtype": 4, + "price": 3.5, + "adm": "awesome-markup", + "crid": "20", + "adomain": [ + "awesome.com" + ] + }, + "type": "native" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/bigoad/bigoadtest/exemplary/video_app.json b/adapters/bigoad/bigoadtest/exemplary/video_app.json new file mode 100644 index 00000000000..db9940ebcfe --- /dev/null +++ b/adapters/bigoad/bigoadtest/exemplary/video_app.json @@ -0,0 +1,160 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "app": { + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ], + "bundle": "com.app.awesome", + "name": "Awesome App", + "domain": "awesomeapp.com", + "id": "123456789" + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "ext": { + "bidder": { + "sspid": "sspid" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "uri": "https://api.imotech.tech/Ad/GetAdOut?sspid=sspid", + "body": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "some-impression-id", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 120, + "maxduration": 150, + "w": 640, + "h": 480 + }, + "tagid": "ogTAGID", + "ext": { + "sspid": "sspid" + } + } + ], + "app": { + "id": "123456789", + "name": "Awesome App", + "bundle": "com.app.awesome", + "domain": "awesomeapp.com", + "cat": [ + "IAB22-1" + ], + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + }, + "impIDs": [ + "some-impression-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "awesome-resp-id", + "seatbid": [ + { + "bid": [ + { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id", + "price": 3.5, + "adm": "awesome-markup", + "adomain": [ + "awesome.com" + ], + "crid": "20", + "w": 1280, + "h": 720, + "mtype": 2 + } + ], + "seat": "bigoad" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id", + "price": 3.5, + "adm": "awesome-markup", + "crid": "20", + "adomain": [ + "awesome.com" + ], + "w": 1280, + "h": 720, + "mtype": 2 + }, + "type": "video" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/bigoad/bigoadtest/exemplary/video_web.json b/adapters/bigoad/bigoadtest/exemplary/video_web.json new file mode 100644 index 00000000000..c5cf2fcb976 --- /dev/null +++ b/adapters/bigoad/bigoadtest/exemplary/video_web.json @@ -0,0 +1,158 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "ext": { + "bidder": { + "sspid": "sspid" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "uri": "https://api.imotech.tech/Ad/GetAdOut?sspid=sspid", + "body": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 120, + "maxduration": 150, + "w": 640, + "h": 480 + }, + "ext": { + "sspid": "sspid" + } + } + ], + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + }, + "impIDs": [ + "some-impression-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "awesome-resp-id", + "seatbid": [ + { + "bid": [ + { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id", + "mtype": 2, + "price": 3.5, + "adm": "awesome-markup", + "adomain": [ + "awesome.com" + ], + "crid": "20", + "w": 1280, + "h": 720, + "ext": { + "prebid": { + "type": "video" + } + } + } + ], + "seat": "bigoad" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id", + "mtype": 2, + "price": 3.5, + "adm": "awesome-markup", + "adomain": [ + "awesome.com" + ], + "crid": "20", + "w": 1280, + "h": 720, + "ext": { + "prebid": { + "type": "video" + } + } + }, + "type": "video" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/bigoad/bigoadtest/supplemental/empty_seatbid.json b/adapters/bigoad/bigoadtest/supplemental/empty_seatbid.json new file mode 100644 index 00000000000..cce47e6c8f5 --- /dev/null +++ b/adapters/bigoad/bigoadtest/supplemental/empty_seatbid.json @@ -0,0 +1,125 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "app": { + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ], + "bundle": "com.app.awesome", + "name": "Awesome App", + "domain": "awesomeapp.com", + "id": "123456789" + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "ext": { + "bidder": { + "sspid": "sspid" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "uri": "https://api.imotech.tech/Ad/GetAdOut?sspid=sspid", + "body": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "some-impression-id", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 120, + "maxduration": 150, + "w": 640, + "h": 480 + }, + "tagid": "ogTAGID", + "ext": { + "sspid": "sspid" + } + } + ], + "app": { + "id": "123456789", + "name": "Awesome App", + "bundle": "com.app.awesome", + "domain": "awesomeapp.com", + "cat": [ + "IAB22-1" + ], + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + }, + "impIDs": [ + "some-impression-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [] + } + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "Empty SeatBid array", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/bigoad/bigoadtest/supplemental/invalid_mtype.json b/adapters/bigoad/bigoadtest/supplemental/invalid_mtype.json new file mode 100644 index 00000000000..b84579802a0 --- /dev/null +++ b/adapters/bigoad/bigoadtest/supplemental/invalid_mtype.json @@ -0,0 +1,164 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "id": "123456789", + "bundle": "com.prebid", + "domain": "prebid.com", + "ver": "3.3.2", + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ] + }, + "device": { + "ifa": "87857b31-8942-4646-ae80-ab9c95bf3fab", + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "geo": { + "lon": 16.0, + "country": "KWT", + "city": "deli" + } + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "tagid", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "sspid": "sspid" + } + } + } + ], + "tmax": 1000 + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://api.imotech.tech/Ad/GetAdOut?sspid=sspid", + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "body": { + "id": "test-request-id", + "app": { + "id": "123456789", + "bundle": "com.prebid", + "domain": "prebid.com", + "ver": "3.3.2", + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ] + }, + "device": { + "ifa": "87857b31-8942-4646-ae80-ab9c95bf3fab", + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "geo": { + "lon": 16.0, + "country": "KWT", + "city": "deli" + } + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "tagid", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "sspid": "sspid" + } + } + ], + "tmax": 1000 + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "bigoad", + "type": "banner", + "bid": [ + { + "id": "test-imp-id", + "impid": "test-imp-id", + "mtype": 5, + "adid": "11110126", + "price": 0.42632559, + "adm": "some-test-ad", + "adomain": [ + "www.lazada.com" + ], + "crid": "test-crid", + "cat": [ + "IAB22", + "IAB8-5" + ], + "attr": [ + 4 + ], + "h": 250, + "w": 300, + "ext": { + "dsp": "bigo" + } + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [] + } + ], + "expectedMakeBidsErrors": [ + { + "value": "unrecognized bid type in response from bigoad", + "comparison": "regex" + } + ] +} \ No newline at end of file diff --git a/adapters/bigoad/bigoadtest/supplemental/invalid_request.json b/adapters/bigoad/bigoadtest/supplemental/invalid_request.json new file mode 100644 index 00000000000..846b4d3a14f --- /dev/null +++ b/adapters/bigoad/bigoadtest/supplemental/invalid_request.json @@ -0,0 +1,31 @@ +{ + "expectedMakeRequestsErrors": [ + { + "value": "imp some-impression-id: unable to unmarshal ext", + "comparison": "literal" + } + ], + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "some-impression-id", + "tagid": "my-adcode", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "ext": "Awesome" + } + ], + "site": { + "page": "test.com" + } + }, + "httpCalls": [] +} \ No newline at end of file diff --git a/adapters/bigoad/bigoadtest/supplemental/invalid_request_bigo_ext.json b/adapters/bigoad/bigoadtest/supplemental/invalid_request_bigo_ext.json new file mode 100644 index 00000000000..4c0356c2032 --- /dev/null +++ b/adapters/bigoad/bigoadtest/supplemental/invalid_request_bigo_ext.json @@ -0,0 +1,37 @@ +{ + "expectedMakeRequestsErrors": [ + { + "value": "imp some-impression-id: unable to unmarshal ext.bidder", + "comparison": "regex" + } + ], + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "some-impression-id", + "tagid": "my-adcode", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "ext": { + "prebid": { + "bidder": { + "bigoad": {} + } + } + } + } + ], + "site": { + "page": "test.com" + } + }, + "httpCalls": [] +} \ No newline at end of file diff --git a/adapters/bigoad/bigoadtest/supplemental/invalid_response.json b/adapters/bigoad/bigoadtest/supplemental/invalid_response.json new file mode 100644 index 00000000000..ff910cf095b --- /dev/null +++ b/adapters/bigoad/bigoadtest/supplemental/invalid_response.json @@ -0,0 +1,111 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "app": { + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ], + "bundle": "com.app.awesome", + "name": "Awesome App", + "domain": "awesomeapp.com", + "id": "123456789" + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "sspid": "sspid" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "uri": "https://api.imotech.tech/Ad/GetAdOut?sspid=sspid", + "body": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "some-impression-id", + "banner": { + "w": 320, + "h": 50 + }, + "tagid": "ogTAGID", + "ext": { + "sspid": "sspid" + } + } + ], + "app": { + "id": "123456789", + "name": "Awesome App", + "bundle": "com.app.awesome", + "domain": "awesomeapp.com", + "cat": [ + "IAB22-1" + ], + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + }, + "impIDs": [ + "some-impression-id" + ] + }, + "mockResponse": { + "status": 200, + "body": "" + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Bad server response", + "comparison": "regex" + } + ] +} \ No newline at end of file diff --git a/adapters/bigoad/param_test.go b/adapters/bigoad/param_test.go new file mode 100644 index 00000000000..772bcb77214 --- /dev/null +++ b/adapters/bigoad/param_test.go @@ -0,0 +1,46 @@ +package bigoad + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v3/openrtb_ext" +) + +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json schema. %v", err) + } + + for _, p := range validParams { + if err := validator.Validate(openrtb_ext.BidderBigoAd, json.RawMessage(p)); err != nil { + t.Errorf("Schema rejected valid params: %s", p) + } + } +} + +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json schema. %v", err) + } + + for _, p := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderBigoAd, json.RawMessage(p)); err == nil { + t.Errorf("Schema allowed invalid params: %s", p) + } + } +} + +var validParams = []string{ + `{"sspid": "123"}`, +} + +var invalidParams = []string{ + ``, + `null`, + `[]`, + `{}`, + `{"xxx": "baidu.com"}`, +} diff --git a/adapters/bizzclick/bizzclick_test.go b/adapters/bizzclick/bizzclick_test.go deleted file mode 100644 index 5933ee551a6..00000000000 --- a/adapters/bizzclick/bizzclick_test.go +++ /dev/null @@ -1,28 +0,0 @@ -package bizzclick - -import ( - "testing" - - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/stretchr/testify/assert" -) - -func TestJsonSamples(t *testing.T) { - bidder, buildErr := Builder(openrtb_ext.BidderBizzclick, config.Adapter{ - Endpoint: "http://{{.Host}}.bizzclick.com/bid?rtb_seat_id={{.SourceId}}&secret_key={{.AccountID}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) - - if buildErr != nil { - t.Fatalf("Builder returned unexpected error %v", buildErr) - } - - adapterstest.RunJSONBidderTest(t, "bizzclicktest", bidder) -} - -func TestEndpointTemplateMalformed(t *testing.T) { - _, buildErr := Builder(openrtb_ext.BidderBizzclick, config.Adapter{ - Endpoint: "{{Malformed}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) - - assert.Error(t, buildErr) -} diff --git a/adapters/bizzclick/bizzclick.go b/adapters/blasto/blasto.go similarity index 82% rename from adapters/bizzclick/bizzclick.go rename to adapters/blasto/blasto.go index 40805da0cb0..e9917d08859 100644 --- a/adapters/bizzclick/bizzclick.go +++ b/adapters/blasto/blasto.go @@ -1,4 +1,4 @@ -package bizzclick +package blasto import ( "encoding/json" @@ -7,11 +7,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -60,7 +61,7 @@ func (a *adapter) MakeRequests( requestsToBidder []*adapters.RequestData, errs []error, ) { - bizzclickExt, err := a.getImpressionExt(&openRTBRequest.Imp[0]) + blastoExt, err := a.getImpressionExt(&openRTBRequest.Imp[0]) if err != nil { return nil, []error{err} } @@ -68,7 +69,7 @@ func (a *adapter) MakeRequests( for idx := range openRTBRequest.Imp { openRTBRequest.Imp[idx].Ext = nil } - url, err := a.buildEndpointURL(bizzclickExt) + url, err := a.buildEndpointURL(blastoExt) if err != nil { return nil, []error{err} } @@ -87,33 +88,26 @@ func (a *adapter) MakeRequests( }}, nil } -func (a *adapter) getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtBizzclick, error) { +func (a *adapter) getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtBlasto, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: "ext.bidder not provided", } } - var bizzclickExt openrtb_ext.ExtBizzclick - if err := json.Unmarshal(bidderExt.Bidder, &bizzclickExt); err != nil { + var blastoExt openrtb_ext.ExtBlasto + if err := jsonutil.Unmarshal(bidderExt.Bidder, &blastoExt); err != nil { return nil, &errortypes.BadInput{ Message: "ext.bidder not provided", } } - return &bizzclickExt, nil + return &blastoExt, nil } -func (a *adapter) buildEndpointURL(params *openrtb_ext.ExtBizzclick) (string, error) { - host := "us-e-node1" - if params.Host != "" { - host = params.Host - } +func (a *adapter) buildEndpointURL(params *openrtb_ext.ExtBlasto) (string, error) { sourceId := params.SourceID - if params.SourceID == "" { - sourceId = params.PlacementID - } - endpointParams := macros.EndpointTemplateParams{AccountID: params.AccountID, SourceId: sourceId, Host: host} + endpointParams := macros.EndpointTemplateParams{AccountID: params.AccountID, SourceId: sourceId} return macros.ResolveMacros(a.endpoint, endpointParams) } @@ -158,7 +152,7 @@ func (a *adapter) MakeBids( responseBody := bidderRawResponse.Body var bidResp openrtb2.BidResponse - if err := json.Unmarshal(responseBody, &bidResp); err != nil { + if err := jsonutil.Unmarshal(responseBody, &bidResp); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: "Bad Server Response", }} diff --git a/adapters/blasto/blasto_test.go b/adapters/blasto/blasto_test.go new file mode 100644 index 00000000000..9b09c19ae6a --- /dev/null +++ b/adapters/blasto/blasto_test.go @@ -0,0 +1,28 @@ +package blasto + +import ( + "testing" + + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/stretchr/testify/assert" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderBlasto, config.Adapter{ + Endpoint: "http://t-us.blasto.ai/bid?rtb_seat_id={{.SourceId}}&secret_key={{.AccountID}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "blastotest", bidder) +} + +func TestEndpointTemplateMalformed(t *testing.T) { + _, buildErr := Builder(openrtb_ext.BidderBlasto, config.Adapter{ + Endpoint: "{{Malformed}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + assert.Error(t, buildErr) +} diff --git a/adapters/bizzclick/bizzclicktest/exemplary/banner-app.json b/adapters/blasto/blastotest/exemplary/banner-app.json similarity index 93% rename from adapters/bizzclick/bizzclicktest/exemplary/banner-app.json rename to adapters/blasto/blastotest/exemplary/banner-app.json index 840ed212623..81b8e21fc3b 100644 --- a/adapters/bizzclick/bizzclicktest/exemplary/banner-app.json +++ b/adapters/blasto/blastotest/exemplary/banner-app.json @@ -34,8 +34,7 @@ "ext": { "bidder": { "accountId": "accountId", - "sourceId": "sourceId", - "host": "host" + "sourceId": "sourceId" } } } @@ -61,7 +60,7 @@ "123.123.123.123" ] }, - "uri": "http://host.bizzclick.com/bid?rtb_seat_id=sourceId&secret_key=accountId", + "uri": "http://t-us.blasto.ai/bid?rtb_seat_id=sourceId&secret_key=accountId", "body": { "id": "some-request-id", "device": { @@ -97,7 +96,9 @@ }, "tmax": 1000 }, - "impIDs":["some-impression-id"] + "impIDs": [ + "some-impression-id" + ] }, "mockResponse": { "status": 200, @@ -120,7 +121,7 @@ } ], "type": "banner", - "seat": "bizzclick" + "seat": "blasto" } ], "cur": "USD" diff --git a/adapters/bizzclick/bizzclicktest/exemplary/banner-web.json b/adapters/blasto/blastotest/exemplary/banner-web.json similarity index 92% rename from adapters/bizzclick/bizzclicktest/exemplary/banner-web.json rename to adapters/blasto/blastotest/exemplary/banner-web.json index 21dad82fd12..d971bfa605f 100644 --- a/adapters/bizzclick/bizzclicktest/exemplary/banner-web.json +++ b/adapters/blasto/blastotest/exemplary/banner-web.json @@ -28,8 +28,7 @@ "ext": { "bidder": { "accountId": "accountId", - "sourceId": "sourceId", - "host": "host" + "sourceId": "sourceId" } } }, @@ -43,8 +42,7 @@ "ext": { "bidder": { "accountId": "accountId", - "sourceId": "sourceId", - "host": "host" + "sourceId": "sourceId" } } } @@ -70,7 +68,7 @@ "123.123.123.123" ] }, - "uri": "http://host.bizzclick.com/bid?rtb_seat_id=sourceId&secret_key=accountId", + "uri": "http://t-us.blasto.ai/bid?rtb_seat_id=sourceId&secret_key=accountId", "body": { "id": "some-request-id", "device": { @@ -108,7 +106,10 @@ }, "tmax": 1000 }, - "impIDs":["some-impression-id1","some-impression-id2"] + "impIDs": [ + "some-impression-id1", + "some-impression-id2" + ] }, "mockResponse": { "status": 200, @@ -143,7 +144,7 @@ } ], "type": "banner", - "seat": "bizzclick" + "seat": "blasto" } ], "cur": "USD" diff --git a/adapters/bizzclick/bizzclicktest/exemplary/default-host-param.json b/adapters/blasto/blastotest/exemplary/default-host-param.json similarity index 93% rename from adapters/bizzclick/bizzclicktest/exemplary/default-host-param.json rename to adapters/blasto/blastotest/exemplary/default-host-param.json index a99099092d7..81b8e21fc3b 100644 --- a/adapters/bizzclick/bizzclicktest/exemplary/default-host-param.json +++ b/adapters/blasto/blastotest/exemplary/default-host-param.json @@ -34,7 +34,7 @@ "ext": { "bidder": { "accountId": "accountId", - "placementId": "placementId" + "sourceId": "sourceId" } } } @@ -60,7 +60,7 @@ "123.123.123.123" ] }, - "uri": "http://us-e-node1.bizzclick.com/bid?rtb_seat_id=placementId&secret_key=accountId", + "uri": "http://t-us.blasto.ai/bid?rtb_seat_id=sourceId&secret_key=accountId", "body": { "id": "some-request-id", "device": { @@ -96,7 +96,9 @@ }, "tmax": 1000 }, - "impIDs":["some-impression-id"] + "impIDs": [ + "some-impression-id" + ] }, "mockResponse": { "status": 200, @@ -119,7 +121,7 @@ } ], "type": "banner", - "seat": "bizzclick" + "seat": "blasto" } ], "cur": "USD" diff --git a/adapters/bizzclick/bizzclicktest/exemplary/native-app.json b/adapters/blasto/blastotest/exemplary/native-app.json similarity index 94% rename from adapters/bizzclick/bizzclicktest/exemplary/native-app.json rename to adapters/blasto/blastotest/exemplary/native-app.json index 65fe85085ad..946fa9e0300 100644 --- a/adapters/bizzclick/bizzclicktest/exemplary/native-app.json +++ b/adapters/blasto/blastotest/exemplary/native-app.json @@ -34,8 +34,7 @@ "ext": { "bidder": { "accountId": "accountId", - "sourceId": "sourceId", - "host": "host" + "sourceId": "sourceId" } } } @@ -61,7 +60,7 @@ "123.123.123.123" ] }, - "uri": "http://host.bizzclick.com/bid?rtb_seat_id=sourceId&secret_key=accountId", + "uri": "http://t-us.blasto.ai/bid?rtb_seat_id=sourceId&secret_key=accountId", "body": { "id": "some-request-id", "device": { @@ -97,7 +96,9 @@ }, "tmax": 1000 }, - "impIDs":["some-impression-id"] + "impIDs": [ + "some-impression-id" + ] }, "mockResponse": { "status": 200, @@ -118,7 +119,7 @@ } ], "type": "native", - "seat": "bizzclick" + "seat": "blasto" } ], "cur": "USD" diff --git a/adapters/bizzclick/bizzclicktest/exemplary/native-web.json b/adapters/blasto/blastotest/exemplary/native-web.json similarity index 94% rename from adapters/bizzclick/bizzclicktest/exemplary/native-web.json rename to adapters/blasto/blastotest/exemplary/native-web.json index 0e36975194c..f55da66081e 100644 --- a/adapters/bizzclick/bizzclicktest/exemplary/native-web.json +++ b/adapters/blasto/blastotest/exemplary/native-web.json @@ -28,8 +28,7 @@ "ext": { "bidder": { "accountId": "accountId", - "sourceId": "sourceId", - "host": "host" + "sourceId": "sourceId" } } } @@ -55,7 +54,7 @@ "2607:fb90:f27:4512:d800:cb23:a603:e245" ] }, - "uri": "http://host.bizzclick.com/bid?rtb_seat_id=sourceId&secret_key=accountId", + "uri": "http://t-us.blasto.ai/bid?rtb_seat_id=sourceId&secret_key=accountId", "body": { "id": "some-request-id", "device": { @@ -85,7 +84,9 @@ }, "tmax": 1000 }, - "impIDs":["some-impression-id"] + "impIDs": [ + "some-impression-id" + ] }, "mockResponse": { "status": 200, @@ -105,7 +106,7 @@ "crid": "20" } ], - "seat": "bizzclick" + "seat": "blasto" } ], "cur": "USD" diff --git a/adapters/bizzclick/bizzclicktest/exemplary/video-app.json b/adapters/blasto/blastotest/exemplary/video-app.json similarity index 93% rename from adapters/bizzclick/bizzclicktest/exemplary/video-app.json rename to adapters/blasto/blastotest/exemplary/video-app.json index 9c16795230a..64606f73b0d 100644 --- a/adapters/bizzclick/bizzclicktest/exemplary/video-app.json +++ b/adapters/blasto/blastotest/exemplary/video-app.json @@ -39,8 +39,7 @@ "ext": { "bidder": { "accountId": "accountId", - "sourceId": "sourceId", - "host": "host" + "sourceId": "sourceId" } } } @@ -66,7 +65,7 @@ "123.123.123.123" ] }, - "uri": "http://host.bizzclick.com/bid?rtb_seat_id=sourceId&secret_key=accountId", + "uri": "http://t-us.blasto.ai/bid?rtb_seat_id=sourceId&secret_key=accountId", "body": { "id": "some-request-id", "device": { @@ -107,7 +106,9 @@ }, "tmax": 1000 }, - "impIDs":["some-impression-id"] + "impIDs": [ + "some-impression-id" + ] }, "mockResponse": { "status": 200, @@ -129,7 +130,7 @@ "h": 720 } ], - "seat": "bizzclick" + "seat": "blasto" } ], "cur": "USD" diff --git a/adapters/bizzclick/bizzclicktest/exemplary/video-web.json b/adapters/blasto/blastotest/exemplary/video-web.json similarity index 93% rename from adapters/bizzclick/bizzclicktest/exemplary/video-web.json rename to adapters/blasto/blastotest/exemplary/video-web.json index 9410fdb78df..2904880889c 100644 --- a/adapters/bizzclick/bizzclicktest/exemplary/video-web.json +++ b/adapters/blasto/blastotest/exemplary/video-web.json @@ -33,8 +33,7 @@ "ext": { "bidder": { "accountId": "accountId", - "sourceId": "sourceId", - "host": "host" + "sourceId": "sourceId" } } } @@ -60,7 +59,7 @@ "123.123.123.123" ] }, - "uri": "http://host.bizzclick.com/bid?rtb_seat_id=sourceId&secret_key=accountId", + "uri": "http://t-us.blasto.ai/bid?rtb_seat_id=sourceId&secret_key=accountId", "body": { "id": "some-request-id", "device": { @@ -95,7 +94,9 @@ }, "tmax": 1000 }, - "impIDs":["some-impression-id"] + "impIDs": [ + "some-impression-id" + ] }, "mockResponse": { "status": 200, @@ -122,7 +123,7 @@ } } ], - "seat": "bizzclick" + "seat": "blasto" } ], "cur": "USD" diff --git a/adapters/bizzclick/bizzclicktest/supplemental/empty-seatbid-array.json b/adapters/blasto/blastotest/supplemental/empty-seatbid-array.json similarity index 93% rename from adapters/bizzclick/bizzclicktest/supplemental/empty-seatbid-array.json rename to adapters/blasto/blastotest/supplemental/empty-seatbid-array.json index 40aa5374504..9bb5ebda566 100644 --- a/adapters/bizzclick/bizzclicktest/supplemental/empty-seatbid-array.json +++ b/adapters/blasto/blastotest/supplemental/empty-seatbid-array.json @@ -39,8 +39,7 @@ "ext": { "bidder": { "accountId": "accountId", - "sourceId": "sourceId", - "host": "host" + "sourceId": "sourceId" } } } @@ -66,7 +65,7 @@ "123.123.123.123" ] }, - "uri": "http://host.bizzclick.com/bid?rtb_seat_id=sourceId&secret_key=accountId", + "uri": "http://t-us.blasto.ai/bid?rtb_seat_id=sourceId&secret_key=accountId", "body": { "id": "some-request-id", "device": { @@ -107,7 +106,9 @@ }, "tmax": 1000 }, - "impIDs":["some-impression-id"] + "impIDs": [ + "some-impression-id" + ] }, "mockResponse": { "status": 200, diff --git a/adapters/bizzclick/bizzclicktest/supplemental/invalid-bizzclick-ext-object.json b/adapters/blasto/blastotest/supplemental/invalid-blasto-ext-object.json similarity index 100% rename from adapters/bizzclick/bizzclicktest/supplemental/invalid-bizzclick-ext-object.json rename to adapters/blasto/blastotest/supplemental/invalid-blasto-ext-object.json diff --git a/adapters/bizzclick/bizzclicktest/supplemental/invalid-response.json b/adapters/blasto/blastotest/supplemental/invalid-response.json similarity index 92% rename from adapters/bizzclick/bizzclicktest/supplemental/invalid-response.json rename to adapters/blasto/blastotest/supplemental/invalid-response.json index 4808f4823ee..620e95148a8 100644 --- a/adapters/bizzclick/bizzclicktest/supplemental/invalid-response.json +++ b/adapters/blasto/blastotest/supplemental/invalid-response.json @@ -34,8 +34,7 @@ "ext": { "bidder": { "accountId": "accountId", - "sourceId": "sourceId", - "host": "host" + "sourceId": "sourceId" } } } @@ -61,7 +60,7 @@ "123.123.123.123" ] }, - "uri": "http://host.bizzclick.com/bid?rtb_seat_id=sourceId&secret_key=accountId", + "uri": "http://t-us.blasto.ai/bid?rtb_seat_id=sourceId&secret_key=accountId", "body": { "id": "some-request-id", "device": { @@ -97,7 +96,9 @@ }, "tmax": 1000 }, - "impIDs":["some-impression-id"] + "impIDs": [ + "some-impression-id" + ] }, "mockResponse": { "status": 200, diff --git a/adapters/bizzclick/bizzclicktest/supplemental/status-code-bad-request.json b/adapters/blasto/blastotest/supplemental/status-code-bad-request.json similarity index 90% rename from adapters/bizzclick/bizzclicktest/supplemental/status-code-bad-request.json rename to adapters/blasto/blastotest/supplemental/status-code-bad-request.json index b274c758856..df55900b99d 100644 --- a/adapters/bizzclick/bizzclicktest/supplemental/status-code-bad-request.json +++ b/adapters/blasto/blastotest/supplemental/status-code-bad-request.json @@ -33,8 +33,7 @@ "ext": { "bidder": { "accountId": "accountId", - "sourceId": "sourceId", - "host": "host" + "sourceId": "sourceId" } } } @@ -43,7 +42,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "http://host.bizzclick.com/bid?rtb_seat_id=sourceId&secret_key=accountId", + "uri": "http://t-us.blasto.ai/bid?rtb_seat_id=sourceId&secret_key=accountId", "body": { "id": "some-request-id", "imp": [ @@ -78,7 +77,9 @@ }, "tmax": 1000 }, - "impIDs":["some-impression-id"] + "impIDs": [ + "some-impression-id" + ] }, "mockResponse": { "status": 400 diff --git a/adapters/bizzclick/bizzclicktest/supplemental/status-code-no-content.json b/adapters/blasto/blastotest/supplemental/status-code-no-content.json similarity index 88% rename from adapters/bizzclick/bizzclicktest/supplemental/status-code-no-content.json rename to adapters/blasto/blastotest/supplemental/status-code-no-content.json index 6163a4af0dd..f59c785b218 100644 --- a/adapters/bizzclick/bizzclicktest/supplemental/status-code-no-content.json +++ b/adapters/blasto/blastotest/supplemental/status-code-no-content.json @@ -27,8 +27,7 @@ "ext": { "bidder": { "accountId": "accountId", - "sourceId": "sourceId", - "host": "host" + "sourceId": "sourceId" } } } @@ -37,7 +36,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "http://host.bizzclick.com/bid?rtb_seat_id=sourceId&secret_key=accountId", + "uri": "http://t-us.blasto.ai/bid?rtb_seat_id=sourceId&secret_key=accountId", "body": { "id": "some-request-id", "imp": [ @@ -66,7 +65,9 @@ }, "tmax": 1000 }, - "impIDs":["some-impression-id"] + "impIDs": [ + "some-impression-id" + ] }, "mockResponse": { "status": 204 diff --git a/adapters/bizzclick/bizzclicktest/supplemental/status-code-other-error.json b/adapters/blasto/blastotest/supplemental/status-code-other-error.json similarity index 89% rename from adapters/bizzclick/bizzclicktest/supplemental/status-code-other-error.json rename to adapters/blasto/blastotest/supplemental/status-code-other-error.json index af2a91110d2..c58e935a3e6 100644 --- a/adapters/bizzclick/bizzclicktest/supplemental/status-code-other-error.json +++ b/adapters/blasto/blastotest/supplemental/status-code-other-error.json @@ -27,8 +27,7 @@ "ext": { "bidder": { "accountId": "accountId", - "sourceId": "sourceId", - "host": "host" + "sourceId": "sourceId" } } } @@ -37,7 +36,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "http://host.bizzclick.com/bid?rtb_seat_id=sourceId&secret_key=accountId", + "uri": "http://t-us.blasto.ai/bid?rtb_seat_id=sourceId&secret_key=accountId", "body": { "id": "some-request-id", "imp": [ @@ -66,7 +65,9 @@ }, "tmax": 1000 }, - "impIDs":["some-impression-id"] + "impIDs": [ + "some-impression-id" + ] }, "mockResponse": { "status": 306 diff --git a/adapters/bizzclick/bizzclicktest/supplemental/status-code-service-unavailable.json b/adapters/blasto/blastotest/supplemental/status-code-service-unavailable.json similarity index 89% rename from adapters/bizzclick/bizzclicktest/supplemental/status-code-service-unavailable.json rename to adapters/blasto/blastotest/supplemental/status-code-service-unavailable.json index d4c0fa392c8..d1bbba75afb 100644 --- a/adapters/bizzclick/bizzclicktest/supplemental/status-code-service-unavailable.json +++ b/adapters/blasto/blastotest/supplemental/status-code-service-unavailable.json @@ -27,8 +27,7 @@ "ext": { "bidder": { "accountId": "accountId", - "sourceId": "sourceId", - "host": "host" + "sourceId": "sourceId" } } } @@ -37,7 +36,7 @@ "httpCalls": [ { "expectedRequest": { - "uri": "http://host.bizzclick.com/bid?rtb_seat_id=sourceId&secret_key=accountId", + "uri": "http://t-us.blasto.ai/bid?rtb_seat_id=sourceId&secret_key=accountId", "body": { "id": "some-request-id", "imp": [ @@ -66,7 +65,9 @@ }, "tmax": 1000 }, - "impIDs":["some-impression-id"] + "impIDs": [ + "some-impression-id" + ] }, "mockResponse": { "status": 503 diff --git a/adapters/bizzclick/params_test.go b/adapters/blasto/params_test.go similarity index 67% rename from adapters/bizzclick/params_test.go rename to adapters/blasto/params_test.go index fe72e41f16b..c23f162d036 100644 --- a/adapters/bizzclick/params_test.go +++ b/adapters/blasto/params_test.go @@ -1,14 +1,14 @@ -package bizzclick +package blasto import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) var validParams = []string{ - `{ "host": "ep1", "sourceId": "partner", "accountId": "hash" }`, + `{ "sourceId": "partner", "accountId": "hash" }`, } func TestValidParams(t *testing.T) { @@ -18,8 +18,8 @@ func TestValidParams(t *testing.T) { } for _, validParam := range validParams { - if err := validator.Validate(openrtb_ext.BidderBizzclick, json.RawMessage(validParam)); err != nil { - t.Errorf("Schema rejected Bizzclick params: %s", validParam) + if err := validator.Validate(openrtb_ext.BidderBlasto, json.RawMessage(validParam)); err != nil { + t.Errorf("Schema rejected Blasto params: %s", validParam) } } } @@ -43,7 +43,7 @@ func TestInvalidParams(t *testing.T) { } for _, invalidParam := range invalidParams { - if err := validator.Validate(openrtb_ext.BidderBizzclick, json.RawMessage(invalidParam)); err == nil { + if err := validator.Validate(openrtb_ext.BidderBlasto, json.RawMessage(invalidParam)); err == nil { t.Errorf("Schema allowed unexpected params: %s", invalidParam) } } diff --git a/adapters/bliink/bliink.go b/adapters/bliink/bliink.go index 51463698597..900c1de7ee2 100644 --- a/adapters/bliink/bliink.go +++ b/adapters/bliink/bliink.go @@ -7,10 +7,11 @@ import ( "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -68,7 +69,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, _ *adapters.RequestData } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } diff --git a/adapters/bliink/bliink_test.go b/adapters/bliink/bliink_test.go index 02cafb37a4b..d5fa3aa58e5 100644 --- a/adapters/bliink/bliink_test.go +++ b/adapters/bliink/bliink_test.go @@ -3,9 +3,9 @@ package bliink import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/bliink/params_test.go b/adapters/bliink/params_test.go index d1066e8c4ed..646ab96e4ce 100644 --- a/adapters/bliink/params_test.go +++ b/adapters/bliink/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/blue/blue.go b/adapters/blue/blue.go index 127adf136c3..08b5167dd03 100644 --- a/adapters/blue/blue.go +++ b/adapters/blue/blue.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -66,7 +67,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } diff --git a/adapters/blue/blue_test.go b/adapters/blue/blue_test.go index 695984a3383..696d855d6a1 100644 --- a/adapters/blue/blue_test.go +++ b/adapters/blue/blue_test.go @@ -3,9 +3,9 @@ package blue import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestBidderBlue(t *testing.T) { diff --git a/adapters/blue/bluetest/supplemental/bad_response.json b/adapters/blue/bluetest/supplemental/bad_response.json index c45d6b84517..c239a50f972 100644 --- a/adapters/blue/bluetest/supplemental/bad_response.json +++ b/adapters/blue/bluetest/supplemental/bad_response.json @@ -51,7 +51,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/bluesea/bluesea.go b/adapters/bluesea/bluesea.go index 2e8d50b6e08..0428b22b6c0 100644 --- a/adapters/bluesea/bluesea.go +++ b/adapters/bluesea/bluesea.go @@ -7,10 +7,11 @@ import ( "net/url" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -82,14 +83,14 @@ func extraImpExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpBluesea, error) { var impExt adapters.ExtImpBidder var blueseaImpExt openrtb_ext.ExtImpBluesea - err := json.Unmarshal(imp.Ext, &impExt) + err := jsonutil.Unmarshal(imp.Ext, &impExt) if err != nil { return nil, &errortypes.BadInput{ Message: fmt.Sprintf("Error in parsing imp.ext. err = %v, imp.ext = %v", err.Error(), string(imp.Ext)), } } - err = json.Unmarshal(impExt.Bidder, &blueseaImpExt) + err = jsonutil.Unmarshal(impExt.Bidder, &blueseaImpExt) if err != nil { return nil, &errortypes.BadInput{ Message: fmt.Sprintf("Error in parsing imp.ext.bidder. err = %v, bidder = %v", err.Error(), string(impExt.Bidder)), @@ -114,7 +115,7 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest } var blueseaResponse openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &blueseaResponse); err != nil { + if err := jsonutil.Unmarshal(response.Body, &blueseaResponse); err != nil { return nil, []error{fmt.Errorf("Error in parsing bidresponse body")} } @@ -145,7 +146,7 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest func getMediaTypeForBid(bid *openrtb2.Bid) (openrtb_ext.BidType, error) { var bidExt blueseaBidExt - if err := json.Unmarshal(bid.Ext, &bidExt); err != nil { + if err := jsonutil.Unmarshal(bid.Ext, &bidExt); err != nil { return "", fmt.Errorf("Error in parsing bid.ext") } diff --git a/adapters/bluesea/bluesea_test.go b/adapters/bluesea/bluesea_test.go index 8bfe42ce150..2d0b5bdaca5 100644 --- a/adapters/bluesea/bluesea_test.go +++ b/adapters/bluesea/bluesea_test.go @@ -3,9 +3,9 @@ package bluesea import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/bluesea/blueseatest/exemplary/site-banner.json b/adapters/bluesea/blueseatest/exemplary/site-banner.json new file mode 100644 index 00000000000..b3ca13f8d53 --- /dev/null +++ b/adapters/bluesea/blueseatest/exemplary/site-banner.json @@ -0,0 +1,133 @@ +{ + "mockBidRequest":{ + "id":"b655d86c-fdf6-4e68-a1e9-abc223f84a65", + "site":{ + "id": "100", + "domain": "test.domain", + "page": "https://test.domain?target=_blank", + "keywords": "fashion" + }, + "imp":[ + { + "id":"1", + "banner":{ + "w":300, + "h":250 + }, + "secure":1, + "ext":{ + "bidder":{ + "pubid":"test-pubid", + "token":"test-pub-token" + } + } + } + ], + "device":{ + "os":"android", + "ua":"Mozilla/5.0 (Linux; Android 8.0.0; SC-04J Build/R16NW; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/113.0.5672.162 Mobile Safari/537.36", + "ip":"101.101.101.101", + "h":1280, + "w":720 + }, + "at":1, + "tmax":1200, + "test":1 + }, + "httpCalls":[ + { + "expectedRequest":{ + "uri":"https://test.prebid.bluesea?pubid=test-pubid&token=test-pub-token", + "body":{ + "id":"b655d86c-fdf6-4e68-a1e9-abc223f84a65", + "site":{ + "id":"100", + "domain": "test.domain", + "page": "https://test.domain?target=_blank", + "keywords": "fashion" + }, + "imp":[ + { + "id":"1", + "banner":{ + "w":300, + "h":250 + }, + "secure":1, + "ext":{ + "bidder":{ + "pubid":"test-pubid", + "token":"test-pub-token" + } + } + } + ], + "device":{ + "os":"android", + "ua":"Mozilla/5.0 (Linux; Android 8.0.0; SC-04J Build/R16NW; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/113.0.5672.162 Mobile Safari/537.36", + "ip":"101.101.101.101", + "h":1280, + "w":720 + }, + "at":1, + "tmax":1200, + "test":1 + }, + "impIDs":["1"] + }, + "mockResponse":{ + "status":200, + "body":{ + "id":"b655d86c-fdf6-4e68-a1e9-abc223f84a65", + "seatbid":[ + { + "bid":[ + { + "price":0.01, + "adm":"test-adm", + "impid":"1", + "id":"test-bid-id", + "h":250, + "adomain":[ + "adv.com" + ], + "crid":"test-site-crid", + "w":300, + "ext":{ + "mediatype":"banner" + } + } + ], + "seat":"test-seat" + } + ], + "cur":"USD" + } + } + } + ], + "expectedBidResponses":[ + { + "bids":[ + { + "bid":{ + "price":0.01, + "adm":"test-adm", + "impid":"1", + "id":"test-bid-id", + "h":250, + "adomain":[ + "adv.com" + ], + "crid":"test-site-crid", + "w":300, + "ext":{ + "mediatype":"banner" + } + }, + "type":"banner" + } + ] + } + ] +} diff --git a/adapters/bluesea/blueseatest/exemplary/site-native.json b/adapters/bluesea/blueseatest/exemplary/site-native.json new file mode 100644 index 00000000000..b907ebdbea4 --- /dev/null +++ b/adapters/bluesea/blueseatest/exemplary/site-native.json @@ -0,0 +1,133 @@ +{ + "mockBidRequest":{ + "id":"b655d86c-fdf6-4e68-a1e9-abc223f84a65", + "site":{ + "id": "100", + "domain": "test.domain", + "page": "https://test.domain?target=_blank", + "keywords": "fashion" + }, + "imp":[ + { + "id":"1", + "native":{ + "request":"{\"ver\":\"1.2\",\"context\":1,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":150}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":100,\"hmin\":100}},{\"id\":3,\"required\":1,\"data\":{\"type\":2,\"len\":120}}]}", + "ver":"1.2" + }, + "secure":1, + "ext":{ + "bidder":{ + "pubid":"test-pubid", + "token":"test-pub-token" + } + } + } + ], + "device":{ + "os":"android", + "ua":"Mozilla/5.0 (Linux; Android 8.0.0; SC-04J Build/R16NW; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/113.0.5672.162 Mobile Safari/537.36", + "ip":"101.101.101.101", + "h":1280, + "w":720 + }, + "at":1, + "tmax":1200, + "test":1 + }, + "httpCalls":[ + { + "expectedRequest":{ + "uri":"https://test.prebid.bluesea?pubid=test-pubid&token=test-pub-token", + "body":{ + "id":"b655d86c-fdf6-4e68-a1e9-abc223f84a65", + "site":{ + "id":"100", + "domain": "test.domain", + "page": "https://test.domain?target=_blank", + "keywords": "fashion" + }, + "imp":[ + { + "id":"1", + "native":{ + "request":"{\"ver\":\"1.2\",\"context\":1,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":150}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":100,\"hmin\":100}},{\"id\":3,\"required\":1,\"data\":{\"type\":2,\"len\":120}}]}", + "ver":"1.2" + }, + "secure":1, + "ext":{ + "bidder":{ + "pubid":"test-pubid", + "token":"test-pub-token" + } + } + } + ], + "device":{ + "os":"android", + "ua":"Mozilla/5.0 (Linux; Android 8.0.0; SC-04J Build/R16NW; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/113.0.5672.162 Mobile Safari/537.36", + "ip":"101.101.101.101", + "h":1280, + "w":720 + }, + "at":1, + "tmax":1200, + "test":1 + }, + "impIDs":["1"] + }, + "mockResponse":{ + "status":200, + "body":{ + "id":"b655d86c-fdf6-4e68-a1e9-abc223f84a65", + "seatbid":[ + { + "bid":[ + { + "price":0.01, + "adm":"test-native-adm", + "impid":"1", + "id":"test-bid-id", + "h":250, + "adomain":[ + "adv.com" + ], + "crid":"test-site-native-crid", + "w":300, + "ext":{ + "mediatype":"native" + } + } + ], + "seat":"test-seat" + } + ], + "cur":"USD" + } + } + } + ], + "expectedBidResponses":[ + { + "bids":[ + { + "bid":{ + "price":0.01, + "adm":"test-native-adm", + "impid":"1", + "id":"test-bid-id", + "h":250, + "adomain":[ + "adv.com" + ], + "crid":"test-site-native-crid", + "w":300, + "ext":{ + "mediatype":"native" + } + }, + "type":"native" + } + ] + } + ] +} diff --git a/adapters/bluesea/blueseatest/exemplary/site-video.json b/adapters/bluesea/blueseatest/exemplary/site-video.json new file mode 100644 index 00000000000..dd191105cd3 --- /dev/null +++ b/adapters/bluesea/blueseatest/exemplary/site-video.json @@ -0,0 +1,163 @@ +{ + "mockBidRequest":{ + "id":"b655d86c-fdf6-4e68-a1e9-abc223f84a65", + "site":{ + "id": "100", + "domain": "test.domain", + "page": "https://test.domain?target=_blank", + "keywords": "fashion" + }, + "imp":[ + { + "id":"1", + "video":{ + "mimes":[ + "video/mp4", + "application/javascript", + "video/webm" + ], + "minduration":5, + "maxduration":120, + "protocols":[ + 2, + 3, + 5, + 6 + ], + "pos":7, + "w":320, + "h":480, + "linearity":1 + }, + "secure":1, + "ext":{ + "bidder":{ + "pubid":"test-pubid", + "token":"test-pub-token" + } + } + } + ], + "device":{ + "os":"android", + "ua":"Mozilla/5.0 (Linux; Android 8.0.0; SC-04J Build/R16NW; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/113.0.5672.162 Mobile Safari/537.36", + "ip":"101.101.101.101", + "h":1280, + "w":720 + }, + "at":1, + "tmax":1200, + "test":1 + }, + "httpCalls":[ + { + "expectedRequest":{ + "uri":"https://test.prebid.bluesea?pubid=test-pubid&token=test-pub-token", + "body":{ + "id":"b655d86c-fdf6-4e68-a1e9-abc223f84a65", + "site":{ + "id":"100", + "domain": "test.domain", + "page": "https://test.domain?target=_blank", + "keywords": "fashion" + }, + "imp":[ + { + "id":"1", + "video":{ + "mimes":[ + "video/mp4", + "application/javascript", + "video/webm" + ], + "minduration":5, + "maxduration":120, + "protocols":[ + 2, + 3, + 5, + 6 + ], + "pos":7, + "w":320, + "h":480, + "linearity":1 + }, + "secure":1, + "ext":{ + "bidder":{ + "pubid":"test-pubid", + "token":"test-pub-token" + } + } + } + ], + "device":{ + "os":"android", + "ua":"Mozilla/5.0 (Linux; Android 8.0.0; SC-04J Build/R16NW; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/113.0.5672.162 Mobile Safari/537.36", + "ip":"101.101.101.101", + "h":1280, + "w":720 + }, + "at":1, + "tmax":1200, + "test":1 + }, + "impIDs":["1"] + }, + "mockResponse":{ + "status":200, + "body":{ + "id":"b655d86c-fdf6-4e68-a1e9-abc223f84a65", + "seatbid":[ + { + "bid":[ + { + "price":0.01, + "adm":"test-vast", + "impid":"1", + "id":"test-bid-id", + "h":480, + "adomain":[ + "adv.com" + ], + "crid":"test-site-crid", + "w":320, + "ext":{ + "mediatype":"video" + } + } + ], + "seat":"test-seat" + } + ], + "cur":"USD" + } + } + } + ], + "expectedBidResponses":[ + { + "bids":[ + { + "bid":{ + "price":0.01, + "adm":"test-vast", + "impid":"1", + "id":"test-bid-id", + "h":480, + "adomain":[ + "adv.com" + ], + "crid":"test-site-crid", + "w":320, + "ext":{ + "mediatype":"video" + } + }, + "type":"video" + } + ] + } + ] +} diff --git a/adapters/bluesea/params_test.go b/adapters/bluesea/params_test.go index e1f7661ac09..79d15d0baa9 100644 --- a/adapters/bluesea/params_test.go +++ b/adapters/bluesea/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // TestValidParams makes sure that the bluesea schema accepts all imp.ext fields which we intend to support. diff --git a/adapters/bmtm/brightmountainmedia.go b/adapters/bmtm/brightmountainmedia.go index 068021ff337..6f48df6d4de 100644 --- a/adapters/bmtm/brightmountainmedia.go +++ b/adapters/bmtm/brightmountainmedia.go @@ -7,10 +7,11 @@ import ( "strconv" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -48,14 +49,14 @@ func (a *adapter) makeRequest(ortbRequest openrtb2.BidRequest, ortbImp openrtb2. } var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(ortbImp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(ortbImp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: fmt.Sprintf("Error unmarshalling ExtImpBidder: %s", err.Error()), } } var bmtmExt openrtb_ext.ImpExtBmtm - if err := json.Unmarshal(bidderExt.Bidder, &bmtmExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &bmtmExt); err != nil { return nil, &errortypes.BadInput{ Message: fmt.Sprintf("Error unmarshalling ExtImpBmtm: %s", err.Error()), } @@ -99,7 +100,7 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } diff --git a/adapters/bmtm/brightmountainmedia_test.go b/adapters/bmtm/brightmountainmedia_test.go index f98cbde0063..28af575c572 100644 --- a/adapters/bmtm/brightmountainmedia_test.go +++ b/adapters/bmtm/brightmountainmedia_test.go @@ -3,9 +3,9 @@ package bmtm import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/bmtm/params_test.go b/adapters/bmtm/params_test.go index d4a07e5a294..f6f8b6105e7 100644 --- a/adapters/bmtm/params_test.go +++ b/adapters/bmtm/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/boldwin/boldwin.go b/adapters/boldwin/boldwin.go index 48de29f3ce2..2dbb1454287 100644 --- a/adapters/boldwin/boldwin.go +++ b/adapters/boldwin/boldwin.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -44,10 +45,10 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E var bidderExt adapters.ExtImpBidder var boldwinExt openrtb_ext.ImpExtBoldwin - if err = json.Unmarshal(reqCopy.Imp[0].Ext, &bidderExt); err != nil { + if err = jsonutil.Unmarshal(reqCopy.Imp[0].Ext, &bidderExt); err != nil { return nil, []error{err} } - if err = json.Unmarshal(bidderExt.Bidder, &boldwinExt); err != nil { + if err = jsonutil.Unmarshal(bidderExt.Bidder, &boldwinExt); err != nil { return nil, []error{err} } @@ -111,7 +112,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } diff --git a/adapters/boldwin/boldwin_test.go b/adapters/boldwin/boldwin_test.go index a8921a9d27f..1a270fcfe9e 100644 --- a/adapters/boldwin/boldwin_test.go +++ b/adapters/boldwin/boldwin_test.go @@ -3,9 +3,9 @@ package boldwin import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/boldwin/boldwintest/supplemental/bad_response.json b/adapters/boldwin/boldwintest/supplemental/bad_response.json index 231a089d2ae..c046bd11674 100644 --- a/adapters/boldwin/boldwintest/supplemental/bad_response.json +++ b/adapters/boldwin/boldwintest/supplemental/bad_response.json @@ -78,7 +78,7 @@ }], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/boldwin/params_test.go b/adapters/boldwin/params_test.go index 2cef0d59cd6..627af2418f1 100644 --- a/adapters/boldwin/params_test.go +++ b/adapters/boldwin/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/brave/brave.go b/adapters/brave/brave.go index a641314813a..4cca024f43c 100755 --- a/adapters/brave/brave.go +++ b/adapters/brave/brave.go @@ -7,11 +7,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -67,13 +68,13 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte func (a *adapter) getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpBrave, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: "ext.bidder not provided", } } var braveExt openrtb_ext.ExtImpBrave - if err := json.Unmarshal(bidderExt.Bidder, &braveExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &braveExt); err != nil { return nil, &errortypes.BadInput{ Message: "ext.bidder not provided", } @@ -118,7 +119,7 @@ func (a *adapter) MakeBids( } var bidResponse openrtb2.BidResponse - if err := json.Unmarshal(bidderResponse.Body, &bidResponse); err != nil { + if err := jsonutil.Unmarshal(bidderResponse.Body, &bidResponse); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: "Bad Server Response", }} diff --git a/adapters/brave/brave_test.go b/adapters/brave/brave_test.go index e4f58252425..a1ea0cd70de 100644 --- a/adapters/brave/brave_test.go +++ b/adapters/brave/brave_test.go @@ -3,9 +3,9 @@ package brave import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/brave/params_test.go b/adapters/brave/params_test.go index c4bcd99959b..fd0a6f8c633 100644 --- a/adapters/brave/params_test.go +++ b/adapters/brave/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/bwx/bwx.go b/adapters/bwx/bwx.go index baa80498347..55e64a05c25 100644 --- a/adapters/bwx/bwx.go +++ b/adapters/bwx/bwx.go @@ -7,11 +7,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type bidType struct { @@ -41,14 +42,14 @@ func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server co func (a *adapter) buildEndpointFromRequest(imp *openrtb2.Imp) (string, error) { var impExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &impExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &impExt); err != nil { return "", &errortypes.BadInput{ Message: fmt.Sprintf("Failed to deserialize bidder impression extension: %v", err), } } var boldwinxExt openrtb_ext.ExtBWX - if err := json.Unmarshal(impExt.Bidder, &boldwinxExt); err != nil { + if err := jsonutil.Unmarshal(impExt.Bidder, &boldwinxExt); err != nil { return "", &errortypes.BadInput{ Message: fmt.Sprintf("Failed to deserialize BoldwinX extension: %v", err), } @@ -110,7 +111,7 @@ func (a *adapter) MakeBids(openRTBRequest *openrtb2.BidRequest, requestToBidder } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(bidderRawResponse.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(bidderRawResponse.Body, &bidResp); err != nil { return nil, []error{err} } diff --git a/adapters/bwx/bwx_test.go b/adapters/bwx/bwx_test.go index 4e984008cec..10246ee8a81 100644 --- a/adapters/bwx/bwx_test.go +++ b/adapters/bwx/bwx_test.go @@ -3,9 +3,9 @@ package bwx import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/bwx/bwxtest/supplemental/bad-response.json b/adapters/bwx/bwxtest/supplemental/bad-response.json index 8a26dc6409f..b75b2069abe 100644 --- a/adapters/bwx/bwxtest/supplemental/bad-response.json +++ b/adapters/bwx/bwxtest/supplemental/bad-response.json @@ -99,7 +99,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ], diff --git a/adapters/bwx/bwxtest/supplemental/invalid-ext-bidder-object.json b/adapters/bwx/bwxtest/supplemental/invalid-ext-bidder-object.json index ed081b7912b..4a4c06e2bd3 100644 --- a/adapters/bwx/bwxtest/supplemental/invalid-ext-bidder-object.json +++ b/adapters/bwx/bwxtest/supplemental/invalid-ext-bidder-object.json @@ -42,7 +42,7 @@ "httpCalls": [], "expectedMakeRequestsErrors": [ { - "value": "Failed to deserialize BoldwinX extension: json: cannot unmarshal array into Go value of type openrtb_ext.ExtBWX", + "value": "Failed to deserialize BoldwinX extension: expect { or n, but found [", "comparison": "literal" } ] diff --git a/adapters/bwx/bwxtest/supplemental/invalid-ext-object.json b/adapters/bwx/bwxtest/supplemental/invalid-ext-object.json index aa215eb3e34..16cf58bbe54 100644 --- a/adapters/bwx/bwxtest/supplemental/invalid-ext-object.json +++ b/adapters/bwx/bwxtest/supplemental/invalid-ext-object.json @@ -40,7 +40,7 @@ "httpCalls": [], "expectedMakeRequestsErrors": [ { - "value": "Failed to deserialize bidder impression extension: json: cannot unmarshal string into Go value of type adapters.ExtImpBidder", + "value": "Failed to deserialize bidder impression extension: expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/bwx/params_test.go b/adapters/bwx/params_test.go index f51d863033f..515fbd5073e 100644 --- a/adapters/bwx/params_test.go +++ b/adapters/bwx/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/cadent_aperture_mx/cadent_aperture_mxtest/supplemental/invalid-response-unmarshall-error.json b/adapters/cadent_aperture_mx/cadent_aperture_mxtest/supplemental/invalid-response-unmarshall-error.json index 5a48518513f..904f54de283 100644 --- a/adapters/cadent_aperture_mx/cadent_aperture_mxtest/supplemental/invalid-response-unmarshall-error.json +++ b/adapters/cadent_aperture_mx/cadent_aperture_mxtest/supplemental/invalid-response-unmarshall-error.json @@ -62,8 +62,8 @@ "expectedMakeBidsErrors": [ { - "value": "Unable to unpackage bid response\\. Error: json: cannot unmarshal string into Go struct field (Bid\\.seatbid\\.bid\\.w|Bid\\.w) of type int64", - "comparison": "regex" + "value": "Unable to unpackage bid response. Error: cannot unmarshal openrtb2.Bid.W: unexpected character", + "comparison": "startswith" } ] } diff --git a/adapters/cadent_aperture_mx/cadentaperturemx.go b/adapters/cadent_aperture_mx/cadentaperturemx.go index ae191469a27..58902bad551 100644 --- a/adapters/cadent_aperture_mx/cadentaperturemx.go +++ b/adapters/cadent_aperture_mx/cadentaperturemx.go @@ -11,10 +11,11 @@ import ( "github.com/prebid/openrtb/v20/adcom1" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -84,14 +85,14 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E func unpackImpExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpCadentApertureMX, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: err.Error(), } } var cadentExt openrtb_ext.ExtImpCadentApertureMX - if err := json.Unmarshal(bidderExt.Bidder, &cadentExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &cadentExt); err != nil { return nil, &errortypes.BadInput{ Message: fmt.Sprintf("ignoring imp id=%s, invalid ImpExt", imp.ID), } @@ -267,7 +268,7 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: fmt.Sprintf("Unable to unpackage bid response. Error: %s", err.Error()), }} diff --git a/adapters/cadent_aperture_mx/cadentaperturemx_test.go b/adapters/cadent_aperture_mx/cadentaperturemx_test.go index 961459a2ea8..7a951555d0b 100644 --- a/adapters/cadent_aperture_mx/cadentaperturemx_test.go +++ b/adapters/cadent_aperture_mx/cadentaperturemx_test.go @@ -3,10 +3,10 @@ package cadentaperturemx import ( "testing" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/cadent_aperture_mx/params_test.go b/adapters/cadent_aperture_mx/params_test.go index 6691537d02c..d505bd8329c 100644 --- a/adapters/cadent_aperture_mx/params_test.go +++ b/adapters/cadent_aperture_mx/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/ccx/ccx.go b/adapters/ccx/ccx.go index eb9e3597265..64bb599afda 100644 --- a/adapters/ccx/ccx.go +++ b/adapters/ccx/ccx.go @@ -6,11 +6,12 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -62,7 +63,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } diff --git a/adapters/ccx/ccx_test.go b/adapters/ccx/ccx_test.go index 86f85dc6eb7..de095d72598 100644 --- a/adapters/ccx/ccx_test.go +++ b/adapters/ccx/ccx_test.go @@ -3,9 +3,9 @@ package ccx import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/ccx/params_test.go b/adapters/ccx/params_test.go index cb500fec509..ff600fada16 100644 --- a/adapters/ccx/params_test.go +++ b/adapters/ccx/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/cointraffic/cointraffic.go b/adapters/cointraffic/cointraffic.go new file mode 100644 index 00000000000..781d8def81a --- /dev/null +++ b/adapters/cointraffic/cointraffic.go @@ -0,0 +1,79 @@ +package cointraffic + +import ( + "encoding/json" + "net/http" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" +) + +type adapter struct { + endpoint string +} + +// Builder builds a new instance of the Cointraffic adapter for the given bidder with the given config. +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + bidder := &adapter{ + endpoint: config.Endpoint, + } + return bidder, nil +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + requestJSON, err := json.Marshal(request) + if err != nil { + return nil, []error{err} + } + + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + headers.Add("Accept", "application/json") + headers.Add("x-openrtb-version", "2.5") + + requestData := &adapters.RequestData{ + Method: "POST", + Uri: a.endpoint, + Body: requestJSON, + Headers: headers, + ImpIDs: openrtb_ext.GetImpIDs(request.Imp), + } + + return []*adapters.RequestData{requestData}, nil +} + +func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if adapters.IsResponseStatusCodeNoContent(responseData) { + return nil, nil + } + + if err := adapters.CheckResponseStatusCodeForErrors(responseData); err != nil { + return nil, []error{err} + } + + var response openrtb2.BidResponse + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { + return nil, []error{err} + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(response.SeatBid[0].Bid)) + if response.Cur != "" { + bidResponse.Currency = response.Cur + } + + var errs []error + + for _, seatBid := range response.SeatBid { + for i := range seatBid.Bid { + bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ + Bid: &seatBid.Bid[i], + BidType: openrtb_ext.BidTypeBanner, + }) + } + } + + return bidResponse, errs +} diff --git a/adapters/cointraffic/cointraffic_test.go b/adapters/cointraffic/cointraffic_test.go new file mode 100644 index 00000000000..133dfd2af2c --- /dev/null +++ b/adapters/cointraffic/cointraffic_test.go @@ -0,0 +1,51 @@ +package cointraffic + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" +) + +const testsDir = "cointraffictest" +const testsBidderEndpoint = "http://test-request.com/prebid" + +func TestJsonSamples(t *testing.T) { + ac := config.Adapter{ + Endpoint: testsBidderEndpoint, + ExtraAdapterInfo: "", + } + + sc := config.Server{ + ExternalUrl: "http://hosturl.com", + GvlID: 1, + DataCenter: "2", + } + + bidder, buildErr := Builder(openrtb_ext.BidderCointraffic, ac, sc) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, testsDir, bidder) +} + +func TestEndpointTemplateMalformed(t *testing.T) { + ac := config.Adapter{ + Endpoint: "{{Malformed}}", + } + + sc := config.Server{ + ExternalUrl: "http://hosturl.com", + GvlID: 1, + DataCenter: "2", + } + + _, buildErr := Builder(openrtb_ext.BidderCointraffic, ac, sc) + + assert.Nil(t, buildErr) +} diff --git a/adapters/cointraffic/cointraffictest/exemplary/simple-banner.json b/adapters/cointraffic/cointraffictest/exemplary/simple-banner.json new file mode 100644 index 00000000000..1ca486eedb3 --- /dev/null +++ b/adapters/cointraffic/cointraffictest/exemplary/simple-banner.json @@ -0,0 +1,158 @@ +{ + "mockBidRequest": { + "id": "testRequestIdSingle", + "site": { + "page": "https://publisher-website.com/web" + }, + "imp": [ + { + "id": "testImpressionId1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": "testPlacementId" + } + } + }, + { + "id": "testImpressionId2", + "banner": { + "format": [ + { + "w": 320, + "h": 100 + } + ] + }, + "ext": { + "bidder": { + "placementId": "testPlacementId" + } + } + } + ], + "device": { + "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36", + "ip": "111.111.111.111" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ], + "X-Openrtb-Version": [ + "2.5" + ] + }, + "uri": "http://test-request.com/prebid", + "body": { + "id": "testRequestIdSingle", + "site": { + "page": "https://publisher-website.com/web" + }, + "imp": [ + { + "id": "testImpressionId1", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": "testPlacementId" + } + } + }, + { + "id": "testImpressionId2", + "banner": { + "format": [ + { + "w": 320, + "h": 100 + } + ] + }, + "ext": { + "bidder": { + "placementId": "testPlacementId" + } + } + } + ], + "device": { + "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36", + "ip": "111.111.111.111" + } + }, + "impIDs": [ + "testImpressionId1", + "testImpressionId2" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "testRequestIdSingle", + "seatbid": [ + { + "seat": "cointraffic", + "bid": [ + { + "id": "uniqueId", + "impid": "testImpressionId1", + "price": 1.50, + "adid": "advertiserUniqueId", + "adm": "iframe-content", + "crid": "creativeUniqueId", + "w": 300, + "h": 250, + "nurl": "http://test-request.com/prebid/confirm" + } + ] + } + ], + "cur": "EUR" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids": [ + { + "bid": { + "id": "uniqueId", + "impid": "testImpressionId1", + "price": 1.50, + "adm": "iframe-content", + "adid": "advertiserUniqueId", + "crid": "creativeUniqueId", + "w": 300, + "h": 250, + "nurl": "http://test-request.com/prebid/confirm" + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/cointraffic/cointraffictest/supplemental/bad-request.json b/adapters/cointraffic/cointraffictest/supplemental/bad-request.json new file mode 100644 index 00000000000..7afab031a22 --- /dev/null +++ b/adapters/cointraffic/cointraffictest/supplemental/bad-request.json @@ -0,0 +1,70 @@ +{ + "mockBidRequest": { + "id": "testRequestIssues", + "site": { + "page": "https://publisher-website.com/web" + }, + "imp": [ + { + "id": "testImpressionId", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": "testPlacementId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://test-request.com/prebid", + "body": { + "id": "testRequestIssues", + "site": { + "page": "https://publisher-website.com/web" + }, + "imp": [ + { + "id": "testImpressionId", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": "testPlacementId" + } + } + } + ] + }, + "impIDs": [ + "testImpressionId" + ] + }, + "mockResponse": { + "status": 400, + "body": {} + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} diff --git a/adapters/cointraffic/cointraffictest/supplemental/no-bid.json b/adapters/cointraffic/cointraffictest/supplemental/no-bid.json new file mode 100644 index 00000000000..b88d8e83b55 --- /dev/null +++ b/adapters/cointraffic/cointraffictest/supplemental/no-bid.json @@ -0,0 +1,65 @@ +{ + "mockBidRequest": { + "id": "testRequestNoBid", + "site": { + "page": "https://publisher-website.com/web" + }, + "imp": [ + { + "id": "testImpressionId", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": "testPlacementId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://test-request.com/prebid", + "body": { + "id": "testRequestNoBid", + "site": { + "page": "https://publisher-website.com/web" + }, + "imp": [ + { + "id": "testImpressionId", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": "testPlacementId" + } + } + } + ] + }, + "impIDs": [ + "testImpressionId" + ] + }, + "mockResponse": { + "status": 204, + "body": {} + } + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/cointraffic/cointraffictest/supplemental/server-error.json b/adapters/cointraffic/cointraffictest/supplemental/server-error.json new file mode 100644 index 00000000000..8f439682584 --- /dev/null +++ b/adapters/cointraffic/cointraffictest/supplemental/server-error.json @@ -0,0 +1,70 @@ +{ + "mockBidRequest": { + "id": "testRequestIssues", + "site": { + "page": "https://publisher-website.com/web" + }, + "imp": [ + { + "id": "testImpressionId", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": "testPlacementId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://test-request.com/prebid", + "body": { + "id": "testRequestIssues", + "site": { + "page": "https://publisher-website.com/web" + }, + "imp": [ + { + "id": "testImpressionId", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": "testPlacementId" + } + } + } + ] + }, + "impIDs": [ + "testImpressionId" + ] + }, + "mockResponse": { + "status": 500, + "body": {} + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 500. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} diff --git a/adapters/cointraffic/params_test.go b/adapters/cointraffic/params_test.go new file mode 100644 index 00000000000..484a72c66b7 --- /dev/null +++ b/adapters/cointraffic/params_test.go @@ -0,0 +1,51 @@ +package cointraffic + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v3/openrtb_ext" +) + +// This file actually intends to test static/bidder-params/cointraffic.json +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schemas. %v", err) + } + + for _, validParam := range validParams { + if err := validator.Validate(openrtb_ext.BidderCointraffic, json.RawMessage(validParam)); err != nil { + t.Errorf("Schema rejected params: %s", validParam) + } + } +} + +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schemas. %v", err) + } + + for _, invalidParam := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderCointraffic, json.RawMessage(invalidParam)); err == nil { + t.Errorf("Schema allowed unexpected params: %s", invalidParam) + } + } +} + +var validParams = []string{ + `{"placementId": "123"}`, +} + +var invalidParams = []string{ + ``, + `null`, + `true`, + `5`, + `4.2`, + `[]`, + `{}`, + `{"placementId": 42}`, + `{"placementId": ""}`, +} diff --git a/adapters/coinzilla/coinzilla.go b/adapters/coinzilla/coinzilla.go index 8939a75cec7..21e321406cc 100644 --- a/adapters/coinzilla/coinzilla.go +++ b/adapters/coinzilla/coinzilla.go @@ -6,11 +6,12 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { @@ -67,7 +68,7 @@ func (adapter *adapter) MakeBids(openRTBRequest *openrtb2.BidRequest, requestToB } var openRTBBidderResponse openrtb2.BidResponse - if err := json.Unmarshal(bidderRawResponse.Body, &openRTBBidderResponse); err != nil { + if err := jsonutil.Unmarshal(bidderRawResponse.Body, &openRTBBidderResponse); err != nil { return nil, []error{err} } diff --git a/adapters/coinzilla/coinzilla_test.go b/adapters/coinzilla/coinzilla_test.go index 39b3bb1f6e5..830028f24f7 100644 --- a/adapters/coinzilla/coinzilla_test.go +++ b/adapters/coinzilla/coinzilla_test.go @@ -3,9 +3,9 @@ package coinzilla import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) const testsDir = "coinzillatest" diff --git a/adapters/coinzilla/params_test.go b/adapters/coinzilla/params_test.go index dd2cd757496..d174b1441aa 100644 --- a/adapters/coinzilla/params_test.go +++ b/adapters/coinzilla/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/colossus/colossus.go b/adapters/colossus/colossus.go index d66b588ab4e..0fc1e50a29e 100644 --- a/adapters/colossus/colossus.go +++ b/adapters/colossus/colossus.go @@ -7,10 +7,11 @@ import ( "github.com/buger/jsonparser" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type ColossusAdapter struct { @@ -99,7 +100,7 @@ func (a *ColossusAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externa var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } @@ -124,7 +125,7 @@ func (a *ColossusAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externa func getMediaTypeForImp(bid openrtb2.Bid, imps []openrtb2.Imp) (openrtb_ext.BidType, error) { var bidExt ColossusResponseBidExt - err := json.Unmarshal(bid.Ext, &bidExt) + err := jsonutil.Unmarshal(bid.Ext, &bidExt) if err == nil { switch bidExt.MediaType { case "banner": diff --git a/adapters/colossus/colossus_test.go b/adapters/colossus/colossus_test.go index 6298b7f3958..227bd635ae0 100644 --- a/adapters/colossus/colossus_test.go +++ b/adapters/colossus/colossus_test.go @@ -3,9 +3,9 @@ package colossus import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/colossus/colossustest/supplemental/bad_response.json b/adapters/colossus/colossustest/supplemental/bad_response.json index 10efa26e397..038c597d42f 100644 --- a/adapters/colossus/colossustest/supplemental/bad_response.json +++ b/adapters/colossus/colossustest/supplemental/bad_response.json @@ -79,7 +79,7 @@ }], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/colossus/params_test.go b/adapters/colossus/params_test.go index ebafd637d6a..bf924e4eae5 100644 --- a/adapters/colossus/params_test.go +++ b/adapters/colossus/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // TestValidParams makes sure that the colossus schema accepts all imp.ext fields which we intend to support. diff --git a/adapters/compass/compass.go b/adapters/compass/compass.go index ff74757d058..28f46bc7e2f 100644 --- a/adapters/compass/compass.go +++ b/adapters/compass/compass.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -44,10 +45,10 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E var bidderExt adapters.ExtImpBidder var compassExt openrtb_ext.ImpExtCompass - if err = json.Unmarshal(reqCopy.Imp[0].Ext, &bidderExt); err != nil { + if err = jsonutil.Unmarshal(reqCopy.Imp[0].Ext, &bidderExt); err != nil { return nil, []error{err} } - if err = json.Unmarshal(bidderExt.Bidder, &compassExt); err != nil { + if err = jsonutil.Unmarshal(bidderExt.Bidder, &compassExt); err != nil { return nil, []error{err} } @@ -111,7 +112,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } diff --git a/adapters/compass/compass_test.go b/adapters/compass/compass_test.go index 08d9d1bb46e..7aed7616ded 100644 --- a/adapters/compass/compass_test.go +++ b/adapters/compass/compass_test.go @@ -3,9 +3,9 @@ package compass import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/compass/compasstest/supplemental/bad_response.json b/adapters/compass/compasstest/supplemental/bad_response.json index 86656d785bc..ca81c4cc167 100644 --- a/adapters/compass/compasstest/supplemental/bad_response.json +++ b/adapters/compass/compasstest/supplemental/bad_response.json @@ -78,7 +78,7 @@ }], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/compass/params_test.go b/adapters/compass/params_test.go index 37074bb40f7..edabac29752 100644 --- a/adapters/compass/params_test.go +++ b/adapters/compass/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/concert/concert.go b/adapters/concert/concert.go index 26bb105842a..adf71442744 100644 --- a/adapters/concert/concert.go +++ b/adapters/concert/concert.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -38,7 +39,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte } var requestMap map[string]interface{} - err = json.Unmarshal(requestJSON, &requestMap) + err = jsonutil.Unmarshal(requestJSON, &requestMap) if err != nil { return nil, []error{err} } @@ -78,7 +79,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } @@ -129,10 +130,10 @@ func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) { func getBidderExt(imp openrtb2.Imp) (bidderImpExt openrtb_ext.ImpExtConcert, err error) { var impExt adapters.ExtImpBidder - if err = json.Unmarshal(imp.Ext, &impExt); err != nil { + if err = jsonutil.Unmarshal(imp.Ext, &impExt); err != nil { return bidderImpExt, fmt.Errorf("imp ext: %v", err) } - if err = json.Unmarshal(impExt.Bidder, &bidderImpExt); err != nil { + if err = jsonutil.Unmarshal(impExt.Bidder, &bidderImpExt); err != nil { return bidderImpExt, fmt.Errorf("bidder ext: %v", err) } return bidderImpExt, nil diff --git a/adapters/concert/concert_test.go b/adapters/concert/concert_test.go index e8c06d06377..d6cea80fb93 100644 --- a/adapters/concert/concert_test.go +++ b/adapters/concert/concert_test.go @@ -3,9 +3,9 @@ package concert import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/concert/params_test.go b/adapters/concert/params_test.go index 4cf653d2b27..b8ec65bda88 100644 --- a/adapters/concert/params_test.go +++ b/adapters/concert/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/connectad/connectad.go b/adapters/connectad/connectad.go index 83023195c54..dd13bc3764d 100644 --- a/adapters/connectad/connectad.go +++ b/adapters/connectad/connectad.go @@ -8,10 +8,11 @@ import ( "strconv" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type ConnectAdAdapter struct { @@ -84,7 +85,7 @@ func (a *ConnectAdAdapter) MakeBids(bidReq *openrtb2.BidRequest, unused *adapter var bidResp openrtb2.BidResponse - if err := json.Unmarshal(httpRes.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(httpRes.Body, &bidResp); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: fmt.Sprintf("Unable to unpackage bid response. Error: %s", err.Error()), }} @@ -139,7 +140,7 @@ func preprocess(request *openrtb2.BidRequest) []error { } func addImpInfo(imp *openrtb2.Imp, secure *int8, cadExt *openrtb_ext.ExtImpConnectAd) { - imp.TagID = strconv.Itoa(cadExt.SiteID) + imp.TagID = strconv.Itoa(int(cadExt.SiteID)) imp.Secure = secure if cadExt.Bidfloor != 0 { @@ -156,14 +157,14 @@ func addHeaderIfNonEmpty(headers http.Header, headerName string, headerValue str func unpackImpExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpConnectAd, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: fmt.Sprintf("Impression id=%s has an Error: %s", imp.ID, err.Error()), } } var cadExt openrtb_ext.ExtImpConnectAd - if err := json.Unmarshal(bidderExt.Bidder, &cadExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &cadExt); err != nil { return nil, &errortypes.BadInput{ Message: fmt.Sprintf("Impression id=%s, has invalid Ext", imp.ID), } diff --git a/adapters/connectad/connectad_test.go b/adapters/connectad/connectad_test.go index 6ce9dd3eade..4563e0045f9 100644 --- a/adapters/connectad/connectad_test.go +++ b/adapters/connectad/connectad_test.go @@ -3,9 +3,9 @@ package connectad import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/connectad/connectadtest/supplemental/badresponse.json b/adapters/connectad/connectadtest/supplemental/badresponse.json index 9f2761c9044..0b714f44fe6 100644 --- a/adapters/connectad/connectadtest/supplemental/badresponse.json +++ b/adapters/connectad/connectadtest/supplemental/badresponse.json @@ -84,7 +84,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "Unable to unpackage bid response. Error: json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "Unable to unpackage bid response. Error: expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/connectad/connectadtest/supplemental/no_ext.json b/adapters/connectad/connectadtest/supplemental/no_ext.json index af1b671a5b9..e75ec87b243 100644 --- a/adapters/connectad/connectadtest/supplemental/no_ext.json +++ b/adapters/connectad/connectadtest/supplemental/no_ext.json @@ -21,8 +21,8 @@ }, "expectedMakeRequestsErrors": [ { - "value": "Impression id=test-banner-imp-id has an Error: unexpected end of JSON input", - "comparison": "literal" + "value": "Impression id=test-banner-imp-id has an Error: expect { or n, but found", + "comparison": "startswith" }, { "value": "Error in preprocess of Imp", diff --git a/adapters/connectad/params_test.go b/adapters/connectad/params_test.go index 2ab3c4902e7..dc7c40be729 100644 --- a/adapters/connectad/params_test.go +++ b/adapters/connectad/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { @@ -36,13 +36,13 @@ func TestInvalidParams(t *testing.T) { var validParams = []string{ `{"siteId": 123456, "networkId": 123456, "bidfloor": 0.10}`, `{"siteId": 123456, "networkId": 123456}`, + `{"siteId": 123456, "networkId": "123456", "bidfloor": 0.10}`, + `{"siteId": "123456", "networkId": 123456, "bidfloor": 0.10}`, } var invalidParams = []string{ `{}`, `null`, - `{"siteId": 123456, "networkId": "123456", "bidfloor": 0.10}`, - `{"siteId": "123456", "networkId": 123456, "bidfloor": 0.10}`, `{"siteId": 123456, "networkId": 123456, "bidfloor": "0.10"}`, `{"siteId": "123456"}`, `{"networkId": 123456}`, diff --git a/adapters/consumable/consumable.go b/adapters/consumable/consumable.go index dd139e58fb0..9b80fb14599 100644 --- a/adapters/consumable/consumable.go +++ b/adapters/consumable/consumable.go @@ -5,10 +5,11 @@ import ( "fmt" "net/http" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" "github.com/prebid/openrtb/v20/openrtb2" ) @@ -41,7 +42,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E requests := []*adapters.RequestData{ { Method: "POST", - Uri: "https://e.serverbid.com/sb/rtb", + Uri: a.endpoint + "/sb/rtb", Body: bodyBytes, Headers: headers, ImpIDs: openrtb_ext.GetImpIDs(request.Imp), @@ -63,7 +64,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E requests := []*adapters.RequestData{ { Method: "POST", - Uri: "https://e.serverbid.com/rtb/bid?s=" + consumableExt.PlacementId, + Uri: a.endpoint + "/rtb/bid?s=" + consumableExt.PlacementId, Body: bodyBytes, Headers: headers, ImpIDs: openrtb_ext.GetImpIDs(request.Imp), @@ -71,8 +72,8 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E } return requests, errs } - } + func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { if adapters.IsResponseStatusCodeNoContent(responseData) { return nil, nil @@ -83,7 +84,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } @@ -144,14 +145,14 @@ func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server co func extractExtensions(impression openrtb2.Imp) (*adapters.ExtImpBidder, *openrtb_ext.ExtImpConsumable, []error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(impression.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(impression.Ext, &bidderExt); err != nil { return nil, nil, []error{&errortypes.BadInput{ Message: err.Error(), }} } var consumableExt openrtb_ext.ExtImpConsumable - if err := json.Unmarshal(bidderExt.Bidder, &consumableExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &consumableExt); err != nil { return nil, nil, []error{&errortypes.BadInput{ Message: err.Error(), }} diff --git a/adapters/consumable/consumable_test.go b/adapters/consumable/consumable_test.go index f960597cff3..200d6159eae 100644 --- a/adapters/consumable/consumable_test.go +++ b/adapters/consumable/consumable_test.go @@ -6,16 +6,17 @@ import ( "github.com/prebid/openrtb/v20/adcom1" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/ptrutil" ) func TestJsonSamples(t *testing.T) { bidder, buildErr := Builder(openrtb_ext.BidderConsumable, config.Adapter{ - Endpoint: "http://ib.adnxs.com/openrtb2"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + Endpoint: "https://e.serverbid.com", + }, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) if buildErr != nil { t.Fatalf("Builder returned unexpected error %v", buildErr) @@ -28,23 +29,25 @@ func TestConsumableMakeBidsWithCategoryDuration(t *testing.T) { bidder := &adapter{} mockedReq := &openrtb2.BidRequest{ - Imp: []openrtb2.Imp{{ - ID: "1_1", - Video: &openrtb2.Video{ - W: ptrutil.ToPtr[int64](640), - H: ptrutil.ToPtr[int64](360), - MIMEs: []string{"video/mp4"}, - MaxDuration: 60, - Protocols: []adcom1.MediaCreativeSubtype{2, 3, 5, 6}, - }, - Ext: json.RawMessage( - `{ + Imp: []openrtb2.Imp{ + { + ID: "1_1", + Video: &openrtb2.Video{ + W: ptrutil.ToPtr[int64](640), + H: ptrutil.ToPtr[int64](360), + MIMEs: []string{"video/mp4"}, + MaxDuration: 60, + Protocols: []adcom1.MediaCreativeSubtype{2, 3, 5, 6}, + }, + Ext: json.RawMessage( + `{ "prebid": {}, "bidder": { "placementId": "123456" } }`, - )}, + ), + }, }, } mockedExtReq := &adapters.RequestData{} diff --git a/adapters/consumable/params_test.go b/adapters/consumable/params_test.go index 99a993e9752..3820acc7376 100644 --- a/adapters/consumable/params_test.go +++ b/adapters/consumable/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/consumable.json diff --git a/adapters/conversant/conversant.go b/adapters/conversant/conversant.go index b4cf7dcb091..aa05530f815 100644 --- a/adapters/conversant/conversant.go +++ b/adapters/conversant/conversant.go @@ -8,10 +8,11 @@ import ( "github.com/prebid/openrtb/v20/adcom1" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type ConversantAdapter struct { @@ -25,14 +26,14 @@ func (c *ConversantAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo * } for i := 0; i < len(request.Imp); i++ { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(request.Imp[i].Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(request.Imp[i].Ext, &bidderExt); err != nil { return nil, []error{&errortypes.BadInput{ Message: fmt.Sprintf("Impression[%d] missing ext object", i), }} } var cnvrExt openrtb_ext.ExtImpConversant - if err := json.Unmarshal(bidderExt.Bidder, &cnvrExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &cnvrExt); err != nil { return nil, []error{&errortypes.BadInput{ Message: fmt.Sprintf("Impression[%d] missing ext.bidder object", i), }} @@ -164,7 +165,7 @@ func (c *ConversantAdapter) MakeBids(internalRequest *openrtb2.BidRequest, exter } var resp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &resp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &resp); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: fmt.Sprintf("bad server response: %d. ", err), }} diff --git a/adapters/conversant/conversant_test.go b/adapters/conversant/conversant_test.go index 1c08ea557ed..eeb5756471a 100644 --- a/adapters/conversant/conversant_test.go +++ b/adapters/conversant/conversant_test.go @@ -3,9 +3,9 @@ package conversant import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/copper6ssp/copper6ssp.go b/adapters/copper6ssp/copper6ssp.go new file mode 100644 index 00000000000..77154dd6860 --- /dev/null +++ b/adapters/copper6ssp/copper6ssp.go @@ -0,0 +1,158 @@ +package copper6ssp + +import ( + "encoding/json" + "fmt" + "net/http" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" +) + +type adapter struct { + endpoint string +} + +type reqBodyExt struct { + Copper6sspBidderExt reqBodyExtBidder `json:"bidder"` +} + +type reqBodyExtBidder struct { + Type string `json:"type"` + PlacementID string `json:"placementId,omitempty"` + EndpointID string `json:"endpointId,omitempty"` +} + +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + bidder := &adapter{ + endpoint: config.Endpoint, + } + return bidder, nil +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + var errs []error + var adapterRequests []*adapters.RequestData + + reqCopy := *request + for _, imp := range request.Imp { + reqCopy.Imp = []openrtb2.Imp{imp} + + var bidderExt adapters.ExtImpBidder + var copper6sspExt openrtb_ext.ImpExtCopper6ssp + + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { + errs = append(errs, err) + continue + } + if err := jsonutil.Unmarshal(bidderExt.Bidder, &copper6sspExt); err != nil { + errs = append(errs, err) + continue + } + + impExt := reqBodyExt{Copper6sspBidderExt: reqBodyExtBidder{}} + + if copper6sspExt.PlacementID != "" { + impExt.Copper6sspBidderExt.PlacementID = copper6sspExt.PlacementID + impExt.Copper6sspBidderExt.Type = "publisher" + } else if copper6sspExt.EndpointID != "" { + impExt.Copper6sspBidderExt.EndpointID = copper6sspExt.EndpointID + impExt.Copper6sspBidderExt.Type = "network" + } + + finalImpExt, err := json.Marshal(impExt) + if err != nil { + errs = append(errs, err) + continue + } + + reqCopy.Imp[0].Ext = finalImpExt + + adapterReq, err := a.makeRequest(&reqCopy) + if err != nil { + errs = append(errs, err) + continue + } + + if adapterReq != nil { + adapterRequests = append(adapterRequests, adapterReq) + } + } + + if len(adapterRequests) == 0 { + return nil, errs + } + + return adapterRequests, nil +} + +func (a *adapter) makeRequest(request *openrtb2.BidRequest) (*adapters.RequestData, error) { + reqJSON, err := json.Marshal(request) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + headers.Add("Accept", "application/json") + return &adapters.RequestData{ + Method: "POST", + Uri: a.endpoint, + Body: reqJSON, + Headers: headers, + ImpIDs: openrtb_ext.GetImpIDs(request.Imp), + }, nil +} + +func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if adapters.IsResponseStatusCodeNoContent(responseData) { + return nil, nil + } + + if err := adapters.CheckResponseStatusCodeForErrors(responseData); err != nil { + return nil, []error{err} + } + + var response openrtb2.BidResponse + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { + return nil, []error{err} + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) + if len(response.Cur) != 0 { + bidResponse.Currency = response.Cur + } + + for _, seatBid := range response.SeatBid { + for i := range seatBid.Bid { + bidType, err := getBidType(seatBid.Bid[i]) + if err != nil { + return nil, []error{err} + } + + b := &adapters.TypedBid{ + Bid: &seatBid.Bid[i], + BidType: bidType, + } + bidResponse.Bids = append(bidResponse.Bids, b) + } + } + return bidResponse, nil +} + +func getBidType(bid openrtb2.Bid) (openrtb_ext.BidType, error) { + // determinate media type by bid response field mtype + switch bid.MType { + case openrtb2.MarkupBanner: + return openrtb_ext.BidTypeBanner, nil + case openrtb2.MarkupVideo: + return openrtb_ext.BidTypeVideo, nil + case openrtb2.MarkupNative: + return openrtb_ext.BidTypeNative, nil + } + + return "", fmt.Errorf("could not define media type for impression: %s", bid.ImpID) +} diff --git a/adapters/copper6ssp/copper6ssp_test.go b/adapters/copper6ssp/copper6ssp_test.go new file mode 100644 index 00000000000..75ca8ee4044 --- /dev/null +++ b/adapters/copper6ssp/copper6ssp_test.go @@ -0,0 +1,20 @@ +package copper6ssp + +import ( + "testing" + + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderCopper6ssp, config.Adapter{ + Endpoint: "https://example.com"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "copper6ssptest", bidder) +} diff --git a/adapters/copper6ssp/copper6ssptest/exemplary/endpointId.json b/adapters/copper6ssp/copper6ssptest/exemplary/endpointId.json new file mode 100644 index 00000000000..3dc82f836da --- /dev/null +++ b/adapters/copper6ssp/copper6ssptest/exemplary/endpointId.json @@ -0,0 +1,136 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "endpointId": "test" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.com", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "endpointId": "test", + "type": "network" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ], + "seat": "copper6ssp" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/copper6ssp/copper6ssptest/exemplary/multi-format.json b/adapters/copper6ssp/copper6ssptest/exemplary/multi-format.json new file mode 100644 index 00000000000..9e897a9a1bb --- /dev/null +++ b/adapters/copper6ssp/copper6ssptest/exemplary/multi-format.json @@ -0,0 +1,105 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "endpointId": "test" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.com", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "endpointId": "test", + "type": "network" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 204 + } + } + ], + "expectedBidResponses": [] +} \ No newline at end of file diff --git a/adapters/copper6ssp/copper6ssptest/exemplary/multi-imp.json b/adapters/copper6ssp/copper6ssptest/exemplary/multi-imp.json new file mode 100644 index 00000000000..63828352744 --- /dev/null +++ b/adapters/copper6ssp/copper6ssptest/exemplary/multi-imp.json @@ -0,0 +1,253 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "endpointId": "test" + } + } + }, + { + "id": "test-imp-id2", + "tagid": "test2", + "banner": { + "format": [ + { + "w": 3000, + "h": 2500 + }, + { + "w": 3000, + "h": 6000 + } + ] + }, + "ext": { + "bidder": { + "endpointId": "test2" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.com", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "endpointId": "test", + "type": "network" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ], + "seat": "copper6ssp" + } + ], + "cur": "USD" + } + } + }, + { + "expectedRequest": { + "uri": "https://example.com", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id2", + "tagid": "test2", + "banner": { + "format": [ + { + "w": 3000, + "h": 2500 + }, + { + "w": 3000, + "h": 6000 + } + ] + }, + "ext": { + "bidder": { + "endpointId": "test2", + "type": "network" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + } + }, + "impIDs":["test-imp-id2"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id2", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 3000, + "h": 2500, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ], + "seat": "copper6ssp" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + }, + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id2", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 3000, + "h": 2500, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/copper6ssp/copper6ssptest/exemplary/simple-banner.json b/adapters/copper6ssp/copper6ssptest/exemplary/simple-banner.json new file mode 100644 index 00000000000..3bff225709d --- /dev/null +++ b/adapters/copper6ssp/copper6ssptest/exemplary/simple-banner.json @@ -0,0 +1,136 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.com", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ], + "seat": "copper6ssp" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/copper6ssp/copper6ssptest/exemplary/simple-native.json b/adapters/copper6ssp/copper6ssptest/exemplary/simple-native.json new file mode 100644 index 00000000000..63b4a5c824a --- /dev/null +++ b/adapters/copper6ssp/copper6ssptest/exemplary/simple-native.json @@ -0,0 +1,120 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "native": { + "request": "{\"ver\":\"1.1\",\"layout\":1,\"adunit\":2,\"plcmtcnt\":6,\"plcmttype\":4,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"wmin\":492,\"hmin\":328,\"type\":3,\"mimes\":[\"image/jpeg\",\"image/jpg\",\"image/png\"]}},{\"id\":4,\"required\":0,\"data\":{\"type\":6}},{\"id\":5,\"required\":0,\"data\":{\"type\":7}},{\"id\":6,\"required\":0,\"data\":{\"type\":1,\"len\":20}}]}", + "ver": "1.1" + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.com", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "native": { + "request": "{\"ver\":\"1.1\",\"layout\":1,\"adunit\":2,\"plcmtcnt\":6,\"plcmttype\":4,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"wmin\":492,\"hmin\":328,\"type\":3,\"mimes\":[\"image/jpeg\",\"image/jpg\",\"image/png\"]}},{\"id\":4,\"required\":0,\"data\":{\"type\":6}},{\"id\":5,\"required\":0,\"data\":{\"type\":7}},{\"id\":6,\"required\":0,\"data\":{\"type\":1,\"len\":20}}]}", + "ver": "1.1" + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 4, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "native" + } + } + } + ], + "seat": "copper6ssp" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 4, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "native" + } + } + }, + "type": "native" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/copper6ssp/copper6ssptest/exemplary/simple-video.json b/adapters/copper6ssp/copper6ssptest/exemplary/simple-video.json new file mode 100644 index 00000000000..60156082dc7 --- /dev/null +++ b/adapters/copper6ssp/copper6ssptest/exemplary/simple-video.json @@ -0,0 +1,131 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.com", + "body": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ] + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "00:01:00", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 2, + "ext": { + "prebid": { + "type": "video" + } + } + } + ], + "seat": "copper6ssp" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "00:01:00", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 2, + "ext": { + "prebid": { + "type": "video" + } + } + }, + "type": "video" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/copper6ssp/copper6ssptest/exemplary/simple-web-banner.json b/adapters/copper6ssp/copper6ssptest/exemplary/simple-web-banner.json new file mode 100644 index 00000000000..3ff97037a82 --- /dev/null +++ b/adapters/copper6ssp/copper6ssptest/exemplary/simple-web-banner.json @@ -0,0 +1,136 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "site": { + "id": "1", + "domain": "test.com" + }, + "device": { + "ip": "123.123.123.123", + "ua": "Ubuntu" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.com", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "site": { + "id": "1", + "domain": "test.com" + }, + "device": { + "ip": "123.123.123.123", + "ua": "Ubuntu" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 468, + "h": 60, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ], + "seat": "copper6ssp" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 468, + "h": 60, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/copper6ssp/copper6ssptest/supplemental/bad_media_type.json b/adapters/copper6ssp/copper6ssptest/supplemental/bad_media_type.json new file mode 100644 index 00000000000..3b61edd137d --- /dev/null +++ b/adapters/copper6ssp/copper6ssptest/supplemental/bad_media_type.json @@ -0,0 +1,83 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://example.com", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "w": 300, + "h": 250, + "ext": {} + } + ], + "seat": "copper6ssp" + } + ], + "cur": "USD" + } + } + }], + "expectedMakeBidsErrors": [ + { + "value": "could not define media type for impression: test-imp-id", + "comparison": "literal" + } + ] +} diff --git a/adapters/copper6ssp/copper6ssptest/supplemental/bad_response.json b/adapters/copper6ssp/copper6ssptest/supplemental/bad_response.json new file mode 100644 index 00000000000..476058ed624 --- /dev/null +++ b/adapters/copper6ssp/copper6ssptest/supplemental/bad_response.json @@ -0,0 +1,85 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://example.com", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": "" + } + }], + "expectedMakeBidsErrors": [ + { + "value": "expect { or n, but found \"", + "comparison": "literal" + } + ] +} diff --git a/adapters/copper6ssp/copper6ssptest/supplemental/no-valid-bidder-param.json b/adapters/copper6ssp/copper6ssptest/supplemental/no-valid-bidder-param.json new file mode 100644 index 00000000000..d27134c5ab7 --- /dev/null +++ b/adapters/copper6ssp/copper6ssptest/supplemental/no-valid-bidder-param.json @@ -0,0 +1,42 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "endpointId": [] + } + } + } + ] + }, + "expectedMakeRequestsErrors": [ + { + "value": "cannot unmarshal openrtb_ext.ImpExtCopper6ssp.EndpointID: expects \" or n, but found [", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/copper6ssp/copper6ssptest/supplemental/no-valid-imp-ext.json b/adapters/copper6ssp/copper6ssptest/supplemental/no-valid-imp-ext.json new file mode 100644 index 00000000000..09108b2d847 --- /dev/null +++ b/adapters/copper6ssp/copper6ssptest/supplemental/no-valid-imp-ext.json @@ -0,0 +1,38 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": "invalid" + } + ] + }, + "expectedMakeRequestsErrors": [ + { + "value": "expect { or n, but found \"", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/copper6ssp/copper6ssptest/supplemental/status-204.json b/adapters/copper6ssp/copper6ssptest/supplemental/status-204.json new file mode 100644 index 00000000000..7dd1c65fd36 --- /dev/null +++ b/adapters/copper6ssp/copper6ssptest/supplemental/status-204.json @@ -0,0 +1,80 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://example.com", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 204, + "body": {} + } + }], + "expectedBidResponses": [] +} diff --git a/adapters/copper6ssp/copper6ssptest/supplemental/status-not-200.json b/adapters/copper6ssp/copper6ssptest/supplemental/status-not-200.json new file mode 100644 index 00000000000..743f2996260 --- /dev/null +++ b/adapters/copper6ssp/copper6ssptest/supplemental/status-not-200.json @@ -0,0 +1,85 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://example.com", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 404, + "body": {} + } + }], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 404. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} diff --git a/adapters/copper6ssp/params_test.go b/adapters/copper6ssp/params_test.go new file mode 100644 index 00000000000..427cf63b263 --- /dev/null +++ b/adapters/copper6ssp/params_test.go @@ -0,0 +1,47 @@ +package copper6ssp + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v3/openrtb_ext" +) + +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json schema. %v", err) + } + + for _, p := range validParams { + if err := validator.Validate(openrtb_ext.BidderCopper6ssp, json.RawMessage(p)); err != nil { + t.Errorf("Schema rejected valid params: %s", p) + } + } +} + +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json schema. %v", err) + } + + for _, p := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderCopper6ssp, json.RawMessage(p)); err == nil { + t.Errorf("Schema allowed invalid params: %s", p) + } + } +} + +var validParams = []string{ + `{"placementId": "test"}`, + `{"placementId": "1"}`, + `{"endpointId": "test"}`, + `{"endpointId": "1"}`, +} + +var invalidParams = []string{ + `{"placementId": 42}`, + `{"endpointId": 42}`, + `{"placementId": "1", "endpointId": "1"}`, +} diff --git a/adapters/cpmstar/cpmstar.go b/adapters/cpmstar/cpmstar.go index 3449963470f..f4f13901266 100644 --- a/adapters/cpmstar/cpmstar.go +++ b/adapters/cpmstar/cpmstar.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type Adapter struct { @@ -66,7 +67,7 @@ func preprocess(request *openrtb2.BidRequest) error { var imp = &request.Imp[i] var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return &errortypes.BadInput{ Message: err.Error(), } @@ -77,7 +78,7 @@ func preprocess(request *openrtb2.BidRequest) error { } var extImp openrtb_ext.ExtImpCpmstar - if err := json.Unmarshal(bidderExt.Bidder, &extImp); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &extImp); err != nil { return &errortypes.BadInput{ Message: err.Error(), } @@ -112,7 +113,7 @@ func (a *Adapter) MakeBids(bidRequest *openrtb2.BidRequest, unused *adapters.Req var bidResponse openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &bidResponse); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &bidResponse); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: err.Error(), }} diff --git a/adapters/cpmstar/cpmstar_test.go b/adapters/cpmstar/cpmstar_test.go index 2a08258358b..478b8989433 100644 --- a/adapters/cpmstar/cpmstar_test.go +++ b/adapters/cpmstar/cpmstar_test.go @@ -3,9 +3,9 @@ package cpmstar import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/cpmstar/cpmstartest/supplemental/invalid-response-unmarshall-error.json b/adapters/cpmstar/cpmstartest/supplemental/invalid-response-unmarshall-error.json index 141cfc0271c..5447f2573b3 100644 --- a/adapters/cpmstar/cpmstartest/supplemental/invalid-response-unmarshall-error.json +++ b/adapters/cpmstar/cpmstartest/supplemental/invalid-response-unmarshall-error.json @@ -60,8 +60,8 @@ ], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go struct field Bid(\\.seatbid\\.bid)?\\.w of type int64", - "comparison": "regex" + "value": "cannot unmarshal openrtb2.Bid.W: unexpected character", + "comparison": "startswith" } ] } \ No newline at end of file diff --git a/adapters/cpmstar/cpmstartest/supplemental/wrong-impression-ext.json b/adapters/cpmstar/cpmstartest/supplemental/wrong-impression-ext.json index 1e8de0acc66..dc30faba5d0 100644 --- a/adapters/cpmstar/cpmstartest/supplemental/wrong-impression-ext.json +++ b/adapters/cpmstar/cpmstartest/supplemental/wrong-impression-ext.json @@ -19,8 +19,8 @@ "expectedMakeRequestsErrors": [ { - "value": "json: cannot unmarshal string into Go struct field ExtImpCpmstar.placementId of type int", - "comparison": "literal" + "value": "cannot unmarshal openrtb_ext.ExtImpCpmstar.PoolId: unexpected character", + "comparison": "startswith" } ] } diff --git a/adapters/cpmstar/params_test.go b/adapters/cpmstar/params_test.go index e0dcb9ced52..aea148c82f6 100644 --- a/adapters/cpmstar/params_test.go +++ b/adapters/cpmstar/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/cpmstar.json diff --git a/adapters/criteo/criteo.go b/adapters/criteo/criteo.go index 69fc8b38f14..2bfa35ade06 100644 --- a/adapters/criteo/criteo.go +++ b/adapters/criteo/criteo.go @@ -6,14 +6,16 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { - endpoint string + endpoint string + bidderName string } type BidExt struct { @@ -25,9 +27,23 @@ type ExtPrebid struct { NetworkName string `json:"networkName"` } +type CriteoExt struct { + Igi []*CriteoExtIgi `json:"igi"` +} + +type CriteoExtIgi struct { + ImpId string `json:"impid"` + Igs []*CriteoExtIgs `json:"igs"` +} + +type CriteoExtIgs struct { + Config json.RawMessage `json:"config"` +} + func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { bidder := &adapter{ - endpoint: config.Endpoint, + endpoint: config.Endpoint, + bidderName: string(bidderName), } return bidder, nil } @@ -68,7 +84,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } @@ -78,7 +94,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R for _, seatBid := range response.SeatBid { for i := range seatBid.Bid { var bidExt BidExt - if err := json.Unmarshal(seatBid.Bid[i].Ext, &bidExt); err != nil { + if err := jsonutil.Unmarshal(seatBid.Bid[i].Ext, &bidExt); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: fmt.Sprintf("Missing ext.prebid.type in bid for impression : %s.", seatBid.Bid[i].ImpID), }} @@ -93,9 +109,36 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } } + bidResponse.FledgeAuctionConfigs = a.ParseFledgeAuctionConfigs(response) + return bidResponse, nil } +func (a *adapter) ParseFledgeAuctionConfigs(response openrtb2.BidResponse) []*openrtb_ext.FledgeAuctionConfig { + var responseExt CriteoExt + if response.Ext != nil { + if err := jsonutil.Unmarshal(response.Ext, &responseExt); err == nil && len(responseExt.Igi) > 0 { + fledgeAuctionConfigs := make([]*openrtb_ext.FledgeAuctionConfig, 0, len(responseExt.Igi)) + for _, igi := range responseExt.Igi { + if len(igi.Igs) > 0 && igi.Igs[0].Config != nil { + fledgeAuctionConfig := &openrtb_ext.FledgeAuctionConfig{ + ImpId: igi.ImpId, + Bidder: a.bidderName, + Config: igi.Igs[0].Config, + } + fledgeAuctionConfigs = append(fledgeAuctionConfigs, fledgeAuctionConfig) + } + } + + if len(fledgeAuctionConfigs) > 0 { + return fledgeAuctionConfigs + } + } + } + + return nil +} + func getBidMeta(ext BidExt) *openrtb_ext.ExtBidPrebidMeta { var bidMeta *openrtb_ext.ExtBidPrebidMeta if ext.Prebid.NetworkName != "" { diff --git a/adapters/criteo/criteo_test.go b/adapters/criteo/criteo_test.go index ae538246444..66420429a9d 100644 --- a/adapters/criteo/criteo_test.go +++ b/adapters/criteo/criteo_test.go @@ -1,11 +1,15 @@ package criteo import ( + "fmt" "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/stretchr/testify/assert" + + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { @@ -21,3 +25,34 @@ func TestJsonSamples(t *testing.T) { // Execute & Verify: adapterstest.RunJSONBidderTest(t, "criteotest", bidder) } + +func TestParseFledgeAuctionConfigs_Nil(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderCriteo, config.Adapter{ + Endpoint: "https://ssp-bidder.criteo.com/openrtb/pbs/auction/request?profile=230"}, + config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + var tests = []struct { + name string + bidResponse openrtb2.BidResponse + }{ + {"no ext", openrtb2.BidResponse{Ext: nil}}, + {"no igi", openrtb2.BidResponse{Ext: []byte("{}")}}, + {"igi empty", openrtb2.BidResponse{Ext: []byte(`{"igi":[]}`)}}, + {"no igs", openrtb2.BidResponse{Ext: []byte(`{"igi":[{}]}`)}}, + {"igs empty", openrtb2.BidResponse{Ext: []byte(`{"igi":[{"impid": "1", "igs": []}]}`)}}, + {"no config", openrtb2.BidResponse{Ext: []byte(`{"igi":[{"impid": "1", "igs": [{}]}]}`)}}, + } + + for _, tt := range tests { + testname := fmt.Sprintf("%s", tt.name) + t.Run(testname, func(t *testing.T) { + fledgeAuctionConfigs := bidder.(*adapter).ParseFledgeAuctionConfigs(tt.bidResponse) + + assert.Nil(t, fledgeAuctionConfigs) + }) + } +} diff --git a/adapters/criteo/criteotest/exemplary/simple-banner-paapi.json b/adapters/criteo/criteotest/exemplary/simple-banner-paapi.json new file mode 100644 index 00000000000..ea92a9026c8 --- /dev/null +++ b/adapters/criteo/criteotest/exemplary/simple-banner-paapi.json @@ -0,0 +1,176 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "criteo.com" + }, + "device": { + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "user": { + "ext": { + "eids": [ + { + "source": "criteo.com", + "uids": [ + { + "id": "criteo-eid" + } + ] + } + ] + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "ae": 1, + "bidder": { + "zoneid": 123456, + "networkid": 78910 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://ssp-bidder.criteo.com/openrtb/pbs/auction/request?profile=230", + "headers": {}, + "body": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "criteo.com" + }, + "device": { + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "user": { + "ext": { + "eids": [ + { + "source": "criteo.com", + "uids": [ + { + "id": "criteo-eid" + } + ] + } + ] + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "ae": 1, + "bidder": { + "zoneid": 123456, + "networkid": 78910 + } + } + } + ] + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "currency": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ] + } + ], + "ext" : { + "igi": [ + { + "impid": "test-imp-id", + "igs": [ + { + "impid": "test-imp-id", + "config": { + "test": "test" + } + } + ] + } + ] + } + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ], + "fledgeAuctionConfigs": [{ + "impid": "test-imp-id", + "config": { + "test": "test" + }, + "bidder": "criteo" + }] + } + ] +} + diff --git a/adapters/criteo/criteotest/exemplary/simple-native.json b/adapters/criteo/criteotest/exemplary/simple-native.json new file mode 100644 index 00000000000..6181ee17305 --- /dev/null +++ b/adapters/criteo/criteotest/exemplary/simple-native.json @@ -0,0 +1,94 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "https://good.site/url" + }, + "imp": [{ + "id": "test-imp-id", + "native": { + "ver": "1.1", + "request": "{\"ver\":\"1.0\",\"layout\":1,\"adunit\":1,\"plcmttype\":1,\"plcmtcnt\":1,\"seq\":0,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":60,\"hmin\":60,\"mimes\":[\"image/jpeg\",\"image/jpg\",\"image/png\"]}},{\"id\":3,\"required\":0,\"data\":{\"type\":2,\"len\":75}},{\"id\":4,\"required\":0,\"data\":{\"type\":6,\"len\":1000}},{\"id\":5,\"required\":0,\"data\":{\"type\":7,\"len\":1000}},{\"id\":6,\"required\":0,\"data\":{\"type\":11,\"len\":1000}}]}" + }, + "ext": { + "bidder": { + "zoneid": 123456 + } + } + }] + }, + + "httpCalls": [{ + "expectedRequest": { + "uri": "https://ssp-bidder.criteo.com/openrtb/pbs/auction/request?profile=230", + "body": { + "id": "test-request-id", + "site": { + "page": "https://good.site/url" + }, + "imp": [{ + "id": "test-imp-id", + "native": { + "ver": "1.1", + "request": "{\"ver\":\"1.0\",\"layout\":1,\"adunit\":1,\"plcmttype\":1,\"plcmtcnt\":1,\"seq\":0,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":60,\"hmin\":60,\"mimes\":[\"image/jpeg\",\"image/jpg\",\"image/png\"]}},{\"id\":3,\"required\":0,\"data\":{\"type\":2,\"len\":75}},{\"id\":4,\"required\":0,\"data\":{\"type\":6,\"len\":1000}},{\"id\":5,\"required\":0,\"data\":{\"type\":7,\"len\":1000}},{\"id\":6,\"required\":0,\"data\":{\"type\":11,\"len\":1000}}]}" + }, + "ext": { + "bidder": { + "zoneid": 123456 + } + } + }] + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [{ + "seat": "grid", + "bid": [{ + "id": "randomid", + "impid": "test-imp-id", + "price": 0.500000, + "adid": "12345678", + "adm": "{\"ver\":\"1.0\",\"layout\":1,\"adunit\":1,\"plcmttype\":1,\"plcmtcnt\":1,\"seq\":0,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":60,\"hmin\":60,\"mimes\":[\"image/jpeg\",\"image/jpg\",\"image/png\"]}},{\"id\":3,\"required\":0,\"data\":{\"type\":2,\"len\":75}},{\"id\":4,\"required\":0,\"data\":{\"type\":6,\"len\":1000}},{\"id\":5,\"required\":0,\"data\":{\"type\":7,\"len\":1000}},{\"id\":6,\"required\":0,\"data\":{\"type\":11,\"len\":1000}}]}", + "ext": { + "prebid": { + "type": "native" + } + }, + "cid": "987", + "crid": "12345678", + "h": 250, + "w": 300 + }] + }], + "cur": "USD" + } + } + }], + + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "bid": { + "id": "randomid", + "impid": "test-imp-id", + "price": 0.5, + "adm": "{\"ver\":\"1.0\",\"layout\":1,\"adunit\":1,\"plcmttype\":1,\"plcmtcnt\":1,\"seq\":0,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":60,\"hmin\":60,\"mimes\":[\"image/jpeg\",\"image/jpg\",\"image/png\"]}},{\"id\":3,\"required\":0,\"data\":{\"type\":2,\"len\":75}},{\"id\":4,\"required\":0,\"data\":{\"type\":6,\"len\":1000}},{\"id\":5,\"required\":0,\"data\":{\"type\":7,\"len\":1000}},{\"id\":6,\"required\":0,\"data\":{\"type\":11,\"len\":1000}}]}", + "adid": "12345678", + "cid": "987", + "crid": "12345678", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "native" + } + } + }, + "type": "native" + }] + }] +} diff --git a/adapters/criteo/params_test.go b/adapters/criteo/params_test.go index aa17aa87e2e..fd63e582b6c 100644 --- a/adapters/criteo/params_test.go +++ b/adapters/criteo/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/criteo.json diff --git a/adapters/cwire/cwire.go b/adapters/cwire/cwire.go index 244be129b30..2d297f78e9d 100644 --- a/adapters/cwire/cwire.go +++ b/adapters/cwire/cwire.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) /* @@ -80,7 +81,7 @@ func (a *adapter) MakeBids(bidReq *openrtb2.BidRequest, unused *adapters.Request } var resp openrtb2.BidResponse - if err := json.Unmarshal(httpRes.Body, &resp); err != nil { + if err := jsonutil.Unmarshal(httpRes.Body, &resp); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: fmt.Sprintf("Error while decoding response, err: %s", err), }} diff --git a/adapters/cwire/cwire_test.go b/adapters/cwire/cwire_test.go index bd5f32e99ff..726c3caf093 100644 --- a/adapters/cwire/cwire_test.go +++ b/adapters/cwire/cwire_test.go @@ -3,9 +3,9 @@ package cwire import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/cwire/params_test.go b/adapters/cwire/params_test.go index d8c8b117069..f2971b96107 100644 --- a/adapters/cwire/params_test.go +++ b/adapters/cwire/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/cwire.json diff --git a/adapters/datablocks/datablocks.go b/adapters/datablocks/datablocks.go index aea4d65cfad..a0e318524d8 100644 --- a/adapters/datablocks/datablocks.go +++ b/adapters/datablocks/datablocks.go @@ -8,11 +8,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type DatablocksAdapter struct { @@ -87,7 +88,7 @@ func (a *DatablocksAdapter) MakeBids( var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } @@ -130,13 +131,13 @@ func splitImpressions(imps []openrtb2.Imp) (map[openrtb_ext.ExtImpDatablocks][]o func getBidderParams(imp *openrtb2.Imp) (*openrtb_ext.ExtImpDatablocks, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: fmt.Sprintf("Missing bidder ext: %s", err.Error()), } } var datablocksExt openrtb_ext.ExtImpDatablocks - if err := json.Unmarshal(bidderExt.Bidder, &datablocksExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &datablocksExt); err != nil { return nil, &errortypes.BadInput{ Message: fmt.Sprintf("Cannot Resolve sourceId: %s", err.Error()), } diff --git a/adapters/datablocks/datablocks_test.go b/adapters/datablocks/datablocks_test.go index d97560ce332..f44204c7c56 100644 --- a/adapters/datablocks/datablocks_test.go +++ b/adapters/datablocks/datablocks_test.go @@ -3,9 +3,9 @@ package datablocks import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/datablocks/datablockstest/supplemental/bad-response-body.json b/adapters/datablocks/datablockstest/supplemental/bad-response-body.json index 8e872cca163..b8915dd4e56 100644 --- a/adapters/datablocks/datablockstest/supplemental/bad-response-body.json +++ b/adapters/datablocks/datablockstest/supplemental/bad-response-body.json @@ -82,7 +82,7 @@ }], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/datablocks/datablockstest/supplemental/missing-ext.json b/adapters/datablocks/datablockstest/supplemental/missing-ext.json index 68d29e880b9..9e72e3cb6e5 100644 --- a/adapters/datablocks/datablockstest/supplemental/missing-ext.json +++ b/adapters/datablocks/datablockstest/supplemental/missing-ext.json @@ -18,8 +18,8 @@ "expectedMakeRequestsErrors": [ { - "value": "Missing bidder ext: unexpected end of JSON input", - "comparison": "literal" + "value": "Missing bidder ext: expect { or n, but found", + "comparison": "startswith" } ] diff --git a/adapters/decenterads/decenterads.go b/adapters/decenterads/decenterads.go index e4545466d5c..7981f60c976 100644 --- a/adapters/decenterads/decenterads.go +++ b/adapters/decenterads/decenterads.go @@ -8,10 +8,11 @@ import ( "strconv" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -28,7 +29,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, _ *adapters.ExtraRe for _, impression := range impressions { var impExt map[string]json.RawMessage - if err := json.Unmarshal(impression.Ext, &impExt); err != nil { + if err := jsonutil.Unmarshal(impression.Ext, &impExt); err != nil { errs = append(errs, fmt.Errorf("unable to parse bidder parameers: %s", err)) continue } @@ -78,7 +79,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, _ *adapters.RequestData } var bidResponse openrtb2.BidResponse - err := json.Unmarshal(responseData.Body, &bidResponse) + err := jsonutil.Unmarshal(responseData.Body, &bidResponse) if err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: err.Error(), diff --git a/adapters/decenterads/decenterads_test.go b/adapters/decenterads/decenterads_test.go index dfb5161b9c4..ba3cefa989d 100644 --- a/adapters/decenterads/decenterads_test.go +++ b/adapters/decenterads/decenterads_test.go @@ -3,9 +3,9 @@ package decenterads import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/decenterads/decenteradstest/supplemental/bad_response.json b/adapters/decenterads/decenteradstest/supplemental/bad_response.json index a6087b506a4..2eaaba4d21a 100644 --- a/adapters/decenterads/decenteradstest/supplemental/bad_response.json +++ b/adapters/decenterads/decenteradstest/supplemental/bad_response.json @@ -77,7 +77,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/decenterads/decenteradstest/supplemental/imp_ext_string.json b/adapters/decenterads/decenteradstest/supplemental/imp_ext_string.json index db938d6a652..4554cb531a7 100644 --- a/adapters/decenterads/decenteradstest/supplemental/imp_ext_string.json +++ b/adapters/decenterads/decenteradstest/supplemental/imp_ext_string.json @@ -30,7 +30,7 @@ }, "expectedMakeRequestsErrors": [ { - "value": "unable to parse bidder parameers: json: cannot unmarshal string into Go value of type map[string]json.RawMessage", + "value": "unable to parse bidder parameers: expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/decenterads/params_test.go b/adapters/decenterads/params_test.go index ef8b47cce41..7672892ed0d 100644 --- a/adapters/decenterads/params_test.go +++ b/adapters/decenterads/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // TestValidParams makes sure that the decenterads schema accepts all imp.ext fields which we intend to support. diff --git a/adapters/deepintent/deepintent.go b/adapters/deepintent/deepintent.go index 32f0d53ddf8..a1867cdadce 100644 --- a/adapters/deepintent/deepintent.go +++ b/adapters/deepintent/deepintent.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) const displayManager string = "di_prebid" @@ -41,14 +42,14 @@ func (d *DeepintentAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo * reqCopy.Imp = []openrtb2.Imp{imp} var bidderExt adapters.ExtImpBidder - if err = json.Unmarshal(reqCopy.Imp[0].Ext, &bidderExt); err != nil { + if err = jsonutil.Unmarshal(reqCopy.Imp[0].Ext, &bidderExt); err != nil { errs = append(errs, &errortypes.BadInput{ Message: fmt.Sprintf("Impression id=%s has an Error: %s", imp.ID, err.Error()), }) continue } - if err = json.Unmarshal(bidderExt.Bidder, &deepintentExt); err != nil { + if err = jsonutil.Unmarshal(bidderExt.Bidder, &deepintentExt); err != nil { errs = append(errs, &errortypes.BadInput{ Message: fmt.Sprintf("Impression id=%s, has invalid Ext", imp.ID), }) @@ -87,7 +88,7 @@ func (d *DeepintentAdapter) MakeBids(internalRequest *openrtb2.BidRequest, exter var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } diff --git a/adapters/deepintent/deepintent_test.go b/adapters/deepintent/deepintent_test.go index 9b2c92967b4..6b2d216db38 100644 --- a/adapters/deepintent/deepintent_test.go +++ b/adapters/deepintent/deepintent_test.go @@ -3,10 +3,10 @@ package deepintent import ( "testing" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/deepintent/deepintenttest/supplemental/bad_response.json b/adapters/deepintent/deepintenttest/supplemental/bad_response.json index 7c090732330..c86881f7e36 100644 --- a/adapters/deepintent/deepintenttest/supplemental/bad_response.json +++ b/adapters/deepintent/deepintenttest/supplemental/bad_response.json @@ -85,7 +85,7 @@ }], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/deepintent/deepintenttest/supplemental/no_ext-1.json b/adapters/deepintent/deepintenttest/supplemental/no_ext-1.json index 609c08e71ad..ba0c54018d7 100644 --- a/adapters/deepintent/deepintenttest/supplemental/no_ext-1.json +++ b/adapters/deepintent/deepintenttest/supplemental/no_ext-1.json @@ -22,7 +22,7 @@ }, "expectedMakeRequestsErrors": [ { - "value": "Impression id=test-banner-imp-id has an Error: json: cannot unmarshal string into Go value of type adapters.ExtImpBidder", + "value": "Impression id=test-banner-imp-id has an Error: expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/deepintent/deepintenttest/supplemental/no_ext.json b/adapters/deepintent/deepintenttest/supplemental/no_ext.json index f40257e4716..bf2fdf09f29 100644 --- a/adapters/deepintent/deepintenttest/supplemental/no_ext.json +++ b/adapters/deepintent/deepintenttest/supplemental/no_ext.json @@ -21,8 +21,8 @@ }, "expectedMakeRequestsErrors": [ { - "value": "Impression id=test-banner-imp-id has an Error: unexpected end of JSON input", - "comparison": "literal" + "value": "Impression id=test-banner-imp-id has an Error: expect { or n, but found", + "comparison": "startswith" } ] } diff --git a/adapters/deepintent/params_test.go b/adapters/deepintent/params_test.go index 4cd43b73ebe..b45eaa67a8c 100644 --- a/adapters/deepintent/params_test.go +++ b/adapters/deepintent/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // TestValidParams makes sure that the deepintent schema accepts all imp.ext fields which we intend to support. diff --git a/adapters/definemedia/definemedia.go b/adapters/definemedia/definemedia.go index 0bb4ff79e19..7f775b88c36 100644 --- a/adapters/definemedia/definemedia.go +++ b/adapters/definemedia/definemedia.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -62,7 +63,7 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } @@ -93,7 +94,7 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) { if bid.Ext != nil { var bidExt openrtb_ext.ExtBid - err := json.Unmarshal(bid.Ext, &bidExt) + err := jsonutil.Unmarshal(bid.Ext, &bidExt) if err == nil && bidExt.Prebid != nil { if (bidExt.Prebid.Type == openrtb_ext.BidTypeBanner) || (bidExt.Prebid.Type == openrtb_ext.BidTypeNative) { return openrtb_ext.ParseBidType(string(bidExt.Prebid.Type)) diff --git a/adapters/definemedia/definemedia_test.go b/adapters/definemedia/definemedia_test.go index 8a2a860d0c0..9d5b39b5b72 100644 --- a/adapters/definemedia/definemedia_test.go +++ b/adapters/definemedia/definemedia_test.go @@ -3,9 +3,9 @@ package definemedia import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/definemedia/definemediatest/supplemental/unmarshal-error.json b/adapters/definemedia/definemediatest/supplemental/unmarshal-error.json index ac03cc6e48c..532fab1224a 100644 --- a/adapters/definemedia/definemediatest/supplemental/unmarshal-error.json +++ b/adapters/definemedia/definemediatest/supplemental/unmarshal-error.json @@ -218,7 +218,7 @@ "expectedBidResponses": [], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/definemedia/params_test.go b/adapters/definemedia/params_test.go index 45b5be4eae5..bd3912719b3 100644 --- a/adapters/definemedia/params_test.go +++ b/adapters/definemedia/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/dianomi/dianomi.go b/adapters/dianomi/dianomi.go index 57cd85a27c3..5f16547de16 100644 --- a/adapters/dianomi/dianomi.go +++ b/adapters/dianomi/dianomi.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -36,7 +37,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte for _, imp := range request.Imp { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { errors = append(errors, &errortypes.BadInput{ Message: err.Error(), }) @@ -44,7 +45,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte } var dianomiImpExt openrtb_ext.ExtImpDianomi - if err := json.Unmarshal(bidderExt.Bidder, &dianomiImpExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &dianomiImpExt); err != nil { errors = append(errors, &errortypes.BadInput{ Message: err.Error(), }) @@ -65,7 +66,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte var err error if len(request.Ext) > 0 { - if err = json.Unmarshal(request.Ext, &requestExt); err != nil { + if err = jsonutil.Unmarshal(request.Ext, &requestExt); err != nil { errors = append(errors, err) } } @@ -121,7 +122,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } @@ -148,7 +149,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) { if bid.Ext != nil { var bidExt openrtb_ext.ExtBid - err := json.Unmarshal(bid.Ext, &bidExt) + err := jsonutil.Unmarshal(bid.Ext, &bidExt) if err == nil && bidExt.Prebid != nil { return openrtb_ext.ParseBidType(string(bidExt.Prebid.Type)) } diff --git a/adapters/dianomi/dianomi_test.go b/adapters/dianomi/dianomi_test.go index 1baa4b591b3..23a42fa69c7 100644 --- a/adapters/dianomi/dianomi_test.go +++ b/adapters/dianomi/dianomi_test.go @@ -3,9 +3,9 @@ package dianomi import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/dianomi/dianomitest/supplemental/unparsable-response.json b/adapters/dianomi/dianomitest/supplemental/unparsable-response.json index cf5ab4fca11..3bca23e3826 100644 --- a/adapters/dianomi/dianomitest/supplemental/unparsable-response.json +++ b/adapters/dianomi/dianomitest/supplemental/unparsable-response.json @@ -43,7 +43,7 @@ "expectedBidResponses": [], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/dianomi/params_test.go b/adapters/dianomi/params_test.go index 43a9bf6f4f5..294bfa977f9 100644 --- a/adapters/dianomi/params_test.go +++ b/adapters/dianomi/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/dianomi.json diff --git a/adapters/displayio/displayio.go b/adapters/displayio/displayio.go new file mode 100644 index 00000000000..cc9845d72f0 --- /dev/null +++ b/adapters/displayio/displayio.go @@ -0,0 +1,189 @@ +package displayio + +import ( + "encoding/json" + "errors" + "fmt" + "net/http" + "text/template" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" +) + +type adapter struct { + endpoint *template.Template +} + +type reqDioExt struct { + UserSession string `json:"userSession,omitempty"` + PlacementId string `json:"placementId"` + InventoryId string `json:"inventoryId"` +} + +func (adapter *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + headers.Add("Accept", "application/json") + headers.Add("x-openrtb-version", "2.5") + + result := make([]*adapters.RequestData, 0, len(request.Imp)) + errs := make([]error, 0, len(request.Imp)) + + for _, impression := range request.Imp { + var requestExt map[string]interface{} + + if impression.BidFloorCur == "" || impression.BidFloor == 0 { + impression.BidFloorCur = "USD" + } else if impression.BidFloorCur != "USD" { + convertedValue, err := requestInfo.ConvertCurrency(impression.BidFloor, impression.BidFloorCur, "USD") + + if err != nil { + errs = append(errs, err) + continue + } + + impression.BidFloor = convertedValue + impression.BidFloorCur = "USD" + } + + if len(impression.Ext) == 0 { + errs = append(errs, errors.New("impression extensions required")) + continue + } + + var bidderExt adapters.ExtImpBidder + err := jsonutil.Unmarshal(impression.Ext, &bidderExt) + + if err != nil { + errs = append(errs, err) + continue + } + + var impressionExt openrtb_ext.ExtImpDisplayio + err = jsonutil.Unmarshal(bidderExt.Bidder, &impressionExt) + if err != nil { + errs = append(errs, err) + continue + } + + dioExt := reqDioExt{PlacementId: impressionExt.PlacementId, InventoryId: impressionExt.InventoryId} + + requestCopy := *request + + err = jsonutil.Unmarshal(requestCopy.Ext, &requestExt) + if err != nil { + requestExt = make(map[string]interface{}) + } + + requestExt["displayio"] = dioExt + + requestCopy.Ext, err = json.Marshal(requestExt) + if err != nil { + errs = append(errs, err) + continue + } + + requestCopy.Imp = []openrtb2.Imp{impression} + body, err := json.Marshal(requestCopy) + if err != nil { + errs = append(errs, err) + continue + } + + url, err := adapter.buildEndpointURL(&impressionExt) + if err != nil { + return nil, []error{err} + } + + result = append(result, &adapters.RequestData{ + Method: "POST", + Uri: url, + Body: body, + Headers: headers, + ImpIDs: openrtb_ext.GetImpIDs(requestCopy.Imp), + }) + } + + if len(result) == 0 { + return nil, errs + } + return result, errs +} + +// MakeBids translates Displayio bid response to prebid-server specific format +func (adapter *adapter) MakeBids(internalRequest *openrtb2.BidRequest, _ *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { + + if adapters.IsResponseStatusCodeNoContent(responseData) { + return nil, nil + } + + if err := adapters.CheckResponseStatusCodeForErrors(responseData); err != nil { + return nil, []error{err} + } + + var bidResp openrtb2.BidResponse + + if err := jsonutil.Unmarshal(responseData.Body, &bidResp); err != nil { + msg := fmt.Sprintf("Bad server response: %d", err) + return nil, []error{&errortypes.BadServerResponse{Message: msg}} + } + + if len(bidResp.SeatBid) != 1 { + msg := fmt.Sprintf("Invalid SeatBids count: %d", len(bidResp.SeatBid)) + return nil, []error{&errortypes.BadServerResponse{Message: msg}} + } + + var errs []error + bidResponse := adapters.NewBidderResponse() + + for _, sb := range bidResp.SeatBid { + for i := range sb.Bid { + bidType, err := getBidMediaTypeFromMtype(&sb.Bid[i]) + if err != nil { + errs = append(errs, err) + } else { + b := &adapters.TypedBid{ + Bid: &sb.Bid[i], + BidType: bidType, + } + bidResponse.Bids = append(bidResponse.Bids, b) + } + } + } + + return bidResponse, errs +} + +func Builder(_ openrtb_ext.BidderName, config config.Adapter, _ config.Server) (adapters.Bidder, error) { + endpoint, err := template.New("endpointTemplate").Parse(config.Endpoint) + if err != nil { + return nil, fmt.Errorf("unable to parse endpoint url template: %v", err) + } + + bidder := &adapter{ + endpoint: endpoint, + } + return bidder, nil +} + +func getBidMediaTypeFromMtype(bid *openrtb2.Bid) (openrtb_ext.BidType, error) { + switch bid.MType { + case openrtb2.MarkupBanner: + return openrtb_ext.BidTypeBanner, nil + case openrtb2.MarkupVideo: + return openrtb_ext.BidTypeVideo, nil + default: + return "", fmt.Errorf("unexpected media type for bid: %s", bid.ImpID) + } +} + +func (adapter *adapter) buildEndpointURL(params *openrtb_ext.ExtImpDisplayio) (string, error) { + endpointParams := macros.EndpointTemplateParams{PublisherID: params.PublisherId} + return macros.ResolveMacros(adapter.endpoint, endpointParams) +} diff --git a/adapters/displayio/displayio_test.go b/adapters/displayio/displayio_test.go new file mode 100644 index 00000000000..b591abeb420 --- /dev/null +++ b/adapters/displayio/displayio_test.go @@ -0,0 +1,22 @@ +package displayio + +import ( + "testing" + + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderDisplayio, + config.Adapter{Endpoint: "https://adapter.endpoint/?macro={{.PublisherID}}"}, + config.Server{ExternalUrl: "https://server.endpoint/"}, + ) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "displayiotest", bidder) +} diff --git a/adapters/displayio/displayiotest/exemplary/multi-format.json b/adapters/displayio/displayiotest/exemplary/multi-format.json new file mode 100644 index 00000000000..c0e149a8c46 --- /dev/null +++ b/adapters/displayio/displayiotest/exemplary/multi-format.json @@ -0,0 +1,147 @@ +{ + "mockBidRequest": { + "id": "requestId10111011101110111011", + "app": { + "id": "1011" + }, + "imp": [ + { + "id": "impId10111011101110111011", + "tagid": "1011", + "ext": { + "bidder": { + "placementId": "1011", + "publisherId": "101", + "inventoryId": "1011" + } + }, + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 640, + "h": 480 + }, + "bidfloor": 0.5, + "bidfloorcur": "USD" + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://adapter.endpoint/?macro=101", + "body": { + "id": "requestId10111011101110111011", + "app": { + "id": "1011" + }, + "imp": [ + { + "id": "impId10111011101110111011", + "tagid": "1011", + "ext": { + "bidder": { + "placementId": "1011", + "publisherId": "101", + "inventoryId": "1011" + } + }, + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 640, + "h": 480 + }, + "bidfloor": 0.5, + "bidfloorcur": "USD" + } + ], + "ext": { + "displayio": { + "placementId": "1011", + "inventoryId": "1011" + } + } + }, + "impIDs": [ + "impId10111011101110111011" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "bidid": "5778926625248726496", + "seatbid": [ + { + "seat": "seat1", + "bid": [ + { + "id": "12345", + "impid": "impId10111011101110111011", + "price": 0.01, + "adm": "", + "adomain": [ + "domain.test" + ], + "w": 300, + "h": 250, + "mtype": 1 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "12345", + "impid": "impId10111011101110111011", + "price": 0.01, + "adm": "", + "adomain": [ + "domain.test" + ], + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/displayio/displayiotest/exemplary/multi-imp.json b/adapters/displayio/displayiotest/exemplary/multi-imp.json new file mode 100644 index 00000000000..8588ea5bf01 --- /dev/null +++ b/adapters/displayio/displayiotest/exemplary/multi-imp.json @@ -0,0 +1,211 @@ +{ + "mockBidRequest": { + "id": "test-request-multi-id", + "imp": [ + { + "id": "test-imp-id-1", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "placementId": "1010", + "publisherId": "2020", + "inventoryId": "3030" + } + }, + "bidfloor": 0.5 + }, + { + "id": "test-imp-id-2", + "banner": { + "format": [ + { + "w": 300, + "h": 150 + } + ] + }, + "ext": { + "bidder": { + "placementId": "4040", + "publisherId": "5050", + "inventoryId": "6060" + } + }, + "bidfloor": 0.5 + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://adapter.endpoint/?macro=2020", + "body": { + "id": "test-request-multi-id", + "imp": [ + { + "id": "test-imp-id-1", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "placementId": "1010", + "publisherId": "2020", + "inventoryId": "3030" + } + }, + "bidfloor": 0.5, + "bidfloorcur": "USD" + } + ], + "ext": { + "displayio": { + "placementId": "1010", + "inventoryId": "3030" + } + } + }, + "impIDs": [ + "test-imp-id-1" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-multi-id", + "seatbid": [ + { + "seat": "seat1", + "bid": [ + { + "id": "testid1", + "impid": "test-imp-id-1", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "crid_10", + "mtype": 1, + "h": 90, + "w": 728 + } + ] + } + ], + "cur": "USD" + } + } + }, + { + "expectedRequest": { + "uri": "https://adapter.endpoint/?macro=5050", + "body": { + "id": "test-request-multi-id", + "imp": [ + { + "id": "test-imp-id-2", + "banner": { + "format": [ + { + "w": 300, + "h": 150 + } + ] + }, + "ext": { + "bidder": { + "placementId": "4040", + "publisherId": "5050", + "inventoryId": "6060" + } + }, + "bidfloor": 0.5, + "bidfloorcur": "USD" + } + ], + "ext": { + "displayio": { + "placementId": "4040", + "inventoryId": "6060" + } + } + }, + "impIDs": [ + "test-imp-id-2" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-multi-id", + "seatbid": [ + { + "seat": "seat2", + "bid": [ + { + "id": "testid2", + "impid": "test-imp-id-2", + "price": 0.800000, + "adm": "some-test-ad", + "crid": "crid_11", + "mtype": 1, + "h": 150, + "w": 300 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "testid1", + "impid": "test-imp-id-1", + "price": 0.5, + "adm": "some-test-ad", + "crid": "crid_10", + "mtype": 1, + "w": 728, + "h": 90 + }, + "type": "banner" + } + ] + }, + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "testid2", + "impid": "test-imp-id-2", + "price": 0.8, + "adm": "some-test-ad", + "crid": "crid_11", + "mtype": 1, + "w": 300, + "h": 150 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/displayio/displayiotest/exemplary/simple-banner.json b/adapters/displayio/displayiotest/exemplary/simple-banner.json new file mode 100644 index 00000000000..15a5f913210 --- /dev/null +++ b/adapters/displayio/displayiotest/exemplary/simple-banner.json @@ -0,0 +1,117 @@ +{ + "mockBidRequest": { + "app": { + "id": "1011" + }, + "id": "requestId10111011101110111011", + "imp": [ + { + "banner": { + "h": 250, + "w": 300 + }, + "bidfloor": 0.225, + "bidfloorcur": "USD", + "id": "impId10111011101110111011", + "ext": { + "bidder": { + "placementId": "1011", + "publisherId": "101", + "inventoryId": "1011" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://adapter.endpoint/?macro=101", + "body": { + "id": "requestId10111011101110111011", + "app": { + "id": "1011" + }, + "imp": [ + { + "banner": { + "h": 250, + "w": 300 + }, + "bidfloor": 0.225, + "bidfloorcur": "USD", + "id": "impId10111011101110111011", + "ext": { + "bidder": { + "placementId": "1011", + "publisherId": "101", + "inventoryId": "1011" + } + } + } + ], + "ext": { + "displayio": { + "placementId": "1011", + "inventoryId": "1011" + } + } + }, + "impIDs": [ + "impId10111011101110111011" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "958", + "bid": [ + { + "id": "12345", + "impid": "impId10111011101110111011", + "price": 0.01, + "adm": "", + "adid": "12235", + "adomain": [ + "domain.test" + ], + "w": 300, + "h": 250, + "mtype": 1 + } + ] + } + ], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "12345", + "impid": "impId10111011101110111011", + "price": 0.01, + "adm": "", + "adid": "12235", + "adomain": [ + "domain.test" + ], + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/displayio/displayiotest/exemplary/simple-video.json b/adapters/displayio/displayiotest/exemplary/simple-video.json new file mode 100644 index 00000000000..b5d027f33ba --- /dev/null +++ b/adapters/displayio/displayiotest/exemplary/simple-video.json @@ -0,0 +1,124 @@ +{ + "mockBidRequest": { + "app": { + "id": "1011" + }, + "id": "requestId10111011101110111011", + "imp": [ + { + "video": { + "mimes": [ + "video/mp4" + ], + "w": 300, + "h": 250 + }, + "bidfloor": 0.5, + "bidfloorcur": "USD", + "id": "impId10111011101110111011", + "ext": { + "bidder": { + "placementId": "1011", + "publisherId": "101", + "inventoryId": "1011" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://adapter.endpoint/?macro=101", + "body": { + "app": { + "id": "1011" + }, + "id": "requestId10111011101110111011", + "imp": [ + { + "video": { + "mimes": [ + "video/mp4" + ], + "w": 300, + "h": 250 + }, + "bidfloor": 0.5, + "bidfloorcur": "USD", + "id": "impId10111011101110111011", + "ext": { + "bidder": { + "placementId": "1011", + "publisherId": "101", + "inventoryId": "1011" + } + } + } + ], + "ext": { + "displayio": { + "placementId": "1011", + "inventoryId": "1011" + } + } + }, + "impIDs": [ + "impId10111011101110111011" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "requestId10111011101110111011", + "seatbid": [ + { + "bid": [ + { + "id": "12345", + "impid": "impId10111011101110111011", + "price": 2, + "adm": "", + "adid": "12235", + "adomain": [ + "domain.test" + ], + "w": 300, + "h": 250, + "mtype": 2 + } + ], + "seat": "displayio123", + "group": 1 + } + ], + "bidid": "test123", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "12345", + "impid": "impId10111011101110111011", + "price": 2, + "adm": "", + "adid": "12235", + "adomain": [ + "domain.test" + ], + "w": 300, + "h": 250, + "mtype": 2 + }, + "type": "video" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/displayio/displayiotest/supplemental/bad-response.json b/adapters/displayio/displayiotest/supplemental/bad-response.json new file mode 100644 index 00000000000..98cc44e8626 --- /dev/null +++ b/adapters/displayio/displayiotest/supplemental/bad-response.json @@ -0,0 +1,77 @@ +{ + "mockBidRequest": { + "id": "testid", + "imp": [ + { + "id": "testimpid", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "bidfloor": 0.01, + "ext": { + "bidder": { + "placementId": "1101", + "inventoryId": "1101", + "publisherId": "101" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://adapter.endpoint/?macro=101", + "body": { + "id": "testid", + "imp": [ + { + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "id": "testimpid", + "bidfloor": 0.01, + "bidfloorcur": "USD", + "ext": { + "bidder": { + "placementId": "1101", + "inventoryId": "1101", + "publisherId": "101" + } + } + } + ], + "ext": { + "displayio": { + "placementId": "1101", + "inventoryId": "1101" + } + } + }, + "impIDs": [ + "testimpid" + ] + }, + "mockResponse": { + "status": 200, + "body": "" + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Bad server response: .*", + "comparison": "regex" + } + ] +} \ No newline at end of file diff --git a/adapters/displayio/displayiotest/supplemental/currency-conversion.json b/adapters/displayio/displayiotest/supplemental/currency-conversion.json new file mode 100644 index 00000000000..32b6b2a16b4 --- /dev/null +++ b/adapters/displayio/displayiotest/supplemental/currency-conversion.json @@ -0,0 +1,95 @@ +{ + "mockBidRequest": { + "id": "testid", + "imp": [ + { + "id": "testimpid", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": "1101", + "inventoryId": "1101", + "publisherId": "101" + } + }, + "bidfloor": 100, + "bidfloorcur": "RUB" + } + ], + "ext": { + "prebid": { + "currency": { + "rates": { + "RUB": { + "USD": 0.01 + } + }, + "usepbsrates": false + } + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://adapter.endpoint/?macro=101", + "body": { + "id": "testid", + "imp": [ + { + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "id": "testimpid", + "bidfloorcur": "USD", + "bidfloor": 1, + "ext": { + "bidder": { + "placementId": "1101", + "inventoryId": "1101", + "publisherId": "101" + } + } + } + ], + "ext": { + "displayio": { + "placementId": "1101", + "inventoryId": "1101" + }, + "prebid": { + "currency": { + "rates": { + "RUB": { + "USD": 0.01 + } + }, + "usepbsrates": false + } + } + } + }, + "impIDs": [ + "testimpid" + ] + }, + "mockResponse": { + "status": 204 + } + } + ], + "expectedMakeRequestsErrors": [], + "expectedBidResponses": [] +} \ No newline at end of file diff --git a/adapters/displayio/displayiotest/supplemental/ext.json b/adapters/displayio/displayiotest/supplemental/ext.json new file mode 100644 index 00000000000..ad0835d1c61 --- /dev/null +++ b/adapters/displayio/displayiotest/supplemental/ext.json @@ -0,0 +1,30 @@ +{ + "mockBidRequest": { + "id": "testid", + "imp": [ + { + "id": "testimpid", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 320, + "h": 50 + } + ] + }, + "bidfloor": 0.5, + "bidfloorcur": "USD" + } + ] + }, + "expectedMakeRequestsErrors": [ + { + "value": "impression extensions required", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/displayio/displayiotest/supplemental/nobid-response.json b/adapters/displayio/displayiotest/supplemental/nobid-response.json new file mode 100644 index 00000000000..ccfb2c12ca8 --- /dev/null +++ b/adapters/displayio/displayiotest/supplemental/nobid-response.json @@ -0,0 +1,72 @@ +{ + "mockBidRequest": { + "id": "testid", + "imp": [ + { + "id": "testimpid", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": "1101", + "inventoryId": "1101", + "publisherId": "101" + } + }, + "bidfloor": 0.5, + "bidfloorcur": "USD" + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://adapter.endpoint/?macro=101", + "body": { + "id": "testid", + "imp": [ + { + "id": "testimpid", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "bidder": { + "placementId": "1101", + "inventoryId": "1101", + "publisherId": "101" + } + }, + "bidfloor": 0.5, + "bidfloorcur": "USD" + } + ], + "ext": { + "displayio": { + "placementId": "1101", + "inventoryId": "1101" + } + } + }, + "impIDs": [ + "testimpid" + ] + }, + "mockResponse": { + "status": 204 + } + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/displayio/displayiotest/supplemental/response-code-invalid.json b/adapters/displayio/displayiotest/supplemental/response-code-invalid.json new file mode 100644 index 00000000000..4bfa579c672 --- /dev/null +++ b/adapters/displayio/displayiotest/supplemental/response-code-invalid.json @@ -0,0 +1,74 @@ +{ + "mockBidRequest": { + "id": "testid", + "imp": [ + { + "id": "testimpid", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "bidfloor": 0.01, + "ext": { + "bidder": { + "placementId": "1101", + "inventoryId": "1101", + "publisherId": "101" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://adapter.endpoint/?macro=101", + "body": { + "id": "testid", + "imp": [ + { + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "id": "testimpid", + "ext": { + "bidder": { + "placementId": "1101", + "inventoryId": "1101", + "publisherId": "101" + } + } + } + ], + "ext": { + "displayio": { + "placementId": "1101", + "inventoryId": "1101" + } + } + }, + "impIDs":["testimpid"] + }, + "mockResponse": { + "status": 400 + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: [0-9]{3,3}. Run with request.debug = 1 for more info", + "comparison": "regex" + } + ] +} \ No newline at end of file diff --git a/adapters/displayio/displayiotest/supplemental/seatbid-response.json b/adapters/displayio/displayiotest/supplemental/seatbid-response.json new file mode 100644 index 00000000000..f0467d1f0bb --- /dev/null +++ b/adapters/displayio/displayiotest/supplemental/seatbid-response.json @@ -0,0 +1,77 @@ +{ + "mockBidRequest": { + "id": "testid", + "imp": [ + { + "id": "testimpid", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "bidfloor": 0.01, + "ext": { + "bidder": { + "placementId": "1101", + "inventoryId": "1101", + "publisherId": "101" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://adapter.endpoint/?macro=101", + "body": { + "id": "testid", + "imp": [ + { + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "id": "testimpid", + "bidfloor": 0.01, + "bidfloorcur": "USD", + "ext": { + "bidder": { + "placementId": "1101", + "inventoryId": "1101", + "publisherId": "101" + } + } + } + ], + "ext": { + "displayio": { + "placementId": "1101", + "inventoryId": "1101" + } + } + }, + "impIDs":["testimpid"] + }, + "mockResponse": { + "status": 200, + "body": { + "seatbid": [] + } + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Invalid SeatBids count: 0", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/displayio/displayiotest/supplemental/unexpected-media-type.json b/adapters/displayio/displayiotest/supplemental/unexpected-media-type.json new file mode 100644 index 00000000000..be66747a4c4 --- /dev/null +++ b/adapters/displayio/displayiotest/supplemental/unexpected-media-type.json @@ -0,0 +1,105 @@ +{ + "mockBidRequest": { + "app": { + "id": "1011" + }, + "id": "requestId10111011101110111011", + "imp": [ + { + "banner": { + "h": 250, + "w": 300 + }, + "bidfloor": 0.225, + "bidfloorcur": "USD", + "id": "impId10111011101110111011", + "ext": { + "bidder": { + "placementId": "1011", + "publisherId": "101", + "inventoryId": "1011" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://adapter.endpoint/?macro=101", + "body": { + "id": "requestId10111011101110111011", + "app": { + "id": "1011" + }, + "imp": [ + { + "banner": { + "h": 250, + "w": 300 + }, + "bidfloor": 0.225, + "bidfloorcur": "USD", + "id": "impId10111011101110111011", + "ext": { + "bidder": { + "placementId": "1011", + "publisherId": "101", + "inventoryId": "1011" + } + } + } + ], + "ext": { + "displayio": { + "placementId": "1011", + "inventoryId": "1011" + } + } + }, + "impIDs": [ + "impId10111011101110111011" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "958", + "bid": [ + { + "id": "12345", + "impid": "impId10111011101110111011", + "price": 0.01, + "adm": "", + "adomain": [ + "domain.test" + ], + "w": 300, + "h": 250, + "mtype": 5 + } + ] + } + ], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [] + } + ], + "expectedMakeBidsErrors": [ + { + "value": "unexpected media type for bid: .*", + "comparison": "regex" + } + ] +} \ No newline at end of file diff --git a/adapters/displayio/params_test.go b/adapters/displayio/params_test.go new file mode 100644 index 00000000000..2e44954072b --- /dev/null +++ b/adapters/displayio/params_test.go @@ -0,0 +1,48 @@ +package displayio + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v3/openrtb_ext" +) + +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schemas. %v", err) + } + + for _, validParam := range validParams { + if err := validator.Validate(openrtb_ext.BidderDisplayio, json.RawMessage(validParam)); err != nil { + t.Errorf("Schema rejected dmx params: %s", validParam) + } + } + for _, invalidParam := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderDisplayio, json.RawMessage(invalidParam)); err == nil { + t.Errorf("Schema was not supposed to be valid: %s", invalidParam) + } + } +} + +var validParams = []string{ + `{"placementId": "anyPlacementId", "publisherId":"anyPublisherId", "inventoryId":"anyInventoryId"}`, +} + +var invalidParams = []string{ + `null`, + `nil`, + ``, + `[]`, + `true`, + `{}`, + `{"placementId": 1, "publisherId":"anyPublisherId", "inventoryId":"anyInventoryId"}`, + `{"placementId": "anyPlacementId", "publisherId":1, "inventoryId":"anyInventoryId"}`, + `{"placementId": "anyPlacementId", "publisherId":"anyPublisherId", "inventoryId":1}`, + `{"publisherId":"anyPublisherId", "inventoryId":"anyInventoryId"}`, + `{"placementId": "anyPlacementId", "inventoryId":"anyInventoryId"}`, + `{"placementId": "anyPlacementId", "publisherId":"anyPublisherId"}`, + `{"placementId": "anyPlacementId"}`, + `{"inventoryId":"anyInventoryId"}`, + `{"publisherId":"anyPublisherId"}`, +} diff --git a/adapters/dmx/dmx.go b/adapters/dmx/dmx.go index 0ad522c4398..458b497826b 100644 --- a/adapters/dmx/dmx.go +++ b/adapters/dmx/dmx.go @@ -10,10 +10,11 @@ import ( "github.com/prebid/openrtb/v20/adcom1" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type DmxAdapter struct { @@ -75,7 +76,7 @@ func (adapter *DmxAdapter) MakeRequests(request *openrtb2.BidRequest, req *adapt } if len(request.Imp) >= 1 { - err := json.Unmarshal(request.Imp[0].Ext, &rootExtInfo) + err := jsonutil.Unmarshal(request.Imp[0].Ext, &rootExtInfo) if err != nil { errs = append(errs, err) } else { @@ -148,7 +149,7 @@ func (adapter *DmxAdapter) MakeRequests(request *openrtb2.BidRequest, req *adapt hasNoID = false } if dmxReq.User.Ext != nil { - if err := json.Unmarshal(dmxReq.User.Ext, &userExt); err == nil { + if err := jsonutil.Unmarshal(dmxReq.User.Ext, &userExt); err == nil { if len(userExt.Eids) > 0 { hasNoID = false } @@ -161,7 +162,7 @@ func (adapter *DmxAdapter) MakeRequests(request *openrtb2.BidRequest, req *adapt var params dmxExt const intVal int8 = 1 source := (*json.RawMessage)(&inst.Ext) - if err := json.Unmarshal(*source, ¶ms); err != nil { + if err := jsonutil.Unmarshal(*source, ¶ms); err != nil { errs = append(errs, err) } if isDmxParams(params.Bidder) { @@ -236,7 +237,7 @@ func (adapter *DmxAdapter) MakeBids(request *openrtb2.BidRequest, externalReques var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } diff --git a/adapters/dmx/dmx_test.go b/adapters/dmx/dmx_test.go index 8d9b2dc6541..cc46d28f318 100644 --- a/adapters/dmx/dmx_test.go +++ b/adapters/dmx/dmx_test.go @@ -6,11 +6,11 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" ) func TestFetchParams(t *testing.T) { diff --git a/adapters/dmx/params_test.go b/adapters/dmx/params_test.go index 4470fb23057..49d89b330fa 100644 --- a/adapters/dmx/params_test.go +++ b/adapters/dmx/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/driftpixel/driftpixel.go b/adapters/driftpixel/driftpixel.go index e756b03de70..65532a786cc 100644 --- a/adapters/driftpixel/driftpixel.go +++ b/adapters/driftpixel/driftpixel.go @@ -7,11 +7,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type bidType struct { @@ -41,14 +42,14 @@ func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server co func (a *adapter) buildEndpointFromRequest(imp *openrtb2.Imp) (string, error) { var impExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &impExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &impExt); err != nil { return "", &errortypes.BadInput{ Message: fmt.Sprintf("Failed to deserialize bidder impression extension: %v", err), } } var driftpixelExt openrtb_ext.ExtDriftPixel - if err := json.Unmarshal(impExt.Bidder, &driftpixelExt); err != nil { + if err := jsonutil.Unmarshal(impExt.Bidder, &driftpixelExt); err != nil { return "", &errortypes.BadInput{ Message: fmt.Sprintf("Failed to deserialize DriftPixel extension: %v", err), } @@ -110,7 +111,7 @@ func (a *adapter) MakeBids(openRTBRequest *openrtb2.BidRequest, requestToBidder } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(bidderRawResponse.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(bidderRawResponse.Body, &bidResp); err != nil { return nil, []error{err} } diff --git a/adapters/driftpixel/driftpixel_test.go b/adapters/driftpixel/driftpixel_test.go index ac9268f2306..24bf8b15066 100644 --- a/adapters/driftpixel/driftpixel_test.go +++ b/adapters/driftpixel/driftpixel_test.go @@ -3,9 +3,9 @@ package driftpixel import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/driftpixel/driftpixeltest/supplemental/bad-response.json b/adapters/driftpixel/driftpixeltest/supplemental/bad-response.json index 109e51ed4df..b5811eb2e5f 100644 --- a/adapters/driftpixel/driftpixeltest/supplemental/bad-response.json +++ b/adapters/driftpixel/driftpixeltest/supplemental/bad-response.json @@ -99,7 +99,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ], diff --git a/adapters/driftpixel/driftpixeltest/supplemental/invalid-ext-bidder-object.json b/adapters/driftpixel/driftpixeltest/supplemental/invalid-ext-bidder-object.json index 1b812955b1d..685b659ea9a 100644 --- a/adapters/driftpixel/driftpixeltest/supplemental/invalid-ext-bidder-object.json +++ b/adapters/driftpixel/driftpixeltest/supplemental/invalid-ext-bidder-object.json @@ -42,7 +42,7 @@ "httpCalls": [], "expectedMakeRequestsErrors": [ { - "value": "Failed to deserialize DriftPixel extension: json: cannot unmarshal array into Go value of type openrtb_ext.ExtDriftPixel", + "value": "Failed to deserialize DriftPixel extension: expect { or n, but found [", "comparison": "literal" } ] diff --git a/adapters/driftpixel/driftpixeltest/supplemental/invalid-ext-object.json b/adapters/driftpixel/driftpixeltest/supplemental/invalid-ext-object.json index aa215eb3e34..16cf58bbe54 100644 --- a/adapters/driftpixel/driftpixeltest/supplemental/invalid-ext-object.json +++ b/adapters/driftpixel/driftpixeltest/supplemental/invalid-ext-object.json @@ -40,7 +40,7 @@ "httpCalls": [], "expectedMakeRequestsErrors": [ { - "value": "Failed to deserialize bidder impression extension: json: cannot unmarshal string into Go value of type adapters.ExtImpBidder", + "value": "Failed to deserialize bidder impression extension: expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/driftpixel/params_test.go b/adapters/driftpixel/params_test.go index 1470384698b..e8153f054ce 100644 --- a/adapters/driftpixel/params_test.go +++ b/adapters/driftpixel/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/dxkulture/dxkulture.go b/adapters/dxkulture/dxkulture.go index 90fb341f533..6b4bfa40031 100644 --- a/adapters/dxkulture/dxkulture.go +++ b/adapters/dxkulture/dxkulture.go @@ -6,10 +6,11 @@ import ( "net/http" "net/url" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" "github.com/prebid/openrtb/v20/openrtb2" ) @@ -81,7 +82,7 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest } var ortbResponse openrtb2.BidResponse - err := json.Unmarshal(response.Body, &ortbResponse) + err := jsonutil.Unmarshal(response.Body, &ortbResponse) if err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: "Bad Server Response", @@ -122,14 +123,14 @@ func getBidType(bid *openrtb2.Bid) (openrtb_ext.BidType, error) { func parseExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpDXKulture, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: fmt.Sprintf("Ignoring imp id=%s, error while decoding extImpBidder, err: %s", imp.ID, err), } } impExt := openrtb_ext.ExtImpDXKulture{} - err := json.Unmarshal(bidderExt.Bidder, &impExt) + err := jsonutil.Unmarshal(bidderExt.Bidder, &impExt) if err != nil { return nil, &errortypes.BadInput{ Message: fmt.Sprintf("Ignoring imp id=%s, error while decoding impExt, err: %s", imp.ID, err), diff --git a/adapters/dxkulture/dxkulture_test.go b/adapters/dxkulture/dxkulture_test.go index 7344d5a9d51..2ee176968b9 100644 --- a/adapters/dxkulture/dxkulture_test.go +++ b/adapters/dxkulture/dxkulture_test.go @@ -3,9 +3,9 @@ package dxkulture import ( "testing" - "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/dxkulture/dxkulturetest/supplemental/invalid-imp-ext-bidder.json b/adapters/dxkulture/dxkulturetest/supplemental/invalid-imp-ext-bidder.json index ae30b327030..c60c6080577 100644 --- a/adapters/dxkulture/dxkulturetest/supplemental/invalid-imp-ext-bidder.json +++ b/adapters/dxkulture/dxkulturetest/supplemental/invalid-imp-ext-bidder.json @@ -33,7 +33,7 @@ }, "expectedMakeRequestsErrors": [ { - "value": "Ignoring imp id=test-imp-id, error while decoding impExt, err: json: cannot unmarshal string into Go value of type openrtb_ext.ExtImpDXKulture", + "value": "Ignoring imp id=test-imp-id, error while decoding impExt, err: expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/dxkulture/dxkulturetest/supplemental/invalid-imp-ext.json b/adapters/dxkulture/dxkulturetest/supplemental/invalid-imp-ext.json index 2587dc216d2..379acd586cc 100644 --- a/adapters/dxkulture/dxkulturetest/supplemental/invalid-imp-ext.json +++ b/adapters/dxkulture/dxkulturetest/supplemental/invalid-imp-ext.json @@ -31,7 +31,7 @@ }, "expectedMakeRequestsErrors": [ { - "value": "Ignoring imp id=test-imp-id, error while decoding extImpBidder, err: json: cannot unmarshal string into Go value of type adapters.ExtImpBidder", + "value": "Ignoring imp id=test-imp-id, error while decoding extImpBidder, err: expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/dxkulture/params_test.go b/adapters/dxkulture/params_test.go index d1c2f91a7ce..c7997f1862e 100644 --- a/adapters/dxkulture/params_test.go +++ b/adapters/dxkulture/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/dxkulture.json diff --git a/adapters/e_volution/evolution.go b/adapters/e_volution/evolution.go index 89ab5e0994c..1b781c74051 100644 --- a/adapters/e_volution/evolution.go +++ b/adapters/e_volution/evolution.go @@ -7,10 +7,11 @@ import ( "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -84,7 +85,7 @@ func (a *adapter) MakeBids( responseBody := bidderRawResponse.Body var bidResp openrtb2.BidResponse - if err := json.Unmarshal(responseBody, &bidResp); err != nil { + if err := jsonutil.Unmarshal(responseBody, &bidResp); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: fmt.Sprintf("Bad response, %s", err), }} @@ -101,7 +102,7 @@ func (a *adapter) MakeBids( for i := range sb.Bid { var bidType openrtb_ext.BidType var bidExt bidExt - if err := json.Unmarshal(sb.Bid[i].Ext, &bidExt); err != nil { + if err := jsonutil.Unmarshal(sb.Bid[i].Ext, &bidExt); err != nil { bidType = openrtb_ext.BidTypeBanner } else { bidType = bidExt.MediaType diff --git a/adapters/e_volution/evolution_test.go b/adapters/e_volution/evolution_test.go index 4529a742077..6a3dbe671e1 100644 --- a/adapters/e_volution/evolution_test.go +++ b/adapters/e_volution/evolution_test.go @@ -3,9 +3,9 @@ package evolution import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/e_volution/evolutiontest/supplemental/bad-response.json b/adapters/e_volution/evolutiontest/supplemental/bad-response.json index d30a01e3158..0878829ca1b 100644 --- a/adapters/e_volution/evolutiontest/supplemental/bad-response.json +++ b/adapters/e_volution/evolutiontest/supplemental/bad-response.json @@ -150,7 +150,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "Bad response, json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "Bad response, expect { or n, but found \"", "comparison": "literal" } ], diff --git a/adapters/e_volution/params_test.go b/adapters/e_volution/params_test.go index 6049bce7780..98558f88abf 100644 --- a/adapters/e_volution/params_test.go +++ b/adapters/e_volution/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/edge226/edge226.go b/adapters/edge226/edge226.go index 0859da1df67..19804c88436 100644 --- a/adapters/edge226/edge226.go +++ b/adapters/edge226/edge226.go @@ -6,9 +6,10 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -43,10 +44,10 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E var bidderExt adapters.ExtImpBidder var edge226Ext openrtb_ext.ImpExtEdge226 - if err = json.Unmarshal(reqCopy.Imp[0].Ext, &bidderExt); err != nil { + if err = jsonutil.Unmarshal(reqCopy.Imp[0].Ext, &bidderExt); err != nil { return nil, []error{err} } - if err = json.Unmarshal(bidderExt.Bidder, &edge226Ext); err != nil { + if err = jsonutil.Unmarshal(bidderExt.Bidder, &edge226Ext); err != nil { return nil, []error{err} } @@ -107,7 +108,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } diff --git a/adapters/edge226/edge226_test.go b/adapters/edge226/edge226_test.go index fea4abff1a9..cd3d9385aba 100644 --- a/adapters/edge226/edge226_test.go +++ b/adapters/edge226/edge226_test.go @@ -3,9 +3,9 @@ package edge226 import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/edge226/edge226test/supplemental/bad_response.json b/adapters/edge226/edge226test/supplemental/bad_response.json index aa37c31f5b1..7ea65762bdb 100644 --- a/adapters/edge226/edge226test/supplemental/bad_response.json +++ b/adapters/edge226/edge226test/supplemental/bad_response.json @@ -78,7 +78,7 @@ }], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/edge226/params_test.go b/adapters/edge226/params_test.go index 21a83bd65fd..5161c349d7d 100644 --- a/adapters/edge226/params_test.go +++ b/adapters/edge226/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/emtv/emtv.go b/adapters/emtv/emtv.go index f361010ebbe..c8814f80656 100644 --- a/adapters/emtv/emtv.go +++ b/adapters/emtv/emtv.go @@ -7,10 +7,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -45,10 +46,10 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E var bidderExt adapters.ExtImpBidder var emtvExt openrtb_ext.ImpExtEmtv - if err = json.Unmarshal(reqCopy.Imp[0].Ext, &bidderExt); err != nil { + if err = jsonutil.Unmarshal(reqCopy.Imp[0].Ext, &bidderExt); err != nil { return nil, []error{err} } - if err = json.Unmarshal(bidderExt.Bidder, &emtvExt); err != nil { + if err = jsonutil.Unmarshal(bidderExt.Bidder, &emtvExt); err != nil { return nil, []error{err} } @@ -116,7 +117,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } diff --git a/adapters/emtv/emtv_test.go b/adapters/emtv/emtv_test.go index 238e463a0d5..0dd4196af48 100644 --- a/adapters/emtv/emtv_test.go +++ b/adapters/emtv/emtv_test.go @@ -3,9 +3,9 @@ package emtv import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/emtv/emtvtest/supplemental/bad_response.json b/adapters/emtv/emtvtest/supplemental/bad_response.json index c732ba92c67..5cc4a338ac3 100644 --- a/adapters/emtv/emtvtest/supplemental/bad_response.json +++ b/adapters/emtv/emtvtest/supplemental/bad_response.json @@ -78,7 +78,7 @@ }], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/emtv/params_test.go b/adapters/emtv/params_test.go index 40769b97942..cdea31b075b 100644 --- a/adapters/emtv/params_test.go +++ b/adapters/emtv/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/eplanning/eplanning.go b/adapters/eplanning/eplanning.go index 25a44cdd44f..dc8ab900ea3 100644 --- a/adapters/eplanning/eplanning.go +++ b/adapters/eplanning/eplanning.go @@ -1,7 +1,6 @@ package eplanning import ( - "encoding/json" "math/rand" "net/http" "net/url" @@ -13,10 +12,11 @@ import ( "github.com/prebid/openrtb/v20/adcom1" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" "strconv" ) @@ -243,7 +243,7 @@ func cleanName(name string) string { func verifyImp(imp *openrtb2.Imp, isMobile bool, impType int) (*openrtb_ext.ExtImpEPlanning, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: fmt.Sprintf("Ignoring imp id=%s, error while decoding extImpBidder, err: %s", imp.ID, err), } @@ -268,7 +268,7 @@ func verifyImp(imp *openrtb2.Imp, isMobile bool, impType int) (*openrtb_ext.ExtI } impExt := openrtb_ext.ExtImpEPlanning{} - err := json.Unmarshal(bidderExt.Bidder, &impExt) + err := jsonutil.Unmarshal(bidderExt.Bidder, &impExt) if err != nil { return nil, &errortypes.BadInput{ Message: fmt.Sprintf("Ignoring imp id=%s, error while decoding impExt, err: %s", imp.ID, err), @@ -364,7 +364,7 @@ func (adapter *EPlanningAdapter) MakeBids(internalRequest *openrtb2.BidRequest, } var parsedResponse hbResponse - if err := json.Unmarshal(response.Body, &parsedResponse); err != nil { + if err := jsonutil.Unmarshal(response.Body, &parsedResponse); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: fmt.Sprintf("Error unmarshaling HB response: %s", err.Error()), }} diff --git a/adapters/eplanning/eplanning_test.go b/adapters/eplanning/eplanning_test.go index 44ab91413d4..1d220184c6b 100644 --- a/adapters/eplanning/eplanning_test.go +++ b/adapters/eplanning/eplanning_test.go @@ -3,10 +3,10 @@ package eplanning import ( "testing" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/eplanning/eplanningtest/supplemental/bad-imp-ext.json b/adapters/eplanning/eplanningtest/supplemental/bad-imp-ext.json index 475adfd95ac..572349a4e1d 100644 --- a/adapters/eplanning/eplanningtest/supplemental/bad-imp-ext.json +++ b/adapters/eplanning/eplanningtest/supplemental/bad-imp-ext.json @@ -19,7 +19,7 @@ }, "expectedMakeRequestsErrors": [ { - "value": "Ignoring imp id=test-imp-id, error while decoding impExt, err: json: cannot unmarshal number into Go struct field ExtImpEPlanning.ci of type string", + "value": "Ignoring imp id=test-imp-id, error while decoding impExt, err: cannot unmarshal openrtb_ext.ExtImpEPlanning.ClientID: expects \" or n, but found 1", "comparison": "literal" } ] diff --git a/adapters/eplanning/eplanningtest/supplemental/invalid-response-unmarshall-error.json b/adapters/eplanning/eplanningtest/supplemental/invalid-response-unmarshall-error.json index e507648206d..3c1b08ae6bd 100644 --- a/adapters/eplanning/eplanningtest/supplemental/invalid-response-unmarshall-error.json +++ b/adapters/eplanning/eplanningtest/supplemental/invalid-response-unmarshall-error.json @@ -48,8 +48,8 @@ "expectedMakeBidsErrors": [ { - "value": "Error unmarshaling HB response: json: cannot unmarshal string into Go struct field (hbResponseAd\\.sp\\.a\\.w|hbResponseAd\\.w) of type uint64", - "comparison": "regex" + "value": "Error unmarshaling HB response: cannot unmarshal eplanning.hbResponseAd.Width: unexpected character", + "comparison": "startswith" } ] } diff --git a/adapters/epom/epom.go b/adapters/epom/epom.go index 0bee7c33e3d..82e44b409e3 100644 --- a/adapters/epom/epom.go +++ b/adapters/epom/epom.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -86,7 +87,7 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } diff --git a/adapters/epom/epom_test.go b/adapters/epom/epom_test.go index 4e31c2ab982..f90f2189d57 100644 --- a/adapters/epom/epom_test.go +++ b/adapters/epom/epom_test.go @@ -3,9 +3,9 @@ package epom import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/escalax/escalax.go b/adapters/escalax/escalax.go new file mode 100644 index 00000000000..867524a9225 --- /dev/null +++ b/adapters/escalax/escalax.go @@ -0,0 +1,163 @@ +package escalax + +import ( + "encoding/json" + "fmt" + "net/http" + "text/template" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" +) + +type adapter struct { + endpoint *template.Template +} + +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + template, err := template.New("endpointTemplate").Parse(config.Endpoint) + if err != nil { + return nil, fmt.Errorf("unable to parse endpoint url template: %v", err) + } + + bidder := &adapter{ + endpoint: template, + } + return bidder, nil +} + +func getHeaders(request *openrtb2.BidRequest) http.Header { + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + headers.Add("Accept", "application/json") + headers.Add("X-Openrtb-Version", "2.5") + + if request.Device != nil { + if len(request.Device.UA) > 0 { + headers.Add("User-Agent", request.Device.UA) + } + + if len(request.Device.IPv6) > 0 { + headers.Add("X-Forwarded-For", request.Device.IPv6) + } + + if len(request.Device.IP) > 0 { + headers.Add("X-Forwarded-For", request.Device.IP) + } + } + + return headers +} + +func (a *adapter) MakeRequests(openRTBRequest *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) (requestsToBidder []*adapters.RequestData, errs []error) { + escalaxExt, err := getImpressionExt(&openRTBRequest.Imp[0]) + if err != nil { + return nil, []error{err} + } + + openRTBRequest.Imp[0].Ext = nil + + url, err := a.buildEndpointURL(escalaxExt) + if err != nil { + return nil, []error{err} + } + + reqJSON, err := json.Marshal(openRTBRequest) + if err != nil { + return nil, []error{err} + } + + return []*adapters.RequestData{{ + Method: http.MethodPost, + Body: reqJSON, + Uri: url, + Headers: getHeaders(openRTBRequest), + ImpIDs: openrtb_ext.GetImpIDs(openRTBRequest.Imp), + }}, nil +} + +func getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtEscalax, error) { + var bidderExt adapters.ExtImpBidder + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { + return nil, &errortypes.BadInput{ + Message: "Error parsing escalaxExt - " + err.Error(), + } + } + var escalaxExt openrtb_ext.ExtEscalax + if err := jsonutil.Unmarshal(bidderExt.Bidder, &escalaxExt); err != nil { + return nil, &errortypes.BadInput{ + Message: "Error parsing bidderExt - " + err.Error(), + } + } + + return &escalaxExt, nil +} + +func (a *adapter) buildEndpointURL(params *openrtb_ext.ExtEscalax) (string, error) { + endpointParams := macros.EndpointTemplateParams{AccountID: params.AccountID, SourceId: params.SourceID} + return macros.ResolveMacros(a.endpoint, endpointParams) +} + +func (a *adapter) MakeBids(openRTBRequest *openrtb2.BidRequest, requestToBidder *adapters.RequestData, bidderRawResponse *adapters.ResponseData) (bidderResponse *adapters.BidderResponse, errs []error) { + if adapters.IsResponseStatusCodeNoContent(bidderRawResponse) { + return nil, nil + } + + if err := adapters.CheckResponseStatusCodeForErrors(bidderRawResponse); err != nil { + return nil, []error{err} + } + + responseBody := bidderRawResponse.Body + var bidResp openrtb2.BidResponse + if err := jsonutil.Unmarshal(responseBody, &bidResp); err != nil { + return nil, []error{&errortypes.BadServerResponse{ + Message: "Bad Server Response", + }} + } + + if len(bidResp.SeatBid) == 0 { + return nil, []error{&errortypes.BadServerResponse{ + Message: "Empty SeatBid array", + }} + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(5) + var bidsArray []*adapters.TypedBid + + for _, sb := range bidResp.SeatBid { + for idx, bid := range sb.Bid { + bidType, err := determineImpressionMediaType(bid) + if err != nil { + return nil, []error{err} + } + + bidsArray = append(bidsArray, &adapters.TypedBid{ + Bid: &sb.Bid[idx], + BidType: bidType, + }) + } + } + + bidResponse.Bids = bidsArray + return bidResponse, nil +} + +func determineImpressionMediaType(bid openrtb2.Bid) (openrtb_ext.BidType, error) { + switch bid.MType { + case openrtb2.MarkupBanner: + return openrtb_ext.BidTypeBanner, nil + case openrtb2.MarkupVideo: + return openrtb_ext.BidTypeVideo, nil + case openrtb2.MarkupNative: + return openrtb_ext.BidTypeNative, nil + default: + return "", &errortypes.BadInput{ + Message: fmt.Sprintf("unsupported MType %d", bid.MType), + } + } +} diff --git a/adapters/escalax/escalax_test.go b/adapters/escalax/escalax_test.go new file mode 100644 index 00000000000..c4424bb10a3 --- /dev/null +++ b/adapters/escalax/escalax_test.go @@ -0,0 +1,28 @@ +package escalax + +import ( + "testing" + + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/stretchr/testify/assert" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderEscalax, config.Adapter{ + Endpoint: "http://bidder_us.escalax.io/?partner={{.SourceId}}&token={{.AccountID}}&type=pbs"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "escalaxtest", bidder) +} + +func TestEndpointTemplateMalformed(t *testing.T) { + _, buildErr := Builder(openrtb_ext.BidderEscalax, config.Adapter{ + Endpoint: "{{Malformed}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + assert.Error(t, buildErr) +} diff --git a/adapters/escalax/escalaxtest/exemplary/banner-app.json b/adapters/escalax/escalaxtest/exemplary/banner-app.json new file mode 100644 index 00000000000..e76ca1e291c --- /dev/null +++ b/adapters/escalax/escalaxtest/exemplary/banner-app.json @@ -0,0 +1,155 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "app": { + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ], + "bundle": "com.app.awesome", + "name": "Awesome App", + "domain": "awesomeapp.com", + "id": "123456789" + }, + "imp": [ + { + "id": "1", + "tagid": "ogTAGID", + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "accountId": "accountId", + "sourceId": "sourceId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.5" + ], + "User-Agent": [ + "test-user-agent" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ] + }, + "uri": "http://bidder_us.escalax.io/?partner=sourceId&token=accountId&type=pbs", + "body": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "1", + "banner": { + "w": 320, + "h": 50 + }, + "tagid": "ogTAGID" + } + ], + "app": { + "id": "123456789", + "name": "Awesome App", + "bundle": "com.app.awesome", + "domain": "awesomeapp.com", + "cat": [ + "IAB22-1" + ], + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + }, + "impIDs": [ + "1" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "awesome-resp-id", + "seatbid": [ + { + "bid": [ + { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "1", + "price": 3.5, + "adm": "awesome-markup", + "adomain": [ + "awesome.com" + ], + "crid": "20", + "w": 320, + "h": 50, + "mtype": 1 + } + ], + "type": "banner", + "seat": "escalax" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "1", + "price": 3.5, + "adm": "awesome-markup", + "adomain": [ + "awesome.com" + ], + "crid": "20", + "w": 320, + "h": 50, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/escalax/escalaxtest/exemplary/banner-web.json b/adapters/escalax/escalaxtest/exemplary/banner-web.json new file mode 100644 index 00000000000..28432e46f76 --- /dev/null +++ b/adapters/escalax/escalaxtest/exemplary/banner-web.json @@ -0,0 +1,203 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "imp": [ + { + "id": "some-impression-id1", + "tagid": "ogTAGID", + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "accountId": "accountId", + "sourceId": "sourceId" + } + } + }, + { + "id": "some-impression-id2", + "tagid": "ogTAGID", + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "accountId": "accountId", + "sourceId": "sourceId", + "host": "host" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.5" + ], + "User-Agent": [ + "test-user-agent" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ] + }, + "uri": "http://bidder_us.escalax.io/?partner=sourceId&token=accountId&type=pbs", + "body": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "some-impression-id1", + "tagid": "ogTAGID", + "banner": { + "w": 320, + "h": 50 + } + }, + { + "id": "some-impression-id2", + "tagid": "ogTAGID", + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "accountId": "accountId", + "sourceId": "sourceId", + "host": "host" + } + } + } + ], + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + }, + "impIDs": [ + "some-impression-id1", + "some-impression-id2" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "awesome-resp-id", + "seatbid": [ + { + "bid": [ + { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id1", + "price": 3.5, + "adm": "awesome-markup", + "adomain": [ + "awesome.com" + ], + "crid": "20", + "w": 320, + "h": 50, + "mtype": 1 + }, + { + "id": "a3ae1b4e2fc24a4fb45540082e98e162", + "impid": "some-impression-id2", + "price": 3.5, + "adm": "awesome-markup", + "adomain": [ + "awesome.com" + ], + "crid": "20", + "w": 320, + "h": 50, + "mtype": 1 + } + ], + "type": "banner", + "seat": "escalax" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id1", + "price": 3.5, + "adm": "awesome-markup", + "crid": "20", + "adomain": [ + "awesome.com" + ], + "w": 320, + "h": 50, + "mtype": 1 + }, + "type": "banner" + }, + { + "bid": { + "id": "a3ae1b4e2fc24a4fb45540082e98e162", + "impid": "some-impression-id2", + "price": 3.5, + "adm": "awesome-markup", + "crid": "20", + "adomain": [ + "awesome.com" + ], + "w": 320, + "h": 50, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/escalax/escalaxtest/exemplary/native-app.json b/adapters/escalax/escalaxtest/exemplary/native-app.json new file mode 100644 index 00000000000..27d47d9d19b --- /dev/null +++ b/adapters/escalax/escalaxtest/exemplary/native-app.json @@ -0,0 +1,151 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "app": { + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ], + "bundle": "com.app.awesome", + "name": "Awesome App", + "domain": "awesomeapp.com", + "id": "123456789" + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "native": { + "ver": "1.1", + "request": "{\"adunit\":2,\"assets\":[{\"id\":3,\"img\":{\"h\":120,\"hmin\":0,\"type\":3,\"w\":180,\"wmin\":0},\"required\":1},{\"id\":0,\"required\":1,\"title\":{\"len\":25}},{\"data\":{\"len\":25,\"type\":1},\"id\":4,\"required\":1},{\"data\":{\"len\":140,\"type\":2},\"id\":6,\"required\":1}],\"context\":1,\"layout\":1,\"contextsubtype\":11,\"plcmtcnt\":1,\"plcmttype\":2,\"ver\":\"1.1\",\"ext\":{\"banner\":{\"w\":320,\"h\":50}}}" + }, + "ext": { + "bidder": { + "accountId": "accountId", + "sourceId": "sourceId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.5" + ], + "User-Agent": [ + "test-user-agent" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ] + }, + "uri": "http://bidder_us.escalax.io/?partner=sourceId&token=accountId&type=pbs", + "body": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "some-impression-id", + "native": { + "ver": "1.1", + "request": "{\"adunit\":2,\"assets\":[{\"id\":3,\"img\":{\"h\":120,\"hmin\":0,\"type\":3,\"w\":180,\"wmin\":0},\"required\":1},{\"id\":0,\"required\":1,\"title\":{\"len\":25}},{\"data\":{\"len\":25,\"type\":1},\"id\":4,\"required\":1},{\"data\":{\"len\":140,\"type\":2},\"id\":6,\"required\":1}],\"context\":1,\"layout\":1,\"contextsubtype\":11,\"plcmtcnt\":1,\"plcmttype\":2,\"ver\":\"1.1\",\"ext\":{\"banner\":{\"w\":320,\"h\":50}}}" + }, + "tagid": "ogTAGID" + } + ], + "app": { + "id": "123456789", + "name": "Awesome App", + "bundle": "com.app.awesome", + "domain": "awesomeapp.com", + "cat": [ + "IAB22-1" + ], + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + }, + "impIDs": [ + "some-impression-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "awesome-resp-id", + "seatbid": [ + { + "bid": [ + { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id", + "price": 3.5, + "adm": "awesome-markup", + "adomain": [ + "awesome.com" + ], + "crid": "20", + "mtype": 4 + } + ], + "type": "native", + "seat": "escalax" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id", + "price": 3.5, + "adm": "awesome-markup", + "crid": "20", + "adomain": [ + "awesome.com" + ], + "mtype": 4 + }, + "type": "native" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/escalax/escalaxtest/exemplary/native-web.json b/adapters/escalax/escalaxtest/exemplary/native-web.json new file mode 100644 index 00000000000..4480d14d11e --- /dev/null +++ b/adapters/escalax/escalaxtest/exemplary/native-web.json @@ -0,0 +1,138 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ipv6": "2607:fb90:f27:4512:d800:cb23:a603:e245", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "native": { + "ver": "1.1", + "request": "{\"adunit\":2,\"assets\":[{\"id\":3,\"img\":{\"h\":120,\"hmin\":0,\"type\":3,\"w\":180,\"wmin\":0},\"required\":1},{\"id\":0,\"required\":1,\"title\":{\"len\":25}},{\"data\":{\"len\":25,\"type\":1},\"id\":4,\"required\":1},{\"data\":{\"len\":140,\"type\":2},\"id\":6,\"required\":1}],\"context\":1,\"layout\":1,\"contextsubtype\":11,\"plcmtcnt\":1,\"plcmttype\":2,\"ver\":\"1.1\",\"ext\":{\"banner\":{\"w\":320,\"h\":50}}}" + }, + "ext": { + "bidder": { + "accountId": "accountId", + "sourceId": "sourceId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.5" + ], + "User-Agent": [ + "test-user-agent" + ], + "X-Forwarded-For": [ + "2607:fb90:f27:4512:d800:cb23:a603:e245" + ] + }, + "uri": "http://bidder_us.escalax.io/?partner=sourceId&token=accountId&type=pbs", + "body": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ipv6": "2607:fb90:f27:4512:d800:cb23:a603:e245", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "native": { + "ver": "1.1", + "request": "{\"adunit\":2,\"assets\":[{\"id\":3,\"img\":{\"h\":120,\"hmin\":0,\"type\":3,\"w\":180,\"wmin\":0},\"required\":1},{\"id\":0,\"required\":1,\"title\":{\"len\":25}},{\"data\":{\"len\":25,\"type\":1},\"id\":4,\"required\":1},{\"data\":{\"len\":140,\"type\":2},\"id\":6,\"required\":1}],\"context\":1,\"layout\":1,\"contextsubtype\":11,\"plcmtcnt\":1,\"plcmttype\":2,\"ver\":\"1.1\",\"ext\":{\"banner\":{\"w\":320,\"h\":50}}}" + } + } + ], + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + }, + "impIDs": [ + "some-impression-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "awesome-resp-id", + "seatbid": [ + { + "bid": [ + { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id", + "price": 3.5, + "adm": "awesome-markup", + "adomain": [ + "awesome.com" + ], + "crid": "20", + "mtype": 4 + } + ], + "seat": "escalax" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id", + "price": 3.5, + "adm": "awesome-markup", + "crid": "20", + "adomain": [ + "awesome.com" + ], + "mtype": 4 + }, + "type": "native" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/escalax/escalaxtest/exemplary/video-app.json b/adapters/escalax/escalaxtest/exemplary/video-app.json new file mode 100644 index 00000000000..2c23fb27aa3 --- /dev/null +++ b/adapters/escalax/escalaxtest/exemplary/video-app.json @@ -0,0 +1,164 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "app": { + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ], + "bundle": "com.app.awesome", + "name": "Awesome App", + "domain": "awesomeapp.com", + "id": "123456789" + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "ext": { + "bidder": { + "accountId": "accountId", + "sourceId": "sourceId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.5" + ], + "User-Agent": [ + "test-user-agent" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ] + }, + "uri": "http://bidder_us.escalax.io/?partner=sourceId&token=accountId&type=pbs", + "body": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "some-impression-id", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 120, + "maxduration": 150, + "w": 640, + "h": 480 + }, + "tagid": "ogTAGID" + } + ], + "app": { + "id": "123456789", + "name": "Awesome App", + "bundle": "com.app.awesome", + "domain": "awesomeapp.com", + "cat": [ + "IAB22-1" + ], + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + }, + "impIDs": [ + "some-impression-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "awesome-resp-id", + "seatbid": [ + { + "bid": [ + { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id", + "price": 3.5, + "adm": "awesome-markup", + "adomain": [ + "awesome.com" + ], + "crid": "20", + "w": 1280, + "h": 720, + "mtype": 2 + } + ], + "seat": "escalax" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id", + "price": 3.5, + "adm": "awesome-markup", + "crid": "20", + "adomain": [ + "awesome.com" + ], + "w": 1280, + "h": 720, + "mtype": 2 + }, + "type": "video" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/escalax/escalaxtest/exemplary/video-web.json b/adapters/escalax/escalaxtest/exemplary/video-web.json new file mode 100644 index 00000000000..4204767f794 --- /dev/null +++ b/adapters/escalax/escalaxtest/exemplary/video-web.json @@ -0,0 +1,162 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "ext": { + "bidder": { + "accountId": "accountId", + "sourceId": "sourceId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.5" + ], + "User-Agent": [ + "test-user-agent" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ] + }, + "uri": "http://bidder_us.escalax.io/?partner=sourceId&token=accountId&type=pbs", + "body": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 120, + "maxduration": 150, + "w": 640, + "h": 480 + } + } + ], + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + }, + "impIDs": [ + "some-impression-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "awesome-resp-id", + "seatbid": [ + { + "bid": [ + { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id", + "price": 3.5, + "adm": "awesome-markup", + "adomain": [ + "awesome.com" + ], + "crid": "20", + "w": 1280, + "h": 720, + "mtype": 2, + "ext": { + "prebid": { + "type": "video" + } + } + } + ], + "seat": "escalax" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id", + "price": 3.5, + "adm": "awesome-markup", + "adomain": [ + "awesome.com" + ], + "crid": "20", + "w": 1280, + "h": 720, + "mtype": 2, + "ext": { + "prebid": { + "type": "video" + } + } + }, + "type": "video" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/escalax/escalaxtest/supplemental/bad_media_type.json b/adapters/escalax/escalaxtest/supplemental/bad_media_type.json new file mode 100644 index 00000000000..b98d680cb2e --- /dev/null +++ b/adapters/escalax/escalaxtest/supplemental/bad_media_type.json @@ -0,0 +1,139 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "app": { + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ], + "bundle": "com.app.awesome", + "name": "Awesome App", + "domain": "awesomeapp.com", + "id": "123456789" + }, + "imp": [ + { + "id": "1", + "tagid": "ogTAGID", + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "accountId": "accountId", + "sourceId": "sourceId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.5" + ], + "User-Agent": [ + "test-user-agent" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ] + }, + "uri": "http://bidder_us.escalax.io/?partner=sourceId&token=accountId&type=pbs", + "body": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "1", + "banner": { + "w": 320, + "h": 50 + }, + "tagid": "ogTAGID" + } + ], + "app": { + "id": "123456789", + "name": "Awesome App", + "bundle": "com.app.awesome", + "domain": "awesomeapp.com", + "cat": [ + "IAB22-1" + ], + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + }, + "impIDs": [ + "1" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "awesome-resp-id", + "seatbid": [ + { + "bid": [ + { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "test-imp-id", + "price": 3.5, + "adm": "awesome-markup", + "adomain": [ + "awesome.com" + ], + "crid": "20", + "w": 320, + "h": 50, + "mtype": 0 + } + ], + "type": "banner", + "seat": "escalax" + } + ], + "cur": "USD" + } + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "unsupported MType 0", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/escalax/escalaxtest/supplemental/empty-seatbid-array.json b/adapters/escalax/escalaxtest/supplemental/empty-seatbid-array.json new file mode 100644 index 00000000000..a7b8c12194e --- /dev/null +++ b/adapters/escalax/escalaxtest/supplemental/empty-seatbid-array.json @@ -0,0 +1,133 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "app": { + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ], + "bundle": "com.app.awesome", + "name": "Awesome App", + "domain": "awesomeapp.com", + "id": "123456789" + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "ext": { + "bidder": { + "accountId": "accountId", + "sourceId": "sourceId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.5" + ], + "User-Agent": [ + "test-user-agent" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ] + }, + "uri": "http://bidder_us.escalax.io/?partner=sourceId&token=accountId&type=pbs", + "body": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "some-impression-id", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 120, + "maxduration": 150, + "w": 640, + "h": 480 + }, + "tagid": "ogTAGID" + } + ], + "app": { + "id": "123456789", + "name": "Awesome App", + "bundle": "com.app.awesome", + "domain": "awesomeapp.com", + "cat": [ + "IAB22-1" + ], + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + }, + "impIDs": [ + "some-impression-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "awesome-resp-id", + "seatbid": [], + "cur": "USD" + } + } + } + ], + "mockResponse": { + "status": 200, + "body": "invalid response" + }, + "expectedMakeBidsErrors": [ + { + "value": "Empty SeatBid array", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/escalax/escalaxtest/supplemental/invalid-bidder-ext-object.json b/adapters/escalax/escalaxtest/supplemental/invalid-bidder-ext-object.json new file mode 100644 index 00000000000..016fbd43490 --- /dev/null +++ b/adapters/escalax/escalaxtest/supplemental/invalid-bidder-ext-object.json @@ -0,0 +1,33 @@ +{ + "expectedMakeRequestsErrors": [ + { + "value": "Error parsing bidderExt - expect { or n, but found \"", + "comparison": "literal" + } + ], + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "some-impression-id", + "tagid": "my-adcode", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "ext": { + "bidder": "wrongBidderExt" + } + } + ], + "site": { + "page": "test.com" + } + }, + "httpCalls": [] +} \ No newline at end of file diff --git a/adapters/escalax/escalaxtest/supplemental/invalid-ext-object.json b/adapters/escalax/escalaxtest/supplemental/invalid-ext-object.json new file mode 100644 index 00000000000..ccc32ed87a6 --- /dev/null +++ b/adapters/escalax/escalaxtest/supplemental/invalid-ext-object.json @@ -0,0 +1,31 @@ +{ + "expectedMakeRequestsErrors": [ + { + "value": "Error parsing escalaxExt - expect { or n, but found \"", + "comparison": "literal" + } + ], + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "some-impression-id", + "tagid": "my-adcode", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "ext": "wrongEscalaxExt" + } + ], + "site": { + "page": "test.com" + } + }, + "httpCalls": [] +} \ No newline at end of file diff --git a/adapters/escalax/escalaxtest/supplemental/invalid-response.json b/adapters/escalax/escalaxtest/supplemental/invalid-response.json new file mode 100644 index 00000000000..f511eafa980 --- /dev/null +++ b/adapters/escalax/escalaxtest/supplemental/invalid-response.json @@ -0,0 +1,115 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "app": { + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ], + "bundle": "com.app.awesome", + "name": "Awesome App", + "domain": "awesomeapp.com", + "id": "123456789" + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "accountId": "accountId", + "sourceId": "sourceId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Openrtb-Version": [ + "2.5" + ], + "User-Agent": [ + "test-user-agent" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ] + }, + "uri": "http://bidder_us.escalax.io/?partner=sourceId&token=accountId&type=pbs", + "body": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "some-impression-id", + "banner": { + "w": 320, + "h": 50 + }, + "tagid": "ogTAGID" + } + ], + "app": { + "id": "123456789", + "name": "Awesome App", + "bundle": "com.app.awesome", + "domain": "awesomeapp.com", + "cat": [ + "IAB22-1" + ], + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + }, + "impIDs": [ + "some-impression-id" + ] + }, + "mockResponse": { + "status": 200, + "body": "invalid response" + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Bad Server Response", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/escalax/escalaxtest/supplemental/status-code-bad-request.json b/adapters/escalax/escalaxtest/supplemental/status-code-bad-request.json new file mode 100644 index 00000000000..d6537aac95e --- /dev/null +++ b/adapters/escalax/escalaxtest/supplemental/status-code-bad-request.json @@ -0,0 +1,96 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "app": { + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ], + "bundle": "com.app.awesome", + "name": "Awesome App", + "domain": "awesomeapp.com", + "id": "123456789" + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "ext": { + "bidder": { + "accountId": "accountId", + "sourceId": "sourceId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://bidder_us.escalax.io/?partner=sourceId&token=accountId&type=pbs", + "body": { + "id": "some-request-id", + "imp": [ + { + "id": "some-impression-id", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 120, + "maxduration": 150, + "w": 640, + "h": 480 + }, + "tagid": "ogTAGID" + } + ], + "app": { + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ], + "bundle": "com.app.awesome", + "name": "Awesome App", + "domain": "awesomeapp.com", + "id": "123456789" + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + }, + "impIDs": [ + "some-impression-id" + ] + }, + "mockResponse": { + "status": 400 + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/escalax/escalaxtest/supplemental/status-code-other-error.json b/adapters/escalax/escalaxtest/supplemental/status-code-other-error.json new file mode 100644 index 00000000000..00d618e5b29 --- /dev/null +++ b/adapters/escalax/escalaxtest/supplemental/status-code-other-error.json @@ -0,0 +1,84 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "video": { + "mimes": [ + "video/mp4" + ], + "w": 640, + "h": 480, + "minduration": 120, + "maxduration": 150 + }, + "ext": { + "bidder": { + "accountId": "accountId", + "sourceId": "sourceId" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://bidder_us.escalax.io/?partner=sourceId&token=accountId&type=pbs", + "body": { + "id": "some-request-id", + "imp": [ + { + "id": "some-impression-id", + "tagid": "ogTAGID", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 120, + "maxduration": 150, + "w": 640, + "h": 480 + } + } + ], + "site": { + "page": "test.com", + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + }, + "impIDs": [ + "some-impression-id" + ] + }, + "mockResponse": { + "status": 306 + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 306. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/escalax/params_test.go b/adapters/escalax/params_test.go new file mode 100644 index 00000000000..6e6036721ab --- /dev/null +++ b/adapters/escalax/params_test.go @@ -0,0 +1,52 @@ +package escalax + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v3/openrtb_ext" +) + +var validParams = []string{ + `{ "sourceId": "someSourceId", "accountId": "0800fc577294" }`, +} + +var invalidParams = []string{ + ``, + `null`, + `true`, + `9`, + `1.2`, + `[]`, + `{}`, + `{ "accountId": "", "sourceId": "" }`, + `{ "accountId": true, "sourceId": true }`, + `{ "accountId": 123, "sourceId": 123 }`, + `{ "accountId": null, "sourceId": null }`, +} + +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schemas. %v", err) + } + + for _, validParam := range validParams { + if err := validator.Validate(openrtb_ext.BidderEscalax, json.RawMessage(validParam)); err != nil { + t.Errorf("Schema rejected Escalax params: %s", validParam) + } + } +} + +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schemas. %v", err) + } + + for _, invalidParam := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderEscalax, json.RawMessage(invalidParam)); err == nil { + t.Errorf("Schema allowed unexpected params: %s", invalidParam) + } + } +} diff --git a/adapters/flipp/flipp.go b/adapters/flipp/flipp.go index 55a3ce7b3e1..54bf2775354 100644 --- a/adapters/flipp/flipp.go +++ b/adapters/flipp/flipp.go @@ -13,10 +13,11 @@ import ( "github.com/prebid/go-gdpr/consentconstants" "github.com/prebid/go-gdpr/vendorconsent" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/uuidutil" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/uuidutil" ) const ( @@ -94,7 +95,7 @@ func (a *adapter) processImp(request *openrtb2.BidRequest, imp openrtb2.Imp) (*a if err != nil { return nil, fmt.Errorf("flipp params not found. %v", err) } - err = json.Unmarshal(params, &flippExtParams) + err = jsonutil.Unmarshal(params, &flippExtParams) if err != nil { return nil, fmt.Errorf("unable to extract flipp params. %v", err) } @@ -191,7 +192,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var campaignResponseBody CampaignResponseBody - if err := json.Unmarshal(responseData.Body, &campaignResponseBody); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &campaignResponseBody); err != nil { return nil, []error{err} } @@ -248,7 +249,7 @@ func paramsUserKeyPermitted(request *openrtb2.BidRequest) bool { var extData struct { TransmitEids *bool `json:"transmitEids,omitempty"` } - if err := json.Unmarshal(request.Ext, &extData); err == nil { + if err := jsonutil.Unmarshal(request.Ext, &extData); err == nil { if extData.TransmitEids != nil && !*extData.TransmitEids { return false } diff --git a/adapters/flipp/flipp_params.go b/adapters/flipp/flipp_params.go index 11f00560ba4..34d266a7d94 100644 --- a/adapters/flipp/flipp_params.go +++ b/adapters/flipp/flipp_params.go @@ -1,6 +1,6 @@ package flipp -import "github.com/prebid/prebid-server/v2/openrtb_ext" +import "github.com/prebid/prebid-server/v3/openrtb_ext" type CampaignRequestBodyUser struct { Key *string `json:"key"` diff --git a/adapters/flipp/flipp_test.go b/adapters/flipp/flipp_test.go index 10f2cfad5cb..8215dabe827 100644 --- a/adapters/flipp/flipp_test.go +++ b/adapters/flipp/flipp_test.go @@ -5,10 +5,10 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/flipp/flipptest/supplemental/bad-response.json b/adapters/flipp/flipptest/supplemental/bad-response.json index f17320bded9..64920da0e55 100644 --- a/adapters/flipp/flipptest/supplemental/bad-response.json +++ b/adapters/flipp/flipptest/supplemental/bad-response.json @@ -82,7 +82,7 @@ }], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type flipp.CampaignResponseBody", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/flipp/params_test.go b/adapters/flipp/params_test.go index 37f1fda6324..24f30b0a624 100644 --- a/adapters/flipp/params_test.go +++ b/adapters/flipp/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/freewheelssp/freewheelssp.go b/adapters/freewheelssp/freewheelssp.go index df6f756bb65..111b05a60e2 100644 --- a/adapters/freewheelssp/freewheelssp.go +++ b/adapters/freewheelssp/freewheelssp.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -20,14 +21,14 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E for i := 0; i < len(request.Imp); i++ { imp := &request.Imp[i] var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, []error{&errortypes.BadInput{ Message: fmt.Sprintf("Invalid imp.ext for impression index %d. Error Infomation: %s", i, err.Error()), }} } var impExt openrtb_ext.ImpExtFreewheelSSP - if err := json.Unmarshal(bidderExt.Bidder, &impExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &impExt); err != nil { return nil, []error{&errortypes.BadInput{ Message: fmt.Sprintf("Invalid imp.ext for impression index %d. Error Infomation: %s", i, err.Error()), }} @@ -73,7 +74,7 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } diff --git a/adapters/freewheelssp/freewheelssp_test.go b/adapters/freewheelssp/freewheelssp_test.go index ea1b5b7c980..ba5e6cf9aac 100644 --- a/adapters/freewheelssp/freewheelssp_test.go +++ b/adapters/freewheelssp/freewheelssp_test.go @@ -3,9 +3,9 @@ package freewheelssp import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/freewheelssp/freewheelssptest/exemplary/multi-imp.json b/adapters/freewheelssp/freewheelssptest/exemplary/multi-imp.json index 2562a812edc..18a1dbdbdef 100644 --- a/adapters/freewheelssp/freewheelssptest/exemplary/multi-imp.json +++ b/adapters/freewheelssp/freewheelssptest/exemplary/multi-imp.json @@ -153,7 +153,8 @@ }, "type": "video", "video" : { - "duration" : 10 + "duration" : 10, + "primary_category": "" } } ] diff --git a/adapters/frvradn/frvradn.go b/adapters/frvradn/frvradn.go index 7d71e13e374..5b21263b1aa 100644 --- a/adapters/frvradn/frvradn.go +++ b/adapters/frvradn/frvradn.go @@ -7,10 +7,11 @@ import ( "strings" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -90,7 +91,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } @@ -117,13 +118,13 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R func getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ImpExtFRVRAdn, error) { var extImpBidder adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &extImpBidder); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &extImpBidder); err != nil { return nil, &errortypes.BadInput{ Message: "missing ext", } } var frvrAdnExt openrtb_ext.ImpExtFRVRAdn - if err := json.Unmarshal(extImpBidder.Bidder, &frvrAdnExt); err != nil { + if err := jsonutil.Unmarshal(extImpBidder.Bidder, &frvrAdnExt); err != nil { return nil, &errortypes.BadInput{ Message: "missing ext.bidder", } @@ -139,7 +140,7 @@ func getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ImpExtFRVRAdn, error) { func getBidMediaType(bid *openrtb2.Bid) (openrtb_ext.BidType, error) { var extBid openrtb_ext.ExtBid - err := json.Unmarshal(bid.Ext, &extBid) + err := jsonutil.Unmarshal(bid.Ext, &extBid) if err != nil { return "", fmt.Errorf("unable to deserialize imp %v bid.ext", bid.ImpID) } diff --git a/adapters/frvradn/frvradn_test.go b/adapters/frvradn/frvradn_test.go index 89f3dc50b42..514ef6c7123 100644 --- a/adapters/frvradn/frvradn_test.go +++ b/adapters/frvradn/frvradn_test.go @@ -5,9 +5,9 @@ import ( "github.com/stretchr/testify/assert" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/frvradn/params_test.go b/adapters/frvradn/params_test.go index 74a51b26fa2..83e1ba631ac 100644 --- a/adapters/frvradn/params_test.go +++ b/adapters/frvradn/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/gamma/gamma.go b/adapters/gamma/gamma.go index 56153aeedd6..66f99953fe2 100644 --- a/adapters/gamma/gamma.go +++ b/adapters/gamma/gamma.go @@ -9,10 +9,11 @@ import ( "github.com/prebid/openrtb/v20/openrtb2" "github.com/prebid/openrtb/v20/openrtb3" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type GammaAdapter struct { @@ -62,7 +63,7 @@ func (a *GammaAdapter) makeRequest(request *openrtb2.BidRequest, imp openrtb2.Im var errors []error var bidderExt adapters.ExtImpBidder - err := json.Unmarshal(imp.Ext, &bidderExt) + err := jsonutil.Unmarshal(imp.Ext, &bidderExt) if err != nil { err = &errortypes.BadInput{ Message: "ext.bidder not provided", @@ -71,7 +72,7 @@ func (a *GammaAdapter) makeRequest(request *openrtb2.BidRequest, imp openrtb2.Im return nil, errors } var gammaExt openrtb_ext.ExtImpGamma - err = json.Unmarshal(bidderExt.Bidder, &gammaExt) + err = jsonutil.Unmarshal(bidderExt.Bidder, &gammaExt) if err != nil { err = &errortypes.BadInput{ Message: "ext.bidder.publisher not provided", @@ -243,7 +244,7 @@ func (a *GammaAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRe } var gammaResp gammaBidResponse - if err := json.Unmarshal(response.Body, &gammaResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &gammaResp); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: fmt.Sprintf("bad server response: %d. ", err), }} diff --git a/adapters/gamma/gamma_test.go b/adapters/gamma/gamma_test.go index 78cde32984e..9556e83dc0e 100644 --- a/adapters/gamma/gamma_test.go +++ b/adapters/gamma/gamma_test.go @@ -3,9 +3,9 @@ package gamma import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/gamma/gammatest/supplemental/bad-response-no-body.json b/adapters/gamma/gammatest/supplemental/bad-response-no-body.json index 7d27e7c8160..86ba810e453 100644 --- a/adapters/gamma/gammatest/supplemental/bad-response-no-body.json +++ b/adapters/gamma/gammatest/supplemental/bad-response-no-body.json @@ -40,8 +40,8 @@ ], "expectedMakeBidsErrors": [ { - "value": "bad server response: &{%!d(string=unexpected end of JSON input) 0}. ", - "comparison": "literal" + "value": "bad server response: &{%!d(string=expect { or n, but found", + "comparison": "startswith" } ] } diff --git a/adapters/gamma/params_test.go b/adapters/gamma/params_test.go index 7d2d211b054..d377b50c3dc 100644 --- a/adapters/gamma/params_test.go +++ b/adapters/gamma/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/gamma.json diff --git a/adapters/gamoshi/gamoshi.go b/adapters/gamoshi/gamoshi.go index 13cf4d8b2fd..4ba302506f9 100644 --- a/adapters/gamoshi/gamoshi.go +++ b/adapters/gamoshi/gamoshi.go @@ -7,10 +7,11 @@ import ( "strconv" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type GamoshiAdapter struct { @@ -69,7 +70,7 @@ func (a *GamoshiAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *ada errors := make([]error, 0, 1) var bidderExt adapters.ExtImpBidder - err = json.Unmarshal(request.Imp[0].Ext, &bidderExt) + err = jsonutil.Unmarshal(request.Imp[0].Ext, &bidderExt) if err != nil { err = &errortypes.BadInput{ @@ -79,7 +80,7 @@ func (a *GamoshiAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *ada return nil, errors } var gamoshiExt openrtb_ext.ExtImpGamoshi - err = json.Unmarshal(bidderExt.Bidder, &gamoshiExt) + err = jsonutil.Unmarshal(bidderExt.Bidder, &gamoshiExt) if err != nil { err = &errortypes.BadInput{ Message: "ext.bidder.supplyPartnerId not provided", @@ -143,7 +144,7 @@ func (a *GamoshiAdapter) MakeBids(internalRequest *openrtb2.BidRequest, external } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: fmt.Sprintf("bad server response: %v. ", err), }} diff --git a/adapters/gamoshi/gamoshi_test.go b/adapters/gamoshi/gamoshi_test.go index 4c787aeb700..aa20723b2db 100644 --- a/adapters/gamoshi/gamoshi_test.go +++ b/adapters/gamoshi/gamoshi_test.go @@ -3,9 +3,9 @@ package gamoshi import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamplesWithConfiguredURI(t *testing.T) { diff --git a/adapters/gamoshi/gamoshitest/supplemental/bad-response-no-body.json b/adapters/gamoshi/gamoshitest/supplemental/bad-response-no-body.json index 897844ff8e4..ddbcf435f46 100644 --- a/adapters/gamoshi/gamoshitest/supplemental/bad-response-no-body.json +++ b/adapters/gamoshi/gamoshitest/supplemental/bad-response-no-body.json @@ -51,8 +51,8 @@ ], "expectedMakeBidsErrors": [ { - "value": "bad server response: unexpected end of JSON input. ", - "comparison": "literal" + "value": "bad server response: expect { or n, but found", + "comparison": "startswith" } ] } diff --git a/adapters/gamoshi/params_test.go b/adapters/gamoshi/params_test.go index 6fb5d9ee08b..429ed96ad8d 100644 --- a/adapters/gamoshi/params_test.go +++ b/adapters/gamoshi/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/gamoshi.json diff --git a/adapters/globalsun/globalsun.go b/adapters/globalsun/globalsun.go index 533815f7403..a2b2dc5b9ab 100644 --- a/adapters/globalsun/globalsun.go +++ b/adapters/globalsun/globalsun.go @@ -7,10 +7,11 @@ import ( "github.com/buger/jsonparser" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -100,7 +101,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } diff --git a/adapters/globalsun/globalsun_test.go b/adapters/globalsun/globalsun_test.go index a2f33770486..e34805f68f3 100644 --- a/adapters/globalsun/globalsun_test.go +++ b/adapters/globalsun/globalsun_test.go @@ -3,9 +3,9 @@ package globalsun import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/globalsun/globalsuntest/supplemental/bad_response.json b/adapters/globalsun/globalsuntest/supplemental/bad_response.json index c732ba92c67..5cc4a338ac3 100644 --- a/adapters/globalsun/globalsuntest/supplemental/bad_response.json +++ b/adapters/globalsun/globalsuntest/supplemental/bad_response.json @@ -78,7 +78,7 @@ }], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/globalsun/params_test.go b/adapters/globalsun/params_test.go index 87d6427ad8b..b4fe0ede7ad 100644 --- a/adapters/globalsun/params_test.go +++ b/adapters/globalsun/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/gothamads/gothamads.go b/adapters/gothamads/gothamads.go index b4fc8e64cdd..7b2f2471084 100644 --- a/adapters/gothamads/gothamads.go +++ b/adapters/gothamads/gothamads.go @@ -7,11 +7,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -82,13 +83,13 @@ func (a *adapter) MakeRequests(openRTBRequest *openrtb2.BidRequest, reqInfo *ada func getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtGothamAds, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: err.Error(), } } var gothamadsExt openrtb_ext.ExtGothamAds - if err := json.Unmarshal(bidderExt.Bidder, &gothamadsExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &gothamadsExt); err != nil { return nil, &errortypes.BadInput{ Message: err.Error(), } @@ -124,7 +125,7 @@ func (a *adapter) MakeBids(openRTBRequest *openrtb2.BidRequest, requestToBidder responseBody := bidderRawResponse.Body var bidResp openrtb2.BidResponse - if err := json.Unmarshal(responseBody, &bidResp); err != nil { + if err := jsonutil.Unmarshal(responseBody, &bidResp); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: "Bad Server Response", }} diff --git a/adapters/gothamads/gothamads_test.go b/adapters/gothamads/gothamads_test.go index 5dde1527f3f..b3433ae44a8 100644 --- a/adapters/gothamads/gothamads_test.go +++ b/adapters/gothamads/gothamads_test.go @@ -3,9 +3,9 @@ package gothamads import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/gothamads/gothamadstest/supplemental/invalid-bidder-ext-object.json b/adapters/gothamads/gothamadstest/supplemental/invalid-bidder-ext-object.json index e412d39ca2c..ea4091e1489 100644 --- a/adapters/gothamads/gothamadstest/supplemental/invalid-bidder-ext-object.json +++ b/adapters/gothamads/gothamadstest/supplemental/invalid-bidder-ext-object.json @@ -1,7 +1,7 @@ { "expectedMakeRequestsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb_ext.ExtGothamAds", + "value": "expect { or n, but found \"", "comparison": "literal" } ], diff --git a/adapters/gothamads/gothamadstest/supplemental/invalid-gotham-ext-object.json b/adapters/gothamads/gothamadstest/supplemental/invalid-gotham-ext-object.json index 6075e2a4b3d..294b6d1406c 100644 --- a/adapters/gothamads/gothamadstest/supplemental/invalid-gotham-ext-object.json +++ b/adapters/gothamads/gothamadstest/supplemental/invalid-gotham-ext-object.json @@ -1,7 +1,7 @@ { "expectedMakeRequestsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type adapters.ExtImpBidder", + "value": "expect { or n, but found \"", "comparison": "literal" } ], diff --git a/adapters/gothamads/params_test.go b/adapters/gothamads/params_test.go index 1db984321e1..ff61796deb9 100644 --- a/adapters/gothamads/params_test.go +++ b/adapters/gothamads/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/grid/grid.go b/adapters/grid/grid.go index 3f521ba5e0a..ad61058fed4 100644 --- a/adapters/grid/grid.go +++ b/adapters/grid/grid.go @@ -9,11 +9,12 @@ import ( "strings" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/maputil" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/maputil" ) type GridAdapter struct { @@ -122,7 +123,7 @@ func buildConsolidatedKeywordsReqExt(openRTBUser, openRTBSite string, firstImpEx } func parseExtToMap(ext json.RawMessage) map[string]interface{} { var root map[string]interface{} - if err := json.Unmarshal(ext, &root); err != nil { + if err := jsonutil.Unmarshal(ext, &root); err != nil { return make(map[string]interface{}) } return root @@ -252,10 +253,10 @@ func processImp(imp *openrtb2.Imp) error { // get the grid extension var ext adapters.ExtImpBidder var gridExt openrtb_ext.ExtImpGrid - if err := json.Unmarshal(imp.Ext, &ext); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &ext); err != nil { return err } - if err := json.Unmarshal(ext.Bidder, &gridExt); err != nil { + if err := jsonutil.Unmarshal(ext.Bidder, &gridExt); err != nil { return err } @@ -271,7 +272,7 @@ func processImp(imp *openrtb2.Imp) error { func setImpExtData(imp openrtb2.Imp) openrtb2.Imp { var ext ExtImp - if err := json.Unmarshal(imp.Ext, &ext); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &ext); err != nil { return imp } if ext.Data != nil && ext.Data.AdServer != nil && ext.Data.AdServer.AdSlot != "" { @@ -288,7 +289,7 @@ func fixNative(req json.RawMessage) (json.RawMessage, error) { var gridReq map[string]interface{} var parsedRequest map[string]interface{} - if err := json.Unmarshal(req, &gridReq); err != nil { + if err := jsonutil.Unmarshal(req, &gridReq); err != nil { return req, nil } if imps, exists := maputil.ReadEmbeddedSlice(gridReq, "imp"); exists { @@ -299,7 +300,7 @@ func fixNative(req json.RawMessage) (json.RawMessage, error) { request, hasRequest := maputil.ReadEmbeddedString(native, "request") if hasRequest { delete(native, "request") - if err := json.Unmarshal([]byte(request), &parsedRequest); err == nil { + if err := jsonutil.Unmarshal([]byte(request), &parsedRequest); err == nil { native["request_native"] = parsedRequest } else { native["request_native"] = request @@ -387,7 +388,7 @@ func (a *GridAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalReq } var bidResp GridResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } @@ -437,7 +438,7 @@ func getBidMeta(ext json.RawMessage) (*openrtb_ext.ExtBidPrebidMeta, error) { } var bidExt GridBidExt - if err := json.Unmarshal(ext, &bidExt); err != nil { + if err := jsonutil.Unmarshal(ext, &bidExt); err != nil { return nil, err } var bidMeta *openrtb_ext.ExtBidPrebidMeta diff --git a/adapters/grid/grid_test.go b/adapters/grid/grid_test.go index f35f0c66582..bf7bfe547fc 100644 --- a/adapters/grid/grid_test.go +++ b/adapters/grid/grid_test.go @@ -3,9 +3,9 @@ package grid import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/grid/gridtest/supplemental/bad_bidder_request.json b/adapters/grid/gridtest/supplemental/bad_bidder_request.json index 347a3091a41..450d2c3f099 100644 --- a/adapters/grid/gridtest/supplemental/bad_bidder_request.json +++ b/adapters/grid/gridtest/supplemental/bad_bidder_request.json @@ -20,7 +20,7 @@ }, "expectedMakeRequestsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb_ext.ExtImpGrid", + "value": "expect { or n, but found \"", "comparison": "literal" }, { diff --git a/adapters/grid/gridtest/supplemental/bad_ext_request.json b/adapters/grid/gridtest/supplemental/bad_ext_request.json index 789db8504f8..cebaad0a800 100644 --- a/adapters/grid/gridtest/supplemental/bad_ext_request.json +++ b/adapters/grid/gridtest/supplemental/bad_ext_request.json @@ -18,7 +18,7 @@ }, "expectedMakeRequestsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type adapters.ExtImpBidder", + "value": "expect { or n, but found \"", "comparison": "literal" }, { diff --git a/adapters/grid/gridtest/supplemental/bad_response.json b/adapters/grid/gridtest/supplemental/bad_response.json index a4c32c017c4..fb9c10a417a 100644 --- a/adapters/grid/gridtest/supplemental/bad_response.json +++ b/adapters/grid/gridtest/supplemental/bad_response.json @@ -57,7 +57,7 @@ "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type grid.GridResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/gumgum/gumgum.go b/adapters/gumgum/gumgum.go index 9e25e291825..68ca84c7ce1 100644 --- a/adapters/gumgum/gumgum.go +++ b/adapters/gumgum/gumgum.go @@ -8,10 +8,11 @@ import ( "strings" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) // adapter implements Bidder interface. @@ -98,7 +99,7 @@ func (g *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest }} } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: fmt.Sprintf("Bad server response: %d. ", err), }} @@ -121,13 +122,15 @@ func (g *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest }) } } - + if bidResp.Cur != "" { + bidResponse.Currency = bidResp.Cur + } return bidResponse, errs } func preprocess(imp *openrtb2.Imp) (*openrtb_ext.ExtImpGumGum, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { err = &errortypes.BadInput{ Message: err.Error(), } @@ -135,7 +138,7 @@ func preprocess(imp *openrtb2.Imp) (*openrtb_ext.ExtImpGumGum, error) { } var gumgumExt openrtb_ext.ExtImpGumGum - if err := json.Unmarshal(bidderExt.Bidder, &gumgumExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &gumgumExt); err != nil { err = &errortypes.BadInput{ Message: err.Error(), } @@ -161,12 +164,8 @@ func preprocess(imp *openrtb2.Imp) (*openrtb_ext.ExtImpGumGum, error) { } if imp.Video != nil { - err := validateVideoParams(imp.Video) - if err != nil { - return nil, err - } - if gumgumExt.IrisID != "" { + var err error videoCopy := *imp.Video videoExt := openrtb_ext.ExtImpGumGumVideo{IrisID: gumgumExt.IrisID} videoCopy.Ext, err = json.Marshal(&videoExt) @@ -221,15 +220,6 @@ func getMediaTypeForImpID(impID string, imps []openrtb2.Imp) openrtb_ext.BidType return openrtb_ext.BidTypeVideo } -func validateVideoParams(video *openrtb2.Video) (err error) { - if video.W == nil || *video.W == 0 || video.H == nil || *video.H == 0 || video.MinDuration == 0 || video.MaxDuration == 0 || video.Placement == 0 || video.Linearity == 0 { - return &errortypes.BadInput{ - Message: "Invalid or missing video field(s)", - } - } - return nil -} - // Builder builds a new instance of the GumGum adapter for the given bidder with the given config. func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { bidder := &adapter{ diff --git a/adapters/gumgum/gumgum_test.go b/adapters/gumgum/gumgum_test.go index 621b4a96b04..6386818803e 100644 --- a/adapters/gumgum/gumgum_test.go +++ b/adapters/gumgum/gumgum_test.go @@ -3,9 +3,9 @@ package gumgum import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/gumgum/gumgumtest/supplemental/convert-currency.json b/adapters/gumgum/gumgumtest/supplemental/convert-currency.json new file mode 100644 index 00000000000..6c5be286275 --- /dev/null +++ b/adapters/gumgum/gumgumtest/supplemental/convert-currency.json @@ -0,0 +1,111 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 300 + } + ], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "pubId": 12345678 + } + } + } + ], + "site": { + "publisher": { + "id": "12345678" + } + } + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://g2.gumgum.com/providers/prbds2s/bid", + "body":{ + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "banner": { + "format": [{ + "w": 300, + "h": 250 + }, { + "w": 300, + "h": 300 + }], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "pubId": 12345678 + } + } + }], + "site": { + "publisher": { + "id": "12345678" + } + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "cur": "EUR", + "seatbid": [ + { + "bid": [ + { + "crid": "2068416", + "adm": "some-test-ad", + "adid": "2068416", + "price": 5, + "id": "5736a50b-6b05-42a8-aa6d-b0a4649dcd05", + "impid": "test-imp-id", + "cid": "4747" + } + ] + } + ] + } + } + } + ], + + "expectedBidResponses": [ + { + "currency": "EUR", + "bids": [ + { + "bid": { + "crid": "2068416", + "adm": "some-test-ad", + "adid": "2068416", + "price": 5, + "id": "5736a50b-6b05-42a8-aa6d-b0a4649dcd05", + "impid": "test-imp-id", + "cid": "4747" + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/gumgum/gumgumtest/supplemental/missing-video-params.json b/adapters/gumgum/gumgumtest/supplemental/missing-video-params.json deleted file mode 100644 index b2475cd7bb4..00000000000 --- a/adapters/gumgum/gumgumtest/supplemental/missing-video-params.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "video": { - "mimes": [ - "video/mp4" - ], - "protocols": [ - 1, - 2 - ], - "w": 640, - "h": 480, - "startdelay": 1, - "placement": 1, - "linearity": 1 - }, - "ext": { - "bidder": { - "zone": "ggumtest" - } - } - } - ] - }, - "expectedMakeRequestsErrors": [ - { - "value": "Invalid or missing video field(s)", - "comparison": "literal" - } - ] - } - \ No newline at end of file diff --git a/adapters/gumgum/gumgumtest/supplemental/video-missing-size.json b/adapters/gumgum/gumgumtest/supplemental/video-missing-size.json deleted file mode 100644 index 1e4afe167ea..00000000000 --- a/adapters/gumgum/gumgumtest/supplemental/video-missing-size.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "video": { - "mimes": [ - "video/mp4" - ], - "minduration": 1, - "maxduration": 2, - "protocols": [ - 1, - 2 - ], - "startdelay": 1, - "placement": 1, - "linearity": 1 - }, - "ext": { - "bidder": { - "zone": "ggumtest" - } - } - } - ] - }, - "expectedMakeRequestsErrors": [ - { - "value": "Invalid or missing video field(s)", - "comparison": "literal" - } - ] -} \ No newline at end of file diff --git a/adapters/gumgum/gumgumtest/supplemental/video-partial-size.json b/adapters/gumgum/gumgumtest/supplemental/video-partial-size.json index 3c9727a1a9c..ce43a93b145 100644 --- a/adapters/gumgum/gumgumtest/supplemental/video-partial-size.json +++ b/adapters/gumgum/gumgumtest/supplemental/video-partial-size.json @@ -27,10 +27,79 @@ } ] }, - "expectedMakeRequestsErrors": [ + "httpCalls": [ { - "value": "Invalid or missing video field(s)", - "comparison": "literal" + "expectedRequest": { + "uri": "https://g2.gumgum.com/providers/prbds2s/bid", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 1, + "maxduration": 2, + "protocols": [ + 1, + 2 + ], + "w": 640, + "startdelay": 1, + "placement": 1, + "linearity": 1 + }, + "ext": { + "bidder": { + "zone": "ggumtest" + } + } + } + ] + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "seatbid": [ + { + "bid": [ + { + "id": "15da721e-940a-4db6-8621-a1f93140b21b", + "impid": "video1", + "price": 15, + "adid": "59082", + "adm": "\n \n \n GumGum Video\n \n \n \n \n \n \n \n \n \n 00:00:15\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n", + "cid": "3579", + "crid": "59082" + } + ] + } + ] + } + } + } +], +"expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "15da721e-940a-4db6-8621-a1f93140b21b", + "impid": "video1", + "price": 15, + "adid": "59082", + "adm": "\n \n \n GumGum Video\n \n \n \n \n \n \n \n \n \n 00:00:15\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n", + "cid": "3579", + "crid": "59082" + }, + "type": "video" + } + ] } - ] +] } \ No newline at end of file diff --git a/adapters/gumgum/gumgumtest/supplemental/video-zero-size.json b/adapters/gumgum/gumgumtest/supplemental/video-zero-size.json index d3d4b427120..4fc7dc3ce77 100644 --- a/adapters/gumgum/gumgumtest/supplemental/video-zero-size.json +++ b/adapters/gumgum/gumgumtest/supplemental/video-zero-size.json @@ -28,10 +28,80 @@ } ] }, - "expectedMakeRequestsErrors": [ + "httpCalls": [ { - "value": "Invalid or missing video field(s)", - "comparison": "literal" + "expectedRequest": { + "uri": "https://g2.gumgum.com/providers/prbds2s/bid", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 1, + "maxduration": 2, + "protocols": [ + 1, + 2 + ], + "w": 0, + "h": 0, + "startdelay": 1, + "placement": 1, + "linearity": 1 + }, + "ext": { + "bidder": { + "zone": "ggumtest" + } + } + } + ] + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "seatbid": [ + { + "bid": [ + { + "id": "15da721e-940a-4db6-8621-a1f93140b21b", + "impid": "video1", + "price": 15, + "adid": "59082", + "adm": "\n \n \n GumGum Video\n \n \n \n \n \n \n \n \n \n 00:00:15\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n", + "cid": "3579", + "crid": "59082" + } + ] + } + ] + } + } + } +], +"expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "15da721e-940a-4db6-8621-a1f93140b21b", + "impid": "video1", + "price": 15, + "adid": "59082", + "adm": "\n \n \n GumGum Video\n \n \n \n \n \n \n \n \n \n 00:00:15\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n", + "cid": "3579", + "crid": "59082" + }, + "type": "video" + } + ] } - ] +] } \ No newline at end of file diff --git a/adapters/gumgum/params_test.go b/adapters/gumgum/params_test.go index 11874cdbd61..514ab1d8c7f 100644 --- a/adapters/gumgum/params_test.go +++ b/adapters/gumgum/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/huaweiads/huaweiads.go b/adapters/huaweiads/huaweiads.go index bc346096437..144f5e22204 100644 --- a/adapters/huaweiads/huaweiads.go +++ b/adapters/huaweiads/huaweiads.go @@ -20,11 +20,12 @@ import ( nativeRequests "github.com/prebid/openrtb/v20/native1/request" nativeResponse "github.com/prebid/openrtb/v20/native1/response" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/ptrutil" ) const huaweiAdxApiVersion = "3.4" @@ -362,7 +363,7 @@ func (a *adapter) MakeBids(openRTBRequest *openrtb2.BidRequest, requestToBidder } var huaweiAdsResponse huaweiAdsResponse - if err := json.Unmarshal(bidderRawResponse.Body, &huaweiAdsResponse); err != nil { + if err := jsonutil.Unmarshal(bidderRawResponse.Body, &huaweiAdsResponse); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: "Unable to parse server response", }} @@ -400,7 +401,7 @@ func getExtraInfo(v string) (ExtraInfo, error) { return extraInfo, nil } - if err := json.Unmarshal([]byte(v), &extraInfo); err != nil { + if err := jsonutil.Unmarshal([]byte(v), &extraInfo); err != nil { return extraInfo, fmt.Errorf("invalid extra info: %v , pls check", err) } @@ -532,7 +533,7 @@ func getNativeFormat(adslot30 *adslot30, openRTBImp *openrtb2.Imp) error { } var nativePayload nativeRequests.Request - if err := json.Unmarshal(json.RawMessage(openRTBImp.Native.Request), &nativePayload); err != nil { + if err := jsonutil.Unmarshal(json.RawMessage(openRTBImp.Native.Request), &nativePayload); err != nil { return err } @@ -856,7 +857,7 @@ func getDeviceIDFromUserExt(device *device, openRTBRequest *openrtb2.BidRequest) } if userObjExist { var extUserDataHuaweiAds openrtb_ext.ExtUserDataHuaweiAds - if err := json.Unmarshal(openRTBRequest.User.Ext, &extUserDataHuaweiAds); err != nil { + if err := jsonutil.Unmarshal(openRTBRequest.User.Ext, &extUserDataHuaweiAds); err != nil { return errors.New("get gaid from openrtb Device.IFA failed, and get device id failed: Unmarshal openRTBRequest.User.Ext -> extUserDataHuaweiAds. Error: " + err.Error()) } @@ -954,7 +955,7 @@ func getReqGeoInfo(request *huaweiAdsRequest, openRTBRequest *openrtb2.BidReques func getReqConsentInfo(request *huaweiAdsRequest, openRTBRequest *openrtb2.BidRequest) { if openRTBRequest.User != nil && openRTBRequest.User.Ext != nil { var extUser openrtb_ext.ExtUser - if err := json.Unmarshal(openRTBRequest.User.Ext, &extUser); err != nil { + if err := jsonutil.Unmarshal(openRTBRequest.User.Ext, &extUser); err != nil { return } request.Consent = extUser.Consent @@ -964,10 +965,10 @@ func getReqConsentInfo(request *huaweiAdsRequest, openRTBRequest *openrtb2.BidRe func unmarshalExtImpHuaweiAds(openRTBImp *openrtb2.Imp) (*openrtb_ext.ExtImpHuaweiAds, error) { var bidderExt adapters.ExtImpBidder var huaweiAdsImpExt openrtb_ext.ExtImpHuaweiAds - if err := json.Unmarshal(openRTBImp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(openRTBImp.Ext, &bidderExt); err != nil { return nil, errors.New("Unmarshal: openRTBImp.Ext -> bidderExt failed") } - if err := json.Unmarshal(bidderExt.Bidder, &huaweiAdsImpExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &huaweiAdsImpExt); err != nil { return nil, errors.New("Unmarshal: bidderExt.Bidder -> huaweiAdsImpExt failed") } if huaweiAdsImpExt.SlotId == "" { @@ -1166,7 +1167,7 @@ func (a *adapter) extractAdmNative(adType int32, content *content, bidType openr } var nativePayload nativeRequests.Request - if err := json.Unmarshal(json.RawMessage(openrtb2Imp.Native.Request), &nativePayload); err != nil { + if err := jsonutil.Unmarshal(json.RawMessage(openrtb2Imp.Native.Request), &nativePayload); err != nil { return "", 0, 0, err } diff --git a/adapters/huaweiads/huaweiads_test.go b/adapters/huaweiads/huaweiads_test.go index 9e7d0b55364..c6fd17feaa7 100644 --- a/adapters/huaweiads/huaweiads_test.go +++ b/adapters/huaweiads/huaweiads_test.go @@ -3,9 +3,9 @@ package huaweiads import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/huaweiads/huaweiadstest/supplemental/missing_deviceid2.json b/adapters/huaweiads/huaweiadstest/supplemental/missing_deviceid2.json index 133282239cf..30028dee2ba 100644 --- a/adapters/huaweiads/huaweiadstest/supplemental/missing_deviceid2.json +++ b/adapters/huaweiads/huaweiadstest/supplemental/missing_deviceid2.json @@ -68,7 +68,7 @@ ], "expectedMakeRequestsErrors": [ { - "value": "get gaid from openrtb Device.IFA failed, and get device id failed: Unmarshal openRTBRequest.User.Ext -> extUserDataHuaweiAds. Error: json: cannot unmarshal object into Go struct field ExtUserDataDeviceIdHuaweiAds.data.gaid of type []string", + "value": "get gaid from openrtb Device.IFA failed, and get device id failed: Unmarshal openRTBRequest.User.Ext -> extUserDataHuaweiAds. Error: cannot unmarshal openrtb_ext.ExtUserDataDeviceIdHuaweiAds.Gaid: decode slice: expect [ or n, but found {", "comparison": "literal" } ] diff --git a/adapters/huaweiads/params_test.go b/adapters/huaweiads/params_test.go index c93c3c3ac55..9c4b5b36d25 100644 --- a/adapters/huaweiads/params_test.go +++ b/adapters/huaweiads/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/imds/imds.go b/adapters/imds/imds.go index 1fba38a0c6d..a5f53d60362 100644 --- a/adapters/imds/imds.go +++ b/adapters/imds/imds.go @@ -8,11 +8,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) const adapterVersion string = "pbs-go/1.0.0" @@ -136,14 +137,14 @@ func (adapter *adapter) buildEndpointURL(params *openrtb_ext.ExtImpImds) (string func getExtImpObj(imp *openrtb2.Imp) (*openrtb_ext.ExtImpImds, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: err.Error(), } } var imdsExt openrtb_ext.ExtImpImds - if err := json.Unmarshal(bidderExt.Bidder, &imdsExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &imdsExt); err != nil { return nil, &errortypes.BadInput{ Message: err.Error(), } @@ -170,7 +171,7 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } diff --git a/adapters/imds/imds_test.go b/adapters/imds/imds_test.go index 6e8165fbe6a..40a00462c13 100644 --- a/adapters/imds/imds_test.go +++ b/adapters/imds/imds_test.go @@ -3,9 +3,9 @@ package imds import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/imds/imdstest/supplemental/bad_response.json b/adapters/imds/imdstest/supplemental/bad_response.json index 9860bc7ac0d..ff7c089e53d 100644 --- a/adapters/imds/imdstest/supplemental/bad_response.json +++ b/adapters/imds/imdstest/supplemental/bad_response.json @@ -65,7 +65,7 @@ "expectedMakeBidsErrors": [ { "comparison": "literal", - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse" + "value": "expect { or n, but found \"" } ] } diff --git a/adapters/imds/imdstest/supplemental/bad_seat_id.json b/adapters/imds/imdstest/supplemental/bad_seat_id.json index 18630c592c4..5e4b879540d 100644 --- a/adapters/imds/imdstest/supplemental/bad_seat_id.json +++ b/adapters/imds/imdstest/supplemental/bad_seat_id.json @@ -24,7 +24,7 @@ "expectedMakeRequestsErrors": [ { - "value": "json: cannot unmarshal number into Go struct field ExtImpImds.seatId of type string", + "value": "cannot unmarshal openrtb_ext.ExtImpImds.SeatId: expects \" or n, but found 1", "comparison": "literal" } ] diff --git a/adapters/imds/params_test.go b/adapters/imds/params_test.go index 740105c3183..d98fe04cd1f 100644 --- a/adapters/imds/params_test.go +++ b/adapters/imds/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/imds.json diff --git a/adapters/impactify/impactify.go b/adapters/impactify/impactify.go index 960a29d6c9b..52f20ddd8dd 100644 --- a/adapters/impactify/impactify.go +++ b/adapters/impactify/impactify.go @@ -8,10 +8,11 @@ import ( "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -47,7 +48,7 @@ func (a *adapter) MakeRequests(bidRequest *openrtb2.BidRequest, reqInfo *adapter var impactifyExt ImpactifyExtBidder var defaultExt DefaultExtBidder - err := json.Unmarshal(bidRequest.Imp[i].Ext, &defaultExt) + err := jsonutil.Unmarshal(bidRequest.Imp[i].Ext, &defaultExt) if err != nil { return nil, []error{&errortypes.BadInput{ Message: fmt.Sprintf("Unable to decode the imp ext : \"%s\"", bidRequest.Imp[i].ID), @@ -128,7 +129,7 @@ func (a *adapter) MakeBids( var openRtbBidResponse openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &openRtbBidResponse); err != nil { + if err := jsonutil.Unmarshal(response.Body, &openRtbBidResponse); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: "Bad server body response", }} diff --git a/adapters/impactify/impactify_test.go b/adapters/impactify/impactify_test.go index b9518d5e2a3..2385c5c64ad 100644 --- a/adapters/impactify/impactify_test.go +++ b/adapters/impactify/impactify_test.go @@ -3,9 +3,9 @@ package impactify import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/impactify/params_test.go b/adapters/impactify/params_test.go index 2fa8b24d627..589e0901726 100644 --- a/adapters/impactify/params_test.go +++ b/adapters/impactify/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/improvedigital/improvedigital.go b/adapters/improvedigital/improvedigital.go index 392e1040eaa..13534cc6ddf 100644 --- a/adapters/improvedigital/improvedigital.go +++ b/adapters/improvedigital/improvedigital.go @@ -9,19 +9,17 @@ import ( "strings" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) const ( - isRewardedInventory = "is_rewarded_inventory" - stateRewardedInventoryEnable = "1" - consentProvidersSettingsInputKey = "ConsentedProvidersSettings" - consentProvidersSettingsOutKey = "consented_providers_settings" - consentedProvidersKey = "consented_providers" - publisherEndpointParam = "{PublisherId}" + isRewardedInventory = "is_rewarded_inventory" + stateRewardedInventoryEnable = "1" + publisherEndpointParam = "{PublisherId}" ) type ImprovedigitalAdapter struct { @@ -75,17 +73,6 @@ func (a *ImprovedigitalAdapter) makeRequest(request openrtb2.BidRequest, imp ope request.Imp = []openrtb2.Imp{imp} - userExtAddtlConsent, err := a.getAdditionalConsentProvidersUserExt(request) - if err != nil { - return nil, err - } - - if len(userExtAddtlConsent) > 0 { - userCopy := *request.User - userCopy.Ext = userExtAddtlConsent - request.User = &userCopy - } - reqJSON, err := json.Marshal(request) if err != nil { return nil, err @@ -123,7 +110,7 @@ func (a *ImprovedigitalAdapter) MakeBids(internalRequest *openrtb2.BidRequest, e var bidResp openrtb2.BidResponse var impMap = make(map[string]openrtb2.Imp) - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } @@ -159,7 +146,7 @@ func (a *ImprovedigitalAdapter) MakeBids(internalRequest *openrtb2.BidRequest, e if bid.Ext != nil { var bidExt BidExt - err = json.Unmarshal(bid.Ext, &bidExt) + err = jsonutil.Unmarshal(bid.Ext, &bidExt) if err != nil { return nil, []error{err} } @@ -255,72 +242,9 @@ func isMultiFormatImp(imp openrtb2.Imp) bool { return formatCount > 1 } -// This method responsible to clone request and convert additional consent providers string to array when additional consent provider found -func (a *ImprovedigitalAdapter) getAdditionalConsentProvidersUserExt(request openrtb2.BidRequest) ([]byte, error) { - var cpStr string - - // If user/user.ext not defined, no need to parse additional consent - if request.User == nil || request.User.Ext == nil { - return nil, nil - } - - // Start validating additional consent - // Check key exist user.ext.ConsentedProvidersSettings - var userExtMap = make(map[string]json.RawMessage) - if err := json.Unmarshal(request.User.Ext, &userExtMap); err != nil { - return nil, err - } - - cpsMapValue, cpsJSONFound := userExtMap[consentProvidersSettingsInputKey] - if !cpsJSONFound { - return nil, nil - } - - // Check key exist user.ext.ConsentedProvidersSettings.consented_providers - var cpMap = make(map[string]json.RawMessage) - if err := json.Unmarshal(cpsMapValue, &cpMap); err != nil { - return nil, err - } - - cpMapValue, cpJSONFound := cpMap[consentedProvidersKey] - if !cpJSONFound { - return nil, nil - } - // End validating additional consent - - // Trim enclosing quotes after casting json.RawMessage to string - consentStr := strings.Trim((string)(cpMapValue), "\"") - // Split by ~ and take only the second string (if exists) as the consented providers spec - var consentStrParts = strings.Split(consentStr, "~") - if len(consentStrParts) < 2 { - return nil, nil - } - cpStr = strings.TrimSpace(consentStrParts[1]) - if len(cpStr) == 0 { - return nil, nil - } - - // Prepare consent providers string - cpStr = fmt.Sprintf("[%s]", strings.Replace(cpStr, ".", ",", -1)) - cpMap[consentedProvidersKey] = json.RawMessage(cpStr) - - cpJSON, err := json.Marshal(cpMap) - if err != nil { - return nil, err - } - userExtMap[consentProvidersSettingsOutKey] = cpJSON - - extJson, err := json.Marshal(userExtMap) - if err != nil { - return nil, err - } - - return extJson, nil -} - func getImpExtWithRewardedInventory(imp openrtb2.Imp) ([]byte, error) { var ext = make(map[string]json.RawMessage) - if err := json.Unmarshal(imp.Ext, &ext); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &ext); err != nil { return nil, err } @@ -330,7 +254,7 @@ func getImpExtWithRewardedInventory(imp openrtb2.Imp) ([]byte, error) { } var prebidMap = make(map[string]json.RawMessage) - if err := json.Unmarshal(prebidJSONValue, &prebidMap); err != nil { + if err := jsonutil.Unmarshal(prebidJSONValue, &prebidMap); err != nil { return nil, err } @@ -351,7 +275,7 @@ func (a *ImprovedigitalAdapter) buildEndpointURL(imp openrtb2.Imp) string { publisherEndpoint := "" var impBidder ImpExtBidder - err := json.Unmarshal(imp.Ext, &impBidder) + err := jsonutil.Unmarshal(imp.Ext, &impBidder) if err == nil && impBidder.Bidder.PublisherID != 0 { publisherEndpoint = strconv.Itoa(impBidder.Bidder.PublisherID) + "/" } diff --git a/adapters/improvedigital/improvedigital_test.go b/adapters/improvedigital/improvedigital_test.go index b89e03320fa..cd00aeaab7c 100644 --- a/adapters/improvedigital/improvedigital_test.go +++ b/adapters/improvedigital/improvedigital_test.go @@ -3,9 +3,9 @@ package improvedigital import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/improvedigital/improvedigitaltest/supplemental/addtl-consent-multi-tilda.json b/adapters/improvedigital/improvedigitaltest/supplemental/addtl-consent-multi-tilda.json deleted file mode 100644 index 87007a6391c..00000000000 --- a/adapters/improvedigital/improvedigitaltest/supplemental/addtl-consent-multi-tilda.json +++ /dev/null @@ -1,95 +0,0 @@ -{ - "mockBidRequest": { - "id": "addtl-consent-request-id", - "site": { - "page": "https://good.site/url" - }, - "imp": [{ - "id": "test-imp-id", - "banner": { - "format": [{ - "w": 300, - "h": 250 - }] - }, - "ext": { - "bidder": { - "placementId": 13245 - } - } - }], - "user": { - "ext":{"consent":"ABC","ConsentedProvidersSettings":{"consented_providers":"1~10.20.90~2"}} - } - }, - - "httpCalls": [{ - "expectedRequest": { - "uri": "http://localhost/pbs", - "body": { - "id": "addtl-consent-request-id", - "site": { - "page": "https://good.site/url" - }, - "imp": [{ - "id": "test-imp-id", - "banner": { - "format": [{ - "w": 300, - "h": 250 - }] - }, - "ext": { - "bidder": { - "placementId": 13245 - } - } - }], - "user": { - "ext": {"consent": "ABC","ConsentedProvidersSettings":{"consented_providers":"1~10.20.90~2"},"consented_providers_settings": {"consented_providers": [10,20,90]} - } - } - }, - "impIDs": ["test-imp-id"] - }, - "mockResponse": { - "status": 200, - "body": { - "id": "addtl-consent-request-id", - "seatbid": [{ - "seat": "improvedigital", - "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": [{ - "bid": { - "id": "randomid", - "impid": "test-imp-id", - "price": 0.5, - "adm": "some-test-ad", - "adid": "12345678", - "cid": "987", - "crid": "12345678", - "w": 300, - "h": 250 - }, - "type": "banner" - }] - }] -} diff --git a/adapters/improvedigital/improvedigitaltest/supplemental/addtl-consent.json b/adapters/improvedigital/improvedigitaltest/supplemental/addtl-consent.json deleted file mode 100644 index f3980e64423..00000000000 --- a/adapters/improvedigital/improvedigitaltest/supplemental/addtl-consent.json +++ /dev/null @@ -1,95 +0,0 @@ -{ - "mockBidRequest": { - "id": "addtl-consent-request-id", - "site": { - "page": "https://good.site/url" - }, - "imp": [{ - "id": "test-imp-id", - "banner": { - "format": [{ - "w": 300, - "h": 250 - }] - }, - "ext": { - "bidder": { - "placementId": 13245 - } - } - }], - "user": { - "ext":{"consent":"ABC","ConsentedProvidersSettings":{"consented_providers":"1~10.20.90"}} - } - }, - - "httpCalls": [{ - "expectedRequest": { - "uri": "http://localhost/pbs", - "body": { - "id": "addtl-consent-request-id", - "site": { - "page": "https://good.site/url" - }, - "imp": [{ - "id": "test-imp-id", - "banner": { - "format": [{ - "w": 300, - "h": 250 - }] - }, - "ext": { - "bidder": { - "placementId": 13245 - } - } - }], - "user": { - "ext": {"consent": "ABC","ConsentedProvidersSettings":{"consented_providers":"1~10.20.90"},"consented_providers_settings": {"consented_providers": [10,20,90]} - } - } - }, - "impIDs":["test-imp-id"] - }, - "mockResponse": { - "status": 200, - "body": { - "id": "addtl-consent-request-id", - "seatbid": [{ - "seat": "improvedigital", - "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": [{ - "bid": { - "id": "randomid", - "impid": "test-imp-id", - "price": 0.5, - "adm": "some-test-ad", - "adid": "12345678", - "cid": "987", - "crid": "12345678", - "w": 300, - "h": 250 - }, - "type": "banner" - }] - }] -} diff --git a/adapters/improvedigital/improvedigitaltest/supplemental/bad_response.json b/adapters/improvedigital/improvedigitaltest/supplemental/bad_response.json index 5edafaaca68..6518f3c0938 100644 --- a/adapters/improvedigital/improvedigitaltest/supplemental/bad_response.json +++ b/adapters/improvedigital/improvedigitaltest/supplemental/bad_response.json @@ -57,7 +57,7 @@ "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/improvedigital/params_test.go b/adapters/improvedigital/params_test.go index 3767c0316a5..abb1491fb03 100644 --- a/adapters/improvedigital/params_test.go +++ b/adapters/improvedigital/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { @@ -36,7 +36,6 @@ func TestInvalidParams(t *testing.T) { var validParams = []string{ `{"placementId":13245}`, `{"placementId":13245, "size": {"w":16, "h":9}}`, - `{"publisherId":13245, "placementKey": "slotA"}`, `{"placementId":13245, "keyValues":{"target1":["foo"],"target2":["bar", "baz"]}}`, } @@ -56,5 +55,5 @@ var invalidParams = []string{ `{"placementId": "1"}`, `{"size": true}`, `{"placementId": true, "size":"1234567"}`, - `{"placementId":13245, "publisherId":13245, "placementKey": "slotA"}`, + `{"publisherId":13245, "placementKey": "slotA"}`, } diff --git a/adapters/infoawarebidder.go b/adapters/infoawarebidder.go index 9361e06fee0..e7b82c96a31 100644 --- a/adapters/infoawarebidder.go +++ b/adapters/infoawarebidder.go @@ -4,9 +4,9 @@ import ( "fmt" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // InfoAwareBidder wraps a Bidder to ensure all requests abide by the capabilities and diff --git a/adapters/infoawarebidder_test.go b/adapters/infoawarebidder_test.go index 7476cc920c9..4eb2dbffe30 100644 --- a/adapters/infoawarebidder_test.go +++ b/adapters/infoawarebidder_test.go @@ -5,10 +5,10 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/adapters/infytv/infytv.go b/adapters/infytv/infytv.go index a5d325e329f..1d0c70123a1 100644 --- a/adapters/infytv/infytv.go +++ b/adapters/infytv/infytv.go @@ -7,10 +7,11 @@ import ( "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -64,7 +65,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: fmt.Sprintf("Bad response, %s", err), }} diff --git a/adapters/infytv/infytv_test.go b/adapters/infytv/infytv_test.go index 80527bbc4ae..85a4dd4b9bc 100644 --- a/adapters/infytv/infytv_test.go +++ b/adapters/infytv/infytv_test.go @@ -3,9 +3,9 @@ package infytv import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/infytv/infytvtest/supplemental/bad-response.json b/adapters/infytv/infytvtest/supplemental/bad-response.json index 01d560cf5e7..05134ef403f 100644 --- a/adapters/infytv/infytvtest/supplemental/bad-response.json +++ b/adapters/infytv/infytvtest/supplemental/bad-response.json @@ -195,7 +195,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "Bad response, json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "Bad response, expect { or n, but found \"", "comparison": "literal" } ], diff --git a/adapters/infytv/params_test.go b/adapters/infytv/params_test.go index 53230cbf263..671a5a4e713 100644 --- a/adapters/infytv/params_test.go +++ b/adapters/infytv/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/inmobi/inmobi.go b/adapters/inmobi/inmobi.go index 9ceac3ec01a..f79151bea87 100644 --- a/adapters/inmobi/inmobi.go +++ b/adapters/inmobi/inmobi.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type InMobiAdapter struct { @@ -69,7 +70,7 @@ func (a *InMobiAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalR } var serverBidResponse openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &serverBidResponse); err != nil { + if err := jsonutil.Unmarshal(response.Body, &serverBidResponse); err != nil { return nil, []error{err} } @@ -77,7 +78,10 @@ func (a *InMobiAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalR for _, sb := range serverBidResponse.SeatBid { for i := range sb.Bid { - mediaType := getMediaTypeForImp(sb.Bid[i].ImpID, internalRequest.Imp) + mediaType, err := getMediaTypeForImp(sb.Bid[i]) + if err != nil { + return nil, []error{err} + } bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ Bid: &sb.Bid[i], BidType: mediaType, @@ -90,14 +94,14 @@ func (a *InMobiAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalR func preprocess(imp *openrtb2.Imp) error { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return &errortypes.BadInput{ Message: err.Error(), } } var inMobiExt openrtb_ext.ExtImpInMobi - if err := json.Unmarshal(bidderExt.Bidder, &inMobiExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &inMobiExt); err != nil { return &errortypes.BadInput{Message: "bad InMobi bidder ext"} } @@ -118,18 +122,17 @@ func preprocess(imp *openrtb2.Imp) error { return nil } -func getMediaTypeForImp(impId string, imps []openrtb2.Imp) openrtb_ext.BidType { - mediaType := openrtb_ext.BidTypeBanner - for _, imp := range imps { - if imp.ID == impId { - if imp.Video != nil { - mediaType = openrtb_ext.BidTypeVideo - } - if imp.Native != nil { - mediaType = openrtb_ext.BidTypeNative - } - break +func getMediaTypeForImp(bid openrtb2.Bid) (openrtb_ext.BidType, error) { + switch bid.MType { + case openrtb2.MarkupBanner: + return openrtb_ext.BidTypeBanner, nil + case openrtb2.MarkupVideo: + return openrtb_ext.BidTypeVideo, nil + case openrtb2.MarkupNative: + return openrtb_ext.BidTypeNative, nil + default: + return "", &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Unsupported mtype %d for bid %s", bid.MType, bid.ID), } } - return mediaType } diff --git a/adapters/inmobi/inmobi_test.go b/adapters/inmobi/inmobi_test.go index 40e77f5fbc3..89884a8ddeb 100644 --- a/adapters/inmobi/inmobi_test.go +++ b/adapters/inmobi/inmobi_test.go @@ -3,9 +3,9 @@ package inmobi import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/inmobi/inmobitest/exemplary/simple-app-banner.json b/adapters/inmobi/inmobitest/exemplary/simple-app-banner.json index 563c8b9103e..01ccd98596f 100644 --- a/adapters/inmobi/inmobitest/exemplary/simple-app-banner.json +++ b/adapters/inmobi/inmobitest/exemplary/simple-app-banner.json @@ -75,7 +75,8 @@ "price": 2.0, "id": "1234", "adm": "bannerhtml", - "impid": "imp-id" + "impid": "imp-id", + "mtype": 1 } ] } @@ -94,6 +95,7 @@ "adm": "bannerhtml", "crid": "123456789", "nurl": "https://some.event.url/params", + "mtype": 1, "ext": { "prebid": { "meta": { diff --git a/adapters/inmobi/inmobitest/exemplary/simple-app-native.json b/adapters/inmobi/inmobitest/exemplary/simple-app-native.json index 7b823c13e11..0e956b6e586 100644 --- a/adapters/inmobi/inmobitest/exemplary/simple-app-native.json +++ b/adapters/inmobi/inmobitest/exemplary/simple-app-native.json @@ -73,7 +73,8 @@ "price": 2.0, "id": "1234", "adm": "native-json", - "impid": "imp-id" + "impid": "imp-id", + "mtype": 4 } ] } @@ -92,6 +93,7 @@ "adm": "native-json", "crid": "123456789", "nurl": "https://some.event.url/params", + "mtype": 4, "ext": { "prebid": { "meta": { diff --git a/adapters/inmobi/inmobitest/exemplary/simple-app-video.json b/adapters/inmobi/inmobitest/exemplary/simple-app-video.json index 69356fd4de7..644b42d573a 100644 --- a/adapters/inmobi/inmobitest/exemplary/simple-app-video.json +++ b/adapters/inmobi/inmobitest/exemplary/simple-app-video.json @@ -77,7 +77,8 @@ "price": 2.0, "id": "1234", "adm": " ", - "impid": "imp-id" + "impid": "imp-id", + "mtype": 2 } ] } @@ -96,6 +97,7 @@ "adm": " ", "crid": "123456789", "nurl": "https://some.event.url/params", + "mtype": 2, "ext": { "prebid": { "meta": { diff --git a/adapters/inmobi/inmobitest/exemplary/simple-web-banner.json b/adapters/inmobi/inmobitest/exemplary/simple-web-banner.json index 0aac1b1571d..3359906e436 100644 --- a/adapters/inmobi/inmobitest/exemplary/simple-web-banner.json +++ b/adapters/inmobi/inmobitest/exemplary/simple-web-banner.json @@ -73,7 +73,8 @@ "price": 2.0, "id": "1234", "adm": "bannerhtml", - "impid": "imp-id" + "impid": "imp-id", + "mtype": 1 } ] } @@ -92,6 +93,7 @@ "adm": "bannerhtml", "crid": "123456789", "nurl": "https://some.event.url/params", + "mtype": 1, "ext": { "prebid": { "meta": { diff --git a/adapters/inmobi/inmobitest/exemplary/simple-web-native.json b/adapters/inmobi/inmobitest/exemplary/simple-web-native.json new file mode 100644 index 00000000000..25313573ea8 --- /dev/null +++ b/adapters/inmobi/inmobitest/exemplary/simple-web-native.json @@ -0,0 +1,106 @@ +{ + "mockBidRequest": { + "site": { + "page": "https://www.inmobi.com" + }, + "id": "req-id", + "device": { + "ip": "1.1.1.1", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G960F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36" + }, + "imp": [ + { + "ext": { + "bidder": { + "plc": "1716021069867" + } + }, + "native": { + "request": "{\"ver\":\"1.2\",\"context\":2,\"contextsubtype\":20,\"plcmttype\":11,\"plcmtcnt\":1,\"aurlsupport\":1,\"durlsupport\":1,\"assets\":[{\"id\":123,\"required\":1,\"title\":{\"len\":140}},{\"id\":128,\"required\":0,\"img\":{\"wmin\":836,\"hmin\":627,\"type\":3}}]}" + }, + "id": "imp-id" + } + ] + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://api.w.inmobi.com/showad/openrtb/bidder/prebid", + "body": { + "site": { + "page": "https://www.inmobi.com" + }, + "id": "req-id", + "device": { + "ip": "1.1.1.1", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G960F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36" + }, + "imp": [ + { + "ext": { + "bidder": { + "plc": "1716021069867" + } + }, + "native": { + "request": "{\"ver\":\"1.2\",\"context\":2,\"contextsubtype\":20,\"plcmttype\":11,\"plcmtcnt\":1,\"aurlsupport\":1,\"durlsupport\":1,\"assets\":[{\"id\":123,\"required\":1,\"title\":{\"len\":140}},{\"id\":128,\"required\":0,\"img\":{\"wmin\":836,\"hmin\":627,\"type\":3}}]}" + }, + "id": "imp-id" + } + ] + }, + "impIDs":["imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "req-id", + "seatbid": [ + { + "bid": [ + { + "ext": { + "prebid": { + "meta": { + "networkName": "inmobi" + } + } + }, + "nurl": "https://some.event.url/params", + "crid": "123456789", + "adomain": [], + "price": 2.0, + "id": "1234", + "adm": "native-json", + "impid": "imp-id", + "mtype": 4 + } + ] + } + ] + } + } + }], + + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "bid": { + "id": "1234", + "impid": "imp-id", + "price": 2.0, + "adm": "native-json", + "crid": "123456789", + "nurl": "https://some.event.url/params", + "mtype": 4, + "ext": { + "prebid": { + "meta": { + "networkName": "inmobi" + } + } + } + }, + "type": "native" + }] + }] +} diff --git a/adapters/inmobi/inmobitest/exemplary/simple-web-video.json b/adapters/inmobi/inmobitest/exemplary/simple-web-video.json index 7ea5dd268ef..582f9044fc9 100644 --- a/adapters/inmobi/inmobitest/exemplary/simple-web-video.json +++ b/adapters/inmobi/inmobitest/exemplary/simple-web-video.json @@ -75,7 +75,8 @@ "price": 2.0, "id": "1234", "adm": " ", - "impid": "imp-id" + "impid": "imp-id", + "mtype": 2 } ] } @@ -94,6 +95,7 @@ "adm": " ", "crid": "123456789", "nurl": "https://some.event.url/params", + "mtype": 2, "ext": { "prebid": { "meta": { diff --git a/adapters/inmobi/inmobitest/supplemental/banner-format-coersion.json b/adapters/inmobi/inmobitest/supplemental/banner-format-coersion.json index 211348de3f3..ee6aae529ee 100644 --- a/adapters/inmobi/inmobitest/supplemental/banner-format-coersion.json +++ b/adapters/inmobi/inmobitest/supplemental/banner-format-coersion.json @@ -81,7 +81,8 @@ "price": 2.0, "id": "1234", "adm": "bannerhtml", - "impid": "imp-id" + "impid": "imp-id", + "mtype": 1 } ] } @@ -100,6 +101,7 @@ "adm": "bannerhtml", "crid": "123456789", "nurl": "https://some.event.url/params", + "mtype": 1, "ext": { "prebid": { "meta": { diff --git a/adapters/inmobi/inmobitest/supplemental/invalid-mtype.json b/adapters/inmobi/inmobitest/supplemental/invalid-mtype.json new file mode 100644 index 00000000000..af2192836b0 --- /dev/null +++ b/adapters/inmobi/inmobitest/supplemental/invalid-mtype.json @@ -0,0 +1,97 @@ +{ + "mockBidRequest": { + "site": { + "page": "https://www.inmobi.com" + }, + "id": "req-id", + "device": { + "ip": "1.1.1.1", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G960F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36" + }, + "imp": [ + { + "ext": { + "bidder": { + "plc": "1621323101291" + } + }, + "video": { + "w": 640, + "h": 360, + "mimes": ["video/mp4"] + }, + "id": "imp-id" + } + ] + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://api.w.inmobi.com/showad/openrtb/bidder/prebid", + "body": { + "site": { + "page": "https://www.inmobi.com" + }, + "id": "req-id", + "device": { + "ip": "1.1.1.1", + "ua": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G960F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36" + }, + "imp": [ + { + "ext": { + "bidder": { + "plc": "1621323101291" + } + }, + "video": { + "w": 640, + "h": 360, + "mimes": ["video/mp4"] + }, + "id": "imp-id" + } + ] + }, + "impIDs":["imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "req-id", + "seatbid": [ + { + "bid": [ + { + "ext": { + "prebid": { + "meta": { + "networkName": "inmobi" + } + } + }, + "nurl": "https://some.event.url/params", + "crid": "123456789", + "adomain": [], + "price": 2.0, + "id": "1234", + "adm": " ", + "impid": "imp-id", + "mtype": 0 + } + ] + } + ] + } + } + }], + + "expectedBidResponses":[], + "expectedMakeBidsErrors":[ + { + "value":"Unsupported mtype 0 for bid 1234", + "comparison":"literal" + } + ] +} + + diff --git a/adapters/interactiveoffers/interactiveoffers.go b/adapters/interactiveoffers/interactiveoffers.go index 53286aa9cc7..6eaee7a9785 100644 --- a/adapters/interactiveoffers/interactiveoffers.go +++ b/adapters/interactiveoffers/interactiveoffers.go @@ -7,11 +7,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -21,14 +22,14 @@ type adapter struct { func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { var errors []error var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(request.Imp[0].Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(request.Imp[0].Ext, &bidderExt); err != nil { errors = append(errors, &errortypes.BadInput{ Message: err.Error(), }) return nil, errors } var ioExt *openrtb_ext.ExtImpInteractiveoffers - if err := json.Unmarshal(bidderExt.Bidder, &ioExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &ioExt); err != nil { errors = append(errors, &errortypes.BadInput{ Message: err.Error(), }) @@ -76,7 +77,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } diff --git a/adapters/interactiveoffers/interactiveoffers_test.go b/adapters/interactiveoffers/interactiveoffers_test.go index daf83869a95..df116c60a5d 100644 --- a/adapters/interactiveoffers/interactiveoffers_test.go +++ b/adapters/interactiveoffers/interactiveoffers_test.go @@ -3,9 +3,9 @@ package interactiveoffers import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/interactiveoffers/interactiveofferstest/supplemental/wrongjsonresponse.json b/adapters/interactiveoffers/interactiveofferstest/supplemental/wrongjsonresponse.json index 3f087a0d79c..750c0a4bb68 100644 --- a/adapters/interactiveoffers/interactiveofferstest/supplemental/wrongjsonresponse.json +++ b/adapters/interactiveoffers/interactiveofferstest/supplemental/wrongjsonresponse.json @@ -54,7 +54,7 @@ "expectedBidResponses": [], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/interactiveoffers/params_test.go b/adapters/interactiveoffers/params_test.go index 8f14a51b512..631d8f44aed 100644 --- a/adapters/interactiveoffers/params_test.go +++ b/adapters/interactiveoffers/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/invibes/invibes.go b/adapters/invibes/invibes.go index ecb3ebae4e8..4657be29745 100644 --- a/adapters/invibes/invibes.go +++ b/adapters/invibes/invibes.go @@ -10,12 +10,13 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/metrics" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/metrics" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) const adapterVersion = "prebid_1.0.0" @@ -100,14 +101,14 @@ func (a *InvibesAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *ada for _, imp := range request.Imp { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { tempErrors = append(tempErrors, &errortypes.BadInput{ Message: "Error parsing bidderExt object", }) continue } var invibesExt openrtb_ext.ExtImpInvibes - if err := json.Unmarshal(bidderExt.Bidder, &invibesExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &invibesExt); err != nil { tempErrors = append(tempErrors, &errortypes.BadInput{ Message: "Error parsing invibesExt parameters", }) @@ -159,14 +160,14 @@ func readGDPR(request *openrtb2.BidRequest) (bool, string) { consentString := "" if request.User != nil { var extUser openrtb_ext.ExtUser - if err := json.Unmarshal(request.User.Ext, &extUser); err == nil { + if err := jsonutil.Unmarshal(request.User.Ext, &extUser); err == nil { consentString = extUser.Consent } } gdprApplies := true var extRegs openrtb_ext.ExtRegs if request.Regs != nil { - if err := json.Unmarshal(request.Regs.Ext, &extRegs); err == nil { + if err := jsonutil.Unmarshal(request.Regs.Ext, &extRegs); err == nil { if extRegs.GDPR != nil { gdprApplies = (*extRegs.GDPR == 1) } @@ -315,7 +316,7 @@ func (a *InvibesAdapter) MakeBids( } bidResponse := BidServerBidderResponse{} - if err := json.Unmarshal(response.Body, &bidResponse); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResponse); err != nil { return nil, []error{err} } diff --git a/adapters/invibes/invibes_test.go b/adapters/invibes/invibes_test.go index e09837764f9..be8dda3ffdf 100644 --- a/adapters/invibes/invibes_test.go +++ b/adapters/invibes/invibes_test.go @@ -3,9 +3,9 @@ package invibes import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/invibes/params_test.go b/adapters/invibes/params_test.go index 88e08d1dc80..48be52c4ba0 100644 --- a/adapters/invibes/params_test.go +++ b/adapters/invibes/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/iqx/iqx.go b/adapters/iqx/iqx.go index 23da6bc8947..c3519b10b1a 100644 --- a/adapters/iqx/iqx.go +++ b/adapters/iqx/iqx.go @@ -7,11 +7,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type bidType struct { @@ -41,14 +42,14 @@ func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server co func (a *adapter) buildEndpointFromRequest(imp *openrtb2.Imp) (string, error) { var impExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &impExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &impExt); err != nil { return "", &errortypes.BadInput{ Message: fmt.Sprintf("Failed to deserialize bidder impression extension: %v", err), } } var iqzonexExt openrtb_ext.ExtIQX - if err := json.Unmarshal(impExt.Bidder, &iqzonexExt); err != nil { + if err := jsonutil.Unmarshal(impExt.Bidder, &iqzonexExt); err != nil { return "", &errortypes.BadInput{ Message: fmt.Sprintf("Failed to deserialize IQZonex extension: %v", err), } @@ -116,7 +117,7 @@ func (a *adapter) MakeBids(openRTBRequest *openrtb2.BidRequest, requestToBidder } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(bidderRawResponse.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(bidderRawResponse.Body, &bidResp); err != nil { return nil, []error{err} } diff --git a/adapters/iqx/iqxtest_test.go b/adapters/iqx/iqxtest_test.go index 7385d37af91..190560d6deb 100644 --- a/adapters/iqx/iqxtest_test.go +++ b/adapters/iqx/iqxtest_test.go @@ -3,9 +3,9 @@ package iqx import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/iqx/iqzonextest/supplemental/bad-response.json b/adapters/iqx/iqzonextest/supplemental/bad-response.json index a5cc1f2aeae..a0f8dc8c960 100644 --- a/adapters/iqx/iqzonextest/supplemental/bad-response.json +++ b/adapters/iqx/iqzonextest/supplemental/bad-response.json @@ -99,7 +99,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ], diff --git a/adapters/iqx/iqzonextest/supplemental/invalid-ext-bidder-object.json b/adapters/iqx/iqzonextest/supplemental/invalid-ext-bidder-object.json index 2f124a8cf3b..22612977a87 100644 --- a/adapters/iqx/iqzonextest/supplemental/invalid-ext-bidder-object.json +++ b/adapters/iqx/iqzonextest/supplemental/invalid-ext-bidder-object.json @@ -42,7 +42,7 @@ "httpCalls": [], "expectedMakeRequestsErrors": [ { - "value": "Failed to deserialize IQZonex extension: json: cannot unmarshal array into Go value of type openrtb_ext.ExtIQX", + "value": "Failed to deserialize IQZonex extension: expect { or n, but found [", "comparison": "literal" } ] diff --git a/adapters/iqx/iqzonextest/supplemental/invalid-ext-object.json b/adapters/iqx/iqzonextest/supplemental/invalid-ext-object.json index aa215eb3e34..16cf58bbe54 100644 --- a/adapters/iqx/iqzonextest/supplemental/invalid-ext-object.json +++ b/adapters/iqx/iqzonextest/supplemental/invalid-ext-object.json @@ -40,7 +40,7 @@ "httpCalls": [], "expectedMakeRequestsErrors": [ { - "value": "Failed to deserialize bidder impression extension: json: cannot unmarshal string into Go value of type adapters.ExtImpBidder", + "value": "Failed to deserialize bidder impression extension: expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/iqx/params_test.go b/adapters/iqx/params_test.go index 23c4d007acb..4b687728b2b 100644 --- a/adapters/iqx/params_test.go +++ b/adapters/iqx/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/iqzone/iqzone.go b/adapters/iqzone/iqzone.go index db570707ba8..9becbfbb89b 100644 --- a/adapters/iqzone/iqzone.go +++ b/adapters/iqzone/iqzone.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -35,10 +36,10 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E var bidderExt adapters.ExtImpBidder var iqzoneExt openrtb_ext.ImpExtIQZone - if err = json.Unmarshal(reqCopy.Imp[0].Ext, &bidderExt); err != nil { + if err = jsonutil.Unmarshal(reqCopy.Imp[0].Ext, &bidderExt); err != nil { return nil, append(errs, err) } - if err = json.Unmarshal(bidderExt.Bidder, &iqzoneExt); err != nil { + if err = jsonutil.Unmarshal(bidderExt.Bidder, &iqzoneExt); err != nil { return nil, append(errs, err) } @@ -104,7 +105,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } diff --git a/adapters/iqzone/iqzone_test.go b/adapters/iqzone/iqzone_test.go index c5713953f40..37ba833f502 100644 --- a/adapters/iqzone/iqzone_test.go +++ b/adapters/iqzone/iqzone_test.go @@ -3,9 +3,9 @@ package iqzone import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/iqzone/iqzonetest/supplemental/bad_response.json b/adapters/iqzone/iqzonetest/supplemental/bad_response.json index 6bae2a728a7..03d00712772 100644 --- a/adapters/iqzone/iqzonetest/supplemental/bad_response.json +++ b/adapters/iqzone/iqzonetest/supplemental/bad_response.json @@ -78,7 +78,7 @@ }], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/iqzone/params_test.go b/adapters/iqzone/params_test.go index 2c6bb223845..4d3aa165a65 100644 --- a/adapters/iqzone/params_test.go +++ b/adapters/iqzone/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/ix/ix.go b/adapters/ix/ix.go index 23f60d4b905..48becbdcf4c 100644 --- a/adapters/ix/ix.go +++ b/adapters/ix/ix.go @@ -7,12 +7,13 @@ import ( "sort" "strings" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/ptrutil" - "github.com/prebid/prebid-server/v2/version" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/ptrutil" + "github.com/prebid/prebid-server/v3/version" "github.com/prebid/openrtb/v20/native1" native1response "github.com/prebid/openrtb/v20/native1/response" @@ -95,7 +96,7 @@ func (a *IxAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters setPublisherId(&requestCopy, uniqueSiteIDs, ixDiag) - err := setIxDiagIntoExtRequest(&requestCopy, ixDiag) + err := setIxDiagIntoExtRequest(&requestCopy, ixDiag, version.Ver) if err != nil { errs = append(errs, err) } @@ -155,12 +156,12 @@ func setPublisherId(requestCopy *openrtb2.BidRequest, uniqueSiteIDs map[string]s func unmarshalToIxExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpIx, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, err } var ixExt openrtb_ext.ExtImpIx - if err := json.Unmarshal(bidderExt.Bidder, &ixExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &ixExt); err != nil { return nil, err } @@ -203,7 +204,7 @@ func (a *IxAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalReque } var bidResponse openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResponse); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResponse); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: fmt.Sprintf("JSON parsing error: %v", err), }} @@ -243,7 +244,7 @@ func (a *IxAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalReque var bidExtVideo *openrtb_ext.ExtBidPrebidVideo var bidExt openrtb_ext.ExtBid if bidType == openrtb_ext.BidTypeVideo { - unmarshalExtErr := json.Unmarshal(bid.Ext, &bidExt) + unmarshalExtErr := jsonutil.Unmarshal(bid.Ext, &bidExt) if unmarshalExtErr == nil && bidExt.Prebid != nil && bidExt.Prebid.Video != nil { bidExtVideo = &openrtb_ext.ExtBidPrebidVideo{ Duration: bidExt.Prebid.Video.Duration, @@ -256,7 +257,7 @@ func (a *IxAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalReque var bidNative1v1 *Native11Wrapper if bidType == openrtb_ext.BidTypeNative { - err := json.Unmarshal([]byte(bid.AdM), &bidNative1v1) + err := jsonutil.Unmarshal([]byte(bid.AdM), &bidNative1v1) if err == nil && len(bidNative1v1.Native.EventTrackers) > 0 { mergeNativeImpTrackers(&bidNative1v1.Native) if json, err := marshalJsonWithoutUnicode(bidNative1v1); err == nil { @@ -267,7 +268,7 @@ func (a *IxAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalReque var bidNative1v2 *native1response.Response if bidType == openrtb_ext.BidTypeNative { - err := json.Unmarshal([]byte(bid.AdM), &bidNative1v2) + err := jsonutil.Unmarshal([]byte(bid.AdM), &bidNative1v2) if err == nil && len(bidNative1v2.EventTrackers) > 0 { mergeNativeImpTrackers(bidNative1v2) if json, err := marshalJsonWithoutUnicode(bidNative1v2); err == nil { @@ -286,7 +287,7 @@ func (a *IxAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalReque if bidResponse.Ext != nil { var bidRespExt ixRespExt - if err := json.Unmarshal(bidResponse.Ext, &bidRespExt); err != nil { + if err := jsonutil.Unmarshal(bidResponse.Ext, &bidRespExt); err != nil { return nil, append(errs, err) } @@ -321,7 +322,7 @@ func getMediaTypeForBid(bid openrtb2.Bid, impMediaTypeReq map[string]openrtb_ext if bid.Ext != nil { var bidExt openrtb_ext.ExtBid - err := json.Unmarshal(bid.Ext, &bidExt) + err := jsonutil.Unmarshal(bid.Ext, &bidExt) if err == nil && bidExt.Prebid != nil { prebidType := string(bidExt.Prebid.Type) if prebidType != "" { @@ -392,10 +393,20 @@ func marshalJsonWithoutUnicode(v interface{}) (string, error) { return strings.TrimSuffix(sb.String(), "\n"), nil } -func setIxDiagIntoExtRequest(request *openrtb2.BidRequest, ixDiag *IxDiag) error { +// extractVersionWithoutCommitHash takes a version string like '0.23.1-g4ee257d8' and returns +// the prefix without the commit hash: '0.23.1' - +// the substring preceding the first hyphen. +func extractVersionWithoutCommitHash(ver string) string { + if strings.Contains(ver, "-") { + return ver[:strings.Index(ver, "-")] + } + return ver // if no hyphen, return the original string +} + +func setIxDiagIntoExtRequest(request *openrtb2.BidRequest, ixDiag *IxDiag, ver string) error { extRequest := &ExtRequest{} if request.Ext != nil { - if err := json.Unmarshal(request.Ext, &extRequest); err != nil { + if err := jsonutil.Unmarshal(request.Ext, &extRequest); err != nil { return err } } @@ -404,17 +415,15 @@ func setIxDiagIntoExtRequest(request *openrtb2.BidRequest, ixDiag *IxDiag) error ixDiag.PbjsV = extRequest.Prebid.Channel.Version } // Slice commit hash out of version - if strings.Contains(version.Ver, "-") { - ixDiag.PbsV = version.Ver[:strings.Index(version.Ver, "-")] - } else if version.Ver != "" { - ixDiag.PbsV = version.Ver + if ver != "" { + ixDiag.PbsV = extractVersionWithoutCommitHash(ver) } // Only set request.ext if ixDiag is not empty if *ixDiag != (IxDiag{}) { extRequest := &ExtRequest{} if request.Ext != nil { - if err := json.Unmarshal(request.Ext, &extRequest); err != nil { + if err := jsonutil.Unmarshal(request.Ext, &extRequest); err != nil { return err } } @@ -436,7 +445,7 @@ func moveSid(imp *openrtb2.Imp, ixExt *openrtb_ext.ExtImpIx) error { if ixExt.Sid != "" { var m map[string]interface{} - if err := json.Unmarshal(imp.Ext, &m); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &m); err != nil { return err } m["sid"] = ixExt.Sid diff --git a/adapters/ix/ix_test.go b/adapters/ix/ix_test.go index 2b48327605a..48b9796bbb5 100644 --- a/adapters/ix/ix_test.go +++ b/adapters/ix/ix_test.go @@ -4,12 +4,11 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/ptrutil" - "github.com/prebid/prebid-server/v2/version" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/ptrutil" "github.com/stretchr/testify/assert" "github.com/prebid/openrtb/v20/adcom1" @@ -152,6 +151,34 @@ func TestIxMakeRequestWithGppString(t *testing.T) { assert.Equal(t, req.Regs.GPP, testGppString) } +func TestExtractVersionWithoutCommitHash(t *testing.T) { + tests := []struct { + name string + version string + expected string + }{ + { + name: "empty version", + version: "", + expected: "", + }, + { + name: "version with commit hash", + version: "1.880-abcdef", + expected: "1.880", + }, + { + name: "version without commit hash", + version: "1.23.4", + expected: "1.23.4", + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + assert.Equal(t, test.expected, extractVersionWithoutCommitHash(test.version)) + }) + } +} func TestBuildIxDiag(t *testing.T) { testCases := []struct { description string @@ -253,9 +280,8 @@ func TestBuildIxDiag(t *testing.T) { for _, test := range testCases { t.Run(test.description, func(t *testing.T) { - version.Ver = test.pbsVersion ixDiag := &IxDiag{} - err := setIxDiagIntoExtRequest(test.request, ixDiag) + err := setIxDiagIntoExtRequest(test.request, ixDiag, test.pbsVersion) if test.expectError { assert.NotNil(t, err) } else { diff --git a/adapters/ix/ixtest/supplemental/bad-ext-bidder.json b/adapters/ix/ixtest/supplemental/bad-ext-bidder.json index e08da1e1a84..87378ca3ce1 100644 --- a/adapters/ix/ixtest/supplemental/bad-ext-bidder.json +++ b/adapters/ix/ixtest/supplemental/bad-ext-bidder.json @@ -15,7 +15,7 @@ }, "expectedMakeRequestsErrors": [ { - "value": "json: cannot unmarshal number into Go struct field ExtImpBidder.prebid of type openrtb_ext.ExtImpPrebid", + "value": "cannot unmarshal adapters.ExtImpBidder.Prebid: expect { or n, but found 1", "comparison": "literal" } ] diff --git a/adapters/ix/ixtest/supplemental/bad-ext-ix.json b/adapters/ix/ixtest/supplemental/bad-ext-ix.json index a9a0383b1a1..a9d533b9172 100644 --- a/adapters/ix/ixtest/supplemental/bad-ext-ix.json +++ b/adapters/ix/ixtest/supplemental/bad-ext-ix.json @@ -14,8 +14,8 @@ }, "expectedMakeRequestsErrors": [ { - "value": "unexpected end of JSON input", - "comparison": "literal" + "value": "expect { or n, but found", + "comparison": "startswith" } ] } diff --git a/adapters/ix/ixtest/supplemental/bad-fledge.json b/adapters/ix/ixtest/supplemental/bad-fledge.json index 42459148e0a..d835d40a33f 100644 --- a/adapters/ix/ixtest/supplemental/bad-fledge.json +++ b/adapters/ix/ixtest/supplemental/bad-fledge.json @@ -128,7 +128,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal number into Go struct field auctionConfig.protectedAudienceAuctionConfigs.bidId of type string", + "value": "cannot unmarshal ix.auctionConfig.BidId: expects \" or n, but found 1", "comparison": "literal" } ] diff --git a/adapters/ix/ixtest/supplemental/bad-response-body.json b/adapters/ix/ixtest/supplemental/bad-response-body.json index eae3fbdb36b..e416123023f 100644 --- a/adapters/ix/ixtest/supplemental/bad-response-body.json +++ b/adapters/ix/ixtest/supplemental/bad-response-body.json @@ -59,7 +59,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "JSON parsing error: json: cannot unmarshal number into Go struct field BidResponse.id of type string", + "value": "JSON parsing error: cannot unmarshal openrtb2.BidResponse.ID: expects \" or n, but found 1", "comparison": "literal" } ] diff --git a/adapters/ix/ixtest/supplemental/multi-imp-requests-error.json b/adapters/ix/ixtest/supplemental/multi-imp-requests-error.json index 7b43ca7961c..6613dce7169 100644 --- a/adapters/ix/ixtest/supplemental/multi-imp-requests-error.json +++ b/adapters/ix/ixtest/supplemental/multi-imp-requests-error.json @@ -183,7 +183,7 @@ ], "expectedMakeRequestsErrors": [ { - "value": "json: cannot unmarshal number into Go struct field ExtImpIx.sid of type string", + "value": "cannot unmarshal openrtb_ext.ExtImpIx.Sid: expects \" or n, but found 1", "comparison": "literal" } ] diff --git a/adapters/ix/params_test.go b/adapters/ix/params_test.go index ba426c0b27b..90d591b50c0 100644 --- a/adapters/ix/params_test.go +++ b/adapters/ix/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/jixie/jixie.go b/adapters/jixie/jixie.go index 7079e403880..d0411d1e5ef 100644 --- a/adapters/jixie/jixie.go +++ b/adapters/jixie/jixie.go @@ -7,10 +7,11 @@ import ( "strings" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -102,7 +103,7 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: fmt.Sprintf("Unable to unpackage bid response. Error: %s", err.Error()), }} diff --git a/adapters/jixie/jixie_test.go b/adapters/jixie/jixie_test.go index dff2b3574d3..6fe4fa24cef 100644 --- a/adapters/jixie/jixie_test.go +++ b/adapters/jixie/jixie_test.go @@ -3,9 +3,9 @@ package jixie import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/jixie/params_test.go b/adapters/jixie/params_test.go index cbcdbe959de..653f3f86e12 100644 --- a/adapters/jixie/params_test.go +++ b/adapters/jixie/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/kargo/kargo.go b/adapters/kargo/kargo.go index e6a06dea179..da12ef68ca3 100644 --- a/adapters/kargo/kargo.go +++ b/adapters/kargo/kargo.go @@ -7,10 +7,11 @@ import ( "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -59,7 +60,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } @@ -79,7 +80,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R func getMediaTypeForBid(ext json.RawMessage) openrtb_ext.BidType { var impExt kargoExt - if err := json.Unmarshal(ext, &impExt); err == nil { + if err := jsonutil.Unmarshal(ext, &impExt); err == nil { switch impExt.MediaType { case string(openrtb_ext.BidTypeVideo): return openrtb_ext.BidTypeVideo diff --git a/adapters/kargo/kargo_test.go b/adapters/kargo/kargo_test.go index f2ceb46f643..0e7eb83bc13 100644 --- a/adapters/kargo/kargo_test.go +++ b/adapters/kargo/kargo_test.go @@ -3,9 +3,9 @@ package kargo import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/kargo/params_test.go b/adapters/kargo/params_test.go index 9907d67116c..91b46fbc4e7 100644 --- a/adapters/kargo/params_test.go +++ b/adapters/kargo/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/kayzen/kayzen.go b/adapters/kayzen/kayzen.go index f3b8153f97f..680362603ef 100644 --- a/adapters/kayzen/kayzen.go +++ b/adapters/kayzen/kayzen.go @@ -7,11 +7,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -76,13 +77,13 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E func (a *adapter) getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtKayzen, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: "Bidder extension not provided or can't be unmarshalled", } } var kayzenExt openrtb_ext.ExtKayzen - if err := json.Unmarshal(bidderExt.Bidder, &kayzenExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &kayzenExt); err != nil { return nil, &errortypes.BadInput{ Message: "Error while unmarshaling bidder extension", } @@ -118,7 +119,7 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: "Bad Server Response", }} diff --git a/adapters/kayzen/kayzen_test.go b/adapters/kayzen/kayzen_test.go index a2cc98a7798..6b3776ddbae 100644 --- a/adapters/kayzen/kayzen_test.go +++ b/adapters/kayzen/kayzen_test.go @@ -3,9 +3,9 @@ package kayzen import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/kayzen/params_test.go b/adapters/kayzen/params_test.go index bd03e23df5b..647f77d1349 100644 --- a/adapters/kayzen/params_test.go +++ b/adapters/kayzen/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/kidoz/kidoz.go b/adapters/kidoz/kidoz.go index b0406b29e00..88628085ef2 100644 --- a/adapters/kidoz/kidoz.go +++ b/adapters/kidoz/kidoz.go @@ -7,10 +7,11 @@ import ( "strconv" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type KidozAdapter struct { @@ -56,7 +57,7 @@ func (a *KidozAdapter) MakeRequests(request *openrtb2.BidRequest, _ *adapters.Ex continue } var bidderExt adapters.ExtImpBidder - err := json.Unmarshal(impression.Ext, &bidderExt) + err := jsonutil.Unmarshal(impression.Ext, &bidderExt) if err != nil { errs = append(errs, err) continue @@ -66,7 +67,7 @@ func (a *KidozAdapter) MakeRequests(request *openrtb2.BidRequest, _ *adapters.Ex continue } var impressionExt openrtb_ext.ExtImpKidoz - err = json.Unmarshal(bidderExt.Bidder, &impressionExt) + err = jsonutil.Unmarshal(bidderExt.Bidder, &impressionExt) if err != nil { errs = append(errs, err) continue @@ -131,7 +132,7 @@ func (a *KidozAdapter) MakeBids(request *openrtb2.BidRequest, _ *adapters.Reques } var bidResponse openrtb2.BidResponse - err := json.Unmarshal(responseData.Body, &bidResponse) + err := jsonutil.Unmarshal(responseData.Body, &bidResponse) if err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: err.Error(), diff --git a/adapters/kidoz/kidoz_test.go b/adapters/kidoz/kidoz_test.go index 9a36764ee97..89235185592 100644 --- a/adapters/kidoz/kidoz_test.go +++ b/adapters/kidoz/kidoz_test.go @@ -6,10 +6,10 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) @@ -83,7 +83,7 @@ func TestMakeBids(t *testing.T) { resp, errs := bidder.MakeBids(request, requestData, responseData) // cant assert message its different on different versions of go assert.Equal(t, 1, len(errs)) - assert.Contains(t, errs[0].Error(), "JSON") + assert.Contains(t, errs[0].Error(), "expect { or n, but found") assert.Nil(t, resp) }) } diff --git a/adapters/kidoz/kidoztest/supplemental/bidder-marshal.json b/adapters/kidoz/kidoztest/supplemental/bidder-marshal.json index 8a8a5e76844..94d189db370 100644 --- a/adapters/kidoz/kidoztest/supplemental/bidder-marshal.json +++ b/adapters/kidoz/kidoztest/supplemental/bidder-marshal.json @@ -22,7 +22,7 @@ "expectedBidResponses": [], "expectedMakeRequestsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb_ext.ExtImpKidoz", + "value": "expect { or n, but found \"", "comparison": "literal" } ], diff --git a/adapters/kidoz/kidoztest/supplemental/ext-marshal.json b/adapters/kidoz/kidoztest/supplemental/ext-marshal.json index eaab459461a..4aefbdac2e8 100644 --- a/adapters/kidoz/kidoztest/supplemental/ext-marshal.json +++ b/adapters/kidoz/kidoztest/supplemental/ext-marshal.json @@ -20,7 +20,7 @@ "expectedBidResponses": [], "expectedMakeRequestsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type adapters.ExtImpBidder", + "value": "expect { or n, but found \"", "comparison": "literal" } ], diff --git a/adapters/kidoz/params_test.go b/adapters/kidoz/params_test.go index fad4e681288..1dfa3e8955d 100644 --- a/adapters/kidoz/params_test.go +++ b/adapters/kidoz/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/kiviads/kiviads.go b/adapters/kiviads/kiviads.go index a102234e860..ad5dcb58e2b 100644 --- a/adapters/kiviads/kiviads.go +++ b/adapters/kiviads/kiviads.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -44,10 +45,10 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E var bidderExt adapters.ExtImpBidder var kiviadsExt openrtb_ext.ImpExtKiviads - if err = json.Unmarshal(reqCopy.Imp[0].Ext, &bidderExt); err != nil { + if err = jsonutil.Unmarshal(reqCopy.Imp[0].Ext, &bidderExt); err != nil { return nil, []error{err} } - if err = json.Unmarshal(bidderExt.Bidder, &kiviadsExt); err != nil { + if err = jsonutil.Unmarshal(bidderExt.Bidder, &kiviadsExt); err != nil { return nil, []error{err} } @@ -111,7 +112,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } diff --git a/adapters/kiviads/kiviads_test.go b/adapters/kiviads/kiviads_test.go index a6725234e6a..dd83e0d1773 100644 --- a/adapters/kiviads/kiviads_test.go +++ b/adapters/kiviads/kiviads_test.go @@ -3,9 +3,9 @@ package kiviads import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/kiviads/kiviadstest/supplemental/bad_response.json b/adapters/kiviads/kiviadstest/supplemental/bad_response.json index d1dbf00134e..3f7eb4945a5 100644 --- a/adapters/kiviads/kiviadstest/supplemental/bad_response.json +++ b/adapters/kiviads/kiviadstest/supplemental/bad_response.json @@ -78,7 +78,7 @@ }], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/kiviads/params_test.go b/adapters/kiviads/params_test.go index 09ee3e24265..01927950061 100644 --- a/adapters/kiviads/params_test.go +++ b/adapters/kiviads/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/krushmedia/krushmedia.go b/adapters/krushmedia/krushmedia.go index aa87033052f..fd2a0adf8b1 100644 --- a/adapters/krushmedia/krushmedia.go +++ b/adapters/krushmedia/krushmedia.go @@ -8,11 +8,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type KrushmediaAdapter struct { @@ -110,13 +111,13 @@ func (a *KrushmediaAdapter) MakeRequests( func (a *KrushmediaAdapter) getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtKrushmedia, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: "Bidder extension not provided or can't be unmarshalled", } } var krushmediaExt openrtb_ext.ExtKrushmedia - if err := json.Unmarshal(bidderExt.Bidder, &krushmediaExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &krushmediaExt); err != nil { return nil, &errortypes.BadInput{ Message: "Error while unmarshaling bidder extension", } @@ -159,7 +160,7 @@ func (a *KrushmediaAdapter) MakeBids( responseBody := bidderRawResponse.Body var bidResp openrtb2.BidResponse - if err := json.Unmarshal(responseBody, &bidResp); err != nil { + if err := jsonutil.Unmarshal(responseBody, &bidResp); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: "Bad Server Response", }} diff --git a/adapters/krushmedia/krushmedia_test.go b/adapters/krushmedia/krushmedia_test.go index e7d71422dfe..26117ce103f 100644 --- a/adapters/krushmedia/krushmedia_test.go +++ b/adapters/krushmedia/krushmedia_test.go @@ -3,9 +3,9 @@ package krushmedia import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/krushmedia/params_test.go b/adapters/krushmedia/params_test.go index 4129fa1bd29..babf6b205df 100644 --- a/adapters/krushmedia/params_test.go +++ b/adapters/krushmedia/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/lemmadigital/lemmadigital.go b/adapters/lemmadigital/lemmadigital.go index 281cd2e1f0f..16d93d47be2 100644 --- a/adapters/lemmadigital/lemmadigital.go +++ b/adapters/lemmadigital/lemmadigital.go @@ -8,11 +8,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -38,14 +39,14 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte } var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(request.Imp[0].Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(request.Imp[0].Ext, &bidderExt); err != nil { return nil, []error{&errortypes.BadInput{ Message: fmt.Sprintf("Invalid imp.ext for impression index %d. Error Infomation: %s", 0, err.Error()), }} } var impExt openrtb_ext.ImpExtLemmaDigital - if err := json.Unmarshal(bidderExt.Bidder, &impExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &impExt); err != nil { return nil, []error{&errortypes.BadInput{ Message: fmt.Sprintf("Invalid imp.ext.bidder for impression index %d. Error Infomation: %s", 0, err.Error()), }} @@ -81,7 +82,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } diff --git a/adapters/lemmadigital/lemmadigital_test.go b/adapters/lemmadigital/lemmadigital_test.go index e0062c0b565..d3e770bb630 100644 --- a/adapters/lemmadigital/lemmadigital_test.go +++ b/adapters/lemmadigital/lemmadigital_test.go @@ -3,14 +3,14 @@ package lemmadigital import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { bidder, buildErr := Builder(openrtb_ext.BidderLemmadigital, config.Adapter{ - Endpoint: "https://sg.ads.lemmatechnologies.com/lemma/servad?pid={{.PublisherID}}&aid={{.AdUnit}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + Endpoint: "https://test.lemmaurl.com/lemma/servad?src=prebid&pid={{.PublisherID}}&aid={{.AdUnit}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) if buildErr != nil { t.Fatalf("Builder returned unexpected error %v", buildErr) diff --git a/adapters/lemmadigital/lemmadigitaltest/exemplary/banner.json b/adapters/lemmadigital/lemmadigitaltest/exemplary/banner.json index 69bdb266b96..3b4d3a0a1c3 100644 --- a/adapters/lemmadigital/lemmadigitaltest/exemplary/banner.json +++ b/adapters/lemmadigital/lemmadigitaltest/exemplary/banner.json @@ -32,7 +32,7 @@ "httpCalls": [{ "expectedRequest": { - "uri": "https://sg.ads.lemmatechnologies.com/lemma/servad?pid=1&aid=1", + "uri": "https://test.lemmaurl.com/lemma/servad?src=prebid&pid=1&aid=1", "body": { "id": "test-request-id", "imp": [{ diff --git a/adapters/lemmadigital/lemmadigitaltest/exemplary/multi-imp.json b/adapters/lemmadigital/lemmadigitaltest/exemplary/multi-imp.json index d71beda8d6d..1b29ab259f7 100644 --- a/adapters/lemmadigital/lemmadigitaltest/exemplary/multi-imp.json +++ b/adapters/lemmadigital/lemmadigitaltest/exemplary/multi-imp.json @@ -49,7 +49,7 @@ "httpCalls": [{ "expectedRequest": { - "uri": "https://sg.ads.lemmatechnologies.com/lemma/servad?pid=1&aid=1", + "uri": "https://test.lemmaurl.com/lemma/servad?src=prebid&pid=1&aid=1", "body": { "id": "test-request-id", "imp": [{ diff --git a/adapters/lemmadigital/lemmadigitaltest/exemplary/video.json b/adapters/lemmadigital/lemmadigitaltest/exemplary/video.json index b6d0e33e25b..af0e5561212 100644 --- a/adapters/lemmadigital/lemmadigitaltest/exemplary/video.json +++ b/adapters/lemmadigital/lemmadigitaltest/exemplary/video.json @@ -25,7 +25,7 @@ "httpCalls": [{ "expectedRequest": { - "uri": "https://sg.ads.lemmatechnologies.com/lemma/servad?pid=1&aid=1", + "uri": "https://test.lemmaurl.com/lemma/servad?src=prebid&pid=1&aid=1", "body": { "id": "test-request-id-video", "imp": [{ diff --git a/adapters/lemmadigital/lemmadigitaltest/supplemental/empty-seatbid-array.json b/adapters/lemmadigital/lemmadigitaltest/supplemental/empty-seatbid-array.json index e24c937fbd7..2e7ddc84f60 100644 --- a/adapters/lemmadigital/lemmadigitaltest/supplemental/empty-seatbid-array.json +++ b/adapters/lemmadigital/lemmadigitaltest/supplemental/empty-seatbid-array.json @@ -42,7 +42,7 @@ }, "httpCalls": [{ "expectedRequest": { - "uri": "https://sg.ads.lemmatechnologies.com/lemma/servad?pid=1&aid=1", + "uri": "https://test.lemmaurl.com/lemma/servad?src=prebid&pid=1&aid=1", "body": { "app": { "bundle": "com.ld.test", diff --git a/adapters/lemmadigital/lemmadigitaltest/supplemental/invalid-ld-ext-bidder-object.json b/adapters/lemmadigital/lemmadigitaltest/supplemental/invalid-ld-ext-bidder-object.json index ba46d76b598..8b078eddd6e 100644 --- a/adapters/lemmadigital/lemmadigitaltest/supplemental/invalid-ld-ext-bidder-object.json +++ b/adapters/lemmadigital/lemmadigitaltest/supplemental/invalid-ld-ext-bidder-object.json @@ -1,7 +1,7 @@ { "expectedMakeRequestsErrors": [{ - "value": "Invalid imp.ext.bidder for impression index 0. Error Infomation: json: cannot unmarshal string into Go struct field ImpExtLemmaDigital.pid of type int", - "comparison": "literal" + "value": "Invalid imp.ext.bidder for impression index 0. Error Infomation: cannot unmarshal openrtb_ext.ImpExtLemmaDigital.PublisherId: unexpected character", + "comparison": "startswith" }], "mockBidRequest": { "app": { diff --git a/adapters/lemmadigital/lemmadigitaltest/supplemental/invalid-ld-ext-object.json b/adapters/lemmadigital/lemmadigitaltest/supplemental/invalid-ld-ext-object.json index 4d3d795c185..690cf1e6b10 100644 --- a/adapters/lemmadigital/lemmadigitaltest/supplemental/invalid-ld-ext-object.json +++ b/adapters/lemmadigital/lemmadigitaltest/supplemental/invalid-ld-ext-object.json @@ -1,7 +1,7 @@ { "expectedMakeRequestsErrors": [{ - "value": "Invalid imp.ext for impression index 0. Error Infomation: unexpected end of JSON input", - "comparison": "literal" + "value": "Invalid imp.ext for impression index 0. Error Infomation: expect { or n, but found", + "comparison": "startswith" }], "mockBidRequest": { "app": { diff --git a/adapters/lemmadigital/lemmadigitaltest/supplemental/invalid-response.json b/adapters/lemmadigital/lemmadigitaltest/supplemental/invalid-response.json index dcf23479bbf..74e418c92c3 100644 --- a/adapters/lemmadigital/lemmadigitaltest/supplemental/invalid-response.json +++ b/adapters/lemmadigital/lemmadigitaltest/supplemental/invalid-response.json @@ -25,7 +25,7 @@ "httpCalls": [{ "expectedRequest": { - "uri": "https://sg.ads.lemmatechnologies.com/lemma/servad?pid=1&aid=1", + "uri": "https://test.lemmaurl.com/lemma/servad?src=prebid&pid=1&aid=1", "body": { "id": "test-request-id-video", "imp": [{ @@ -57,7 +57,7 @@ } }], "expectedMakeBidsErrors": [{ - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" }] } \ No newline at end of file diff --git a/adapters/lemmadigital/lemmadigitaltest/supplemental/status-code-bad-request.json b/adapters/lemmadigital/lemmadigitaltest/supplemental/status-code-bad-request.json index bee034cebfa..3243a12ce38 100644 --- a/adapters/lemmadigital/lemmadigitaltest/supplemental/status-code-bad-request.json +++ b/adapters/lemmadigital/lemmadigitaltest/supplemental/status-code-bad-request.json @@ -25,7 +25,7 @@ "httpCalls": [{ "expectedRequest": { - "uri": "https://sg.ads.lemmatechnologies.com/lemma/servad?pid=1&aid=1", + "uri": "https://test.lemmaurl.com/lemma/servad?src=prebid&pid=1&aid=1", "body": { "id": "test-request-id-video", "imp": [{ diff --git a/adapters/lemmadigital/lemmadigitaltest/supplemental/status-code-no-content.json b/adapters/lemmadigital/lemmadigitaltest/supplemental/status-code-no-content.json index d7d62c091fa..2c70967922d 100644 --- a/adapters/lemmadigital/lemmadigitaltest/supplemental/status-code-no-content.json +++ b/adapters/lemmadigital/lemmadigitaltest/supplemental/status-code-no-content.json @@ -25,7 +25,7 @@ "httpCalls": [{ "expectedRequest": { - "uri": "https://sg.ads.lemmatechnologies.com/lemma/servad?pid=1&aid=1", + "uri": "https://test.lemmaurl.com/lemma/servad?src=prebid&pid=1&aid=1", "body": { "id": "test-request-id-video", "imp": [{ diff --git a/adapters/lemmadigital/lemmadigitaltest/supplemental/status-code-other-error.json b/adapters/lemmadigital/lemmadigitaltest/supplemental/status-code-other-error.json index 65dea99a36c..4213da80a23 100644 --- a/adapters/lemmadigital/lemmadigitaltest/supplemental/status-code-other-error.json +++ b/adapters/lemmadigital/lemmadigitaltest/supplemental/status-code-other-error.json @@ -25,7 +25,7 @@ "httpCalls": [{ "expectedRequest": { - "uri": "https://sg.ads.lemmatechnologies.com/lemma/servad?pid=1&aid=1", + "uri": "https://test.lemmaurl.com/lemma/servad?src=prebid&pid=1&aid=1", "body": { "id": "test-request-id-video", "imp": [{ diff --git a/adapters/lemmadigital/params_test.go b/adapters/lemmadigital/params_test.go index 4ba61319b33..c8c739ff596 100644 --- a/adapters/lemmadigital/params_test.go +++ b/adapters/lemmadigital/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // Tests for static/bidder-params/lemmadigital.json diff --git a/adapters/limelightDigital/limelightDigital.go b/adapters/limelightDigital/limelightDigital.go index b4c327e8475..18ba5dd6f74 100644 --- a/adapters/limelightDigital/limelightDigital.go +++ b/adapters/limelightDigital/limelightDigital.go @@ -10,11 +10,12 @@ import ( "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -115,7 +116,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } @@ -141,13 +142,13 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R func getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ImpExtLimelightDigital, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: "ext.bidder is not provided", } } var limelightDigitalExt openrtb_ext.ImpExtLimelightDigital - if err := json.Unmarshal(bidderExt.Bidder, &limelightDigitalExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &limelightDigitalExt); err != nil { return nil, &errortypes.BadInput{ Message: "ext.bidder is not provided", } diff --git a/adapters/limelightDigital/limelightDigital_test.go b/adapters/limelightDigital/limelightDigital_test.go index beb4222f5c8..2b36ee573de 100644 --- a/adapters/limelightDigital/limelightDigital_test.go +++ b/adapters/limelightDigital/limelightDigital_test.go @@ -5,9 +5,9 @@ import ( "github.com/stretchr/testify/assert" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/limelightDigital/params_test.go b/adapters/limelightDigital/params_test.go index 9a61e9ba7c9..04c49d8373c 100644 --- a/adapters/limelightDigital/params_test.go +++ b/adapters/limelightDigital/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/lm_kiviads/lmkiviads.go b/adapters/lm_kiviads/lmkiviads.go index e5f9723c34d..bc4e48b1d7a 100644 --- a/adapters/lm_kiviads/lmkiviads.go +++ b/adapters/lm_kiviads/lmkiviads.go @@ -7,11 +7,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type bidType struct { @@ -41,14 +42,14 @@ func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server co func (a *adapter) buildEndpointFromRequest(imp *openrtb2.Imp) (string, error) { var impExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &impExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &impExt); err != nil { return "", &errortypes.BadInput{ Message: fmt.Sprintf("Failed to deserialize bidder impression extension: %v", err), } } var kiviExt openrtb_ext.ExtLmKiviads - if err := json.Unmarshal(impExt.Bidder, &kiviExt); err != nil { + if err := jsonutil.Unmarshal(impExt.Bidder, &kiviExt); err != nil { return "", &errortypes.BadInput{ Message: fmt.Sprintf("Failed to deserialize LmKiviads extension: %v", err), } @@ -116,7 +117,7 @@ func (a *adapter) MakeBids(openRTBRequest *openrtb2.BidRequest, requestToBidder } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(bidderRawResponse.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(bidderRawResponse.Body, &bidResp); err != nil { return nil, []error{err} } @@ -136,7 +137,7 @@ func prepareBidResponse(seats []openrtb2.SeatBid) (*adapters.BidderResponse, []e for _, seatBid := range seats { for bidId, bid := range seatBid.Bid { var bidExt bidExt - if err := json.Unmarshal(bid.Ext, &bidExt); err != nil { + if err := jsonutil.Unmarshal(bid.Ext, &bidExt); err != nil { errs = append(errs, &errortypes.BadServerResponse{ Message: fmt.Sprintf("Failed to parse Bid[%d].Ext: %s", bidId, err.Error()), }) diff --git a/adapters/lm_kiviads/lmkiviads_test.go b/adapters/lm_kiviads/lmkiviads_test.go index 01bf47ef8a7..34ea2bf467f 100644 --- a/adapters/lm_kiviads/lmkiviads_test.go +++ b/adapters/lm_kiviads/lmkiviads_test.go @@ -3,9 +3,9 @@ package lmkiviads import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/lm_kiviads/lmkiviadstest/supplemental/bad-response.json b/adapters/lm_kiviads/lmkiviadstest/supplemental/bad-response.json index 87f917e58ab..b913e93293a 100644 --- a/adapters/lm_kiviads/lmkiviadstest/supplemental/bad-response.json +++ b/adapters/lm_kiviads/lmkiviadstest/supplemental/bad-response.json @@ -99,7 +99,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ], diff --git a/adapters/lm_kiviads/lmkiviadstest/supplemental/invalid-ext-bidder-object.json b/adapters/lm_kiviads/lmkiviadstest/supplemental/invalid-ext-bidder-object.json index 87ade656d2d..ec20948c77c 100644 --- a/adapters/lm_kiviads/lmkiviadstest/supplemental/invalid-ext-bidder-object.json +++ b/adapters/lm_kiviads/lmkiviadstest/supplemental/invalid-ext-bidder-object.json @@ -42,7 +42,7 @@ "httpCalls": [], "expectedMakeRequestsErrors": [ { - "value": "Failed to deserialize LmKiviads extension: json: cannot unmarshal array into Go value of type openrtb_ext.ExtLmKiviads", + "value": "Failed to deserialize LmKiviads extension: expect { or n, but found [", "comparison": "literal" } ] diff --git a/adapters/lm_kiviads/lmkiviadstest/supplemental/invalid-ext-object.json b/adapters/lm_kiviads/lmkiviadstest/supplemental/invalid-ext-object.json index aa215eb3e34..16cf58bbe54 100644 --- a/adapters/lm_kiviads/lmkiviadstest/supplemental/invalid-ext-object.json +++ b/adapters/lm_kiviads/lmkiviadstest/supplemental/invalid-ext-object.json @@ -40,7 +40,7 @@ "httpCalls": [], "expectedMakeRequestsErrors": [ { - "value": "Failed to deserialize bidder impression extension: json: cannot unmarshal string into Go value of type adapters.ExtImpBidder", + "value": "Failed to deserialize bidder impression extension: expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/lm_kiviads/params_test.go b/adapters/lm_kiviads/params_test.go index 1f3361b2581..00f76bca95d 100644 --- a/adapters/lm_kiviads/params_test.go +++ b/adapters/lm_kiviads/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/lockerdome/lockerdome.go b/adapters/lockerdome/lockerdome.go index 3e483fad646..2206b82015c 100644 --- a/adapters/lockerdome/lockerdome.go +++ b/adapters/lockerdome/lockerdome.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) const unexpectedStatusCodeMessage = "Unexpected status code: %d. Run with request.debug = 1 for more info" @@ -43,7 +44,7 @@ func (adapter *LockerDomeAdapter) MakeRequests(openRTBRequest *openrtb2.BidReque continue } var bidderExt adapters.ExtImpBidder - err := json.Unmarshal(openRTBRequest.Imp[i].Ext, &bidderExt) + err := jsonutil.Unmarshal(openRTBRequest.Imp[i].Ext, &bidderExt) if err != nil { // lockerdometest/supplemental/no_ext.json err = &errortypes.BadInput{ Message: "ext was not provided.", @@ -52,7 +53,7 @@ func (adapter *LockerDomeAdapter) MakeRequests(openRTBRequest *openrtb2.BidReque continue } var lockerdomeExt openrtb_ext.ExtImpLockerDome - err = json.Unmarshal(bidderExt.Bidder, &lockerdomeExt) + err = jsonutil.Unmarshal(bidderExt.Bidder, &lockerdomeExt) if err != nil { // lockerdometest/supplemental/no_adUnitId_param.json err = &errortypes.BadInput{ Message: "ext.bidder.adUnitId was not provided.", @@ -129,7 +130,7 @@ func (adapter *LockerDomeAdapter) MakeBids(openRTBRequest *openrtb2.BidRequest, } var openRTBBidderResponse openrtb2.BidResponse - if err := json.Unmarshal(bidderRawResponse.Body, &openRTBBidderResponse); err != nil { + if err := jsonutil.Unmarshal(bidderRawResponse.Body, &openRTBBidderResponse); err != nil { return nil, []error{ fmt.Errorf("Error unmarshaling LockerDome bid response - %s", err.Error()), } diff --git a/adapters/lockerdome/lockerdome_test.go b/adapters/lockerdome/lockerdome_test.go index 892fce2183a..b0c12083e46 100644 --- a/adapters/lockerdome/lockerdome_test.go +++ b/adapters/lockerdome/lockerdome_test.go @@ -3,9 +3,9 @@ package lockerdome import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/lockerdome/lockerdometest/supplemental/bad_response.json b/adapters/lockerdome/lockerdometest/supplemental/bad_response.json index c3b0045e275..b90eb3f1e0e 100644 --- a/adapters/lockerdome/lockerdometest/supplemental/bad_response.json +++ b/adapters/lockerdome/lockerdometest/supplemental/bad_response.json @@ -57,7 +57,7 @@ "expectedMakeBidsErrors": [ { - "value": "Error unmarshaling LockerDome bid response - json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "Error unmarshaling LockerDome bid response - expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/lockerdome/params_test.go b/adapters/lockerdome/params_test.go index 9b90ec0b888..50504b68d28 100644 --- a/adapters/lockerdome/params_test.go +++ b/adapters/lockerdome/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file tests static/bidder-params/lockerdome.json diff --git a/adapters/logan/logan.go b/adapters/logan/logan.go index 73e602f5632..a5f995108f4 100644 --- a/adapters/logan/logan.go +++ b/adapters/logan/logan.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -43,7 +44,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E request.Imp = []openrtb2.Imp{currImp} var bidderExt reqBodyExt - if err := json.Unmarshal(currImp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(currImp.Ext, &bidderExt); err != nil { errors = append(errors, &errortypes.BadInput{ Message: err.Error(), }) @@ -103,7 +104,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } diff --git a/adapters/logan/logan_test.go b/adapters/logan/logan_test.go index 219fbb50fe0..8e677c5585e 100644 --- a/adapters/logan/logan_test.go +++ b/adapters/logan/logan_test.go @@ -3,9 +3,9 @@ package logan import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/logan/logantest/supplemental/bad_response.json b/adapters/logan/logantest/supplemental/bad_response.json index d71deaddfb8..1653abee0a8 100644 --- a/adapters/logan/logantest/supplemental/bad_response.json +++ b/adapters/logan/logantest/supplemental/bad_response.json @@ -78,7 +78,7 @@ }], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/logan/params_test.go b/adapters/logan/params_test.go index 55633b47c36..76c8cb3dd84 100644 --- a/adapters/logan/params_test.go +++ b/adapters/logan/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/logicad/logicad.go b/adapters/logicad/logicad.go index 5ce3d0ac7e1..a1dc40fdcf5 100644 --- a/adapters/logicad/logicad.go +++ b/adapters/logicad/logicad.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type LogicadAdapter struct { @@ -74,12 +75,12 @@ func getImpressionExt(imp *openrtb2.Imp) (openrtb_ext.ExtImpLogicad, error) { var bidderExt adapters.ExtImpBidder var logicadExt openrtb_ext.ExtImpLogicad - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return logicadExt, &errortypes.BadInput{ Message: err.Error(), } } - if err := json.Unmarshal(bidderExt.Bidder, &logicadExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &logicadExt); err != nil { return logicadExt, &errortypes.BadInput{ Message: err.Error(), } @@ -128,7 +129,7 @@ func (adapter *LogicadAdapter) MakeBids(internalRequest *openrtb2.BidRequest, ex } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { msg := fmt.Sprintf("Bad server response: %d", err) return nil, []error{&errortypes.BadServerResponse{Message: msg}} } diff --git a/adapters/logicad/logicad_test.go b/adapters/logicad/logicad_test.go index 551bd133a9c..a15d381cbb5 100644 --- a/adapters/logicad/logicad_test.go +++ b/adapters/logicad/logicad_test.go @@ -3,9 +3,9 @@ package logicad import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/logicad/logicadtest/supplemental/ext.json b/adapters/logicad/logicadtest/supplemental/ext.json index ad35892086b..97b5ff61cfa 100644 --- a/adapters/logicad/logicadtest/supplemental/ext.json +++ b/adapters/logicad/logicadtest/supplemental/ext.json @@ -24,8 +24,8 @@ }, "expectedMakeRequestsErrors": [ { - "value": "unexpected end of JSON input", - "comparison": "literal" + "value": "expect { or n, but found", + "comparison": "startswith" } ] } \ No newline at end of file diff --git a/adapters/logicad/params_test.go b/adapters/logicad/params_test.go index c45297d15c2..06f15d9d1ba 100644 --- a/adapters/logicad/params_test.go +++ b/adapters/logicad/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/loyal/loyal.go b/adapters/loyal/loyal.go index 4c1bf4dc59e..efe069c6380 100644 --- a/adapters/loyal/loyal.go +++ b/adapters/loyal/loyal.go @@ -7,9 +7,10 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -44,11 +45,11 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E var bidderExt adapters.ExtImpBidder var loyalExt openrtb_ext.ImpExtLoyal - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { errs = append(errs, err) continue } - if err := json.Unmarshal(bidderExt.Bidder, &loyalExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &loyalExt); err != nil { errs = append(errs, err) continue } @@ -118,7 +119,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } @@ -146,7 +147,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R func getBidMediaType(bid *openrtb2.Bid) (openrtb_ext.BidType, error) { var extBid openrtb_ext.ExtBid - err := json.Unmarshal(bid.Ext, &extBid) + err := jsonutil.Unmarshal(bid.Ext, &extBid) if err != nil { return "", fmt.Errorf("unable to deserialize imp %v bid.ext, error: %v", bid.ImpID, err) } diff --git a/adapters/loyal/loyal_test.go b/adapters/loyal/loyal_test.go index bac3e439162..1836b267beb 100644 --- a/adapters/loyal/loyal_test.go +++ b/adapters/loyal/loyal_test.go @@ -3,9 +3,9 @@ package loyal import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/loyal/loyaltest/supplemental/bad_response.json b/adapters/loyal/loyaltest/supplemental/bad_response.json index 58d5c71fa52..30fa65e95d9 100644 --- a/adapters/loyal/loyaltest/supplemental/bad_response.json +++ b/adapters/loyal/loyaltest/supplemental/bad_response.json @@ -78,7 +78,7 @@ }], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/loyal/params_test.go b/adapters/loyal/params_test.go index 1e9b6c650cd..e0c47d50300 100644 --- a/adapters/loyal/params_test.go +++ b/adapters/loyal/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/lunamedia/lunamedia.go b/adapters/lunamedia/lunamedia.go index bc663d31fdb..3db1b12ad4f 100644 --- a/adapters/lunamedia/lunamedia.go +++ b/adapters/lunamedia/lunamedia.go @@ -7,11 +7,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type LunaMediaAdapter struct { @@ -116,13 +117,13 @@ func compatBannerImpression(imp *openrtb2.Imp) error { func getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpLunaMedia, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: err.Error(), } } var LunaMediaExt openrtb_ext.ExtImpLunaMedia - if err := json.Unmarshal(bidderExt.Bidder, &LunaMediaExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &LunaMediaExt); err != nil { return nil, &errortypes.BadInput{ Message: err.Error(), } @@ -196,7 +197,7 @@ func (adapter *LunaMediaAdapter) MakeBids(internalRequest *openrtb2.BidRequest, } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { msg = fmt.Sprintf("Bad server response: %d", err) return nil, []error{&errortypes.BadServerResponse{Message: msg}} } diff --git a/adapters/lunamedia/lunamedia_test.go b/adapters/lunamedia/lunamedia_test.go index c950ce4d25f..8677fbb2979 100644 --- a/adapters/lunamedia/lunamedia_test.go +++ b/adapters/lunamedia/lunamedia_test.go @@ -3,9 +3,9 @@ package lunamedia import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/lunamedia/lunamediatest/supplemental/ext.json b/adapters/lunamedia/lunamediatest/supplemental/ext.json index 3cfb878bd47..285c8b11ed2 100644 --- a/adapters/lunamedia/lunamediatest/supplemental/ext.json +++ b/adapters/lunamedia/lunamediatest/supplemental/ext.json @@ -27,7 +27,7 @@ }, "expectedMakeRequestsErrors": [ { - "value": "unexpected end of JSON input", - "comparison": "literal" + "value": "expect { or n, but found", + "comparison": "startswith" }] } \ No newline at end of file diff --git a/adapters/lunamedia/params_test.go b/adapters/lunamedia/params_test.go index 12ecc65f420..b78b94934d1 100644 --- a/adapters/lunamedia/params_test.go +++ b/adapters/lunamedia/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/mabidder/mabidder.go b/adapters/mabidder/mabidder.go index 8e636e2281c..25d2830ef93 100644 --- a/adapters/mabidder/mabidder.go +++ b/adapters/mabidder/mabidder.go @@ -4,9 +4,10 @@ import ( "encoding/json" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type serverResponse struct { @@ -71,7 +72,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response serverResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } diff --git a/adapters/mabidder/mabidder_test.go b/adapters/mabidder/mabidder_test.go index 31c28788ad2..f821752e9b6 100644 --- a/adapters/mabidder/mabidder_test.go +++ b/adapters/mabidder/mabidder_test.go @@ -3,9 +3,9 @@ package mabidder import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/mabidder/mabiddertest/supplemental/bad-response-malformed.json b/adapters/mabidder/mabiddertest/supplemental/bad-response-malformed.json index fb59513192d..2638f5415f7 100644 --- a/adapters/mabidder/mabiddertest/supplemental/bad-response-malformed.json +++ b/adapters/mabidder/mabiddertest/supplemental/bad-response-malformed.json @@ -66,8 +66,8 @@ ], "expectedMakeBidsErrors": [ { - "value": "unexpected end of JSON input", - "comparison": "literal" + "value": "expect { or n, but found", + "comparison": "startswith" } ] } diff --git a/adapters/mabidder/params_test.go b/adapters/mabidder/params_test.go index 878e278438d..bd4162448f8 100644 --- a/adapters/mabidder/params_test.go +++ b/adapters/mabidder/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/madvertise/madvertise.go b/adapters/madvertise/madvertise.go index 3c1ffa4ae55..d8c6fc3953c 100644 --- a/adapters/madvertise/madvertise.go +++ b/adapters/madvertise/madvertise.go @@ -8,11 +8,12 @@ import ( "github.com/prebid/openrtb/v20/adcom1" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -93,13 +94,13 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte func getImpressionExt(imp openrtb2.Imp) (*openrtb_ext.ExtImpMadvertise, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: fmt.Sprintf("%s; ImpID=%s", err.Error(), imp.ID), } } var madvertiseExt openrtb_ext.ExtImpMadvertise - if err := json.Unmarshal(bidderExt.Bidder, &madvertiseExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &madvertiseExt); err != nil { return nil, &errortypes.BadInput{ Message: fmt.Sprintf("%s; ImpID=%s", err.Error(), imp.ID), } @@ -131,7 +132,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } diff --git a/adapters/madvertise/madvertise_test.go b/adapters/madvertise/madvertise_test.go index 3d412b1e154..e402ae4dc7f 100644 --- a/adapters/madvertise/madvertise_test.go +++ b/adapters/madvertise/madvertise_test.go @@ -3,9 +3,9 @@ package madvertise import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/madvertise/madvertisetest/supplemental/required-ext.json b/adapters/madvertise/madvertisetest/supplemental/required-ext.json index 8989a8dc4e1..6d953811244 100644 --- a/adapters/madvertise/madvertisetest/supplemental/required-ext.json +++ b/adapters/madvertise/madvertisetest/supplemental/required-ext.json @@ -12,8 +12,8 @@ }, "expectedMakeRequestsErrors": [ { - "value": "unexpected end of JSON input; ImpID=test-imp-id-1", - "comparison": "literal" + "value": "expect { or n, but found", + "comparison": "startswith" } ] } diff --git a/adapters/madvertise/params_test.go b/adapters/madvertise/params_test.go index 55454399155..c155d5beda1 100644 --- a/adapters/madvertise/params_test.go +++ b/adapters/madvertise/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/Madvertise.json diff --git a/adapters/marsmedia/marsmedia.go b/adapters/marsmedia/marsmedia.go index f47ba557d88..92bfa0dc9f7 100644 --- a/adapters/marsmedia/marsmedia.go +++ b/adapters/marsmedia/marsmedia.go @@ -7,10 +7,11 @@ import ( "strconv" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type MarsmediaAdapter struct { @@ -28,14 +29,14 @@ func (a *MarsmediaAdapter) MakeRequests(requestIn *openrtb2.BidRequest, reqInfo } var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(request.Imp[0].Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(request.Imp[0].Ext, &bidderExt); err != nil { return nil, []error{&errortypes.BadInput{ Message: "ext.bidder not provided", }} } var marsmediaExt openrtb_ext.ExtImpMarsmedia - if err := json.Unmarshal(bidderExt.Bidder, &marsmediaExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &marsmediaExt); err != nil { return nil, []error{&errortypes.BadInput{ Message: "ext.bidder.zoneId not provided", }} @@ -126,7 +127,7 @@ func (a *MarsmediaAdapter) MakeBids(internalRequest *openrtb2.BidRequest, extern } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: fmt.Sprintf("Bad server response: %d. ", err), }} diff --git a/adapters/marsmedia/marsmedia_test.go b/adapters/marsmedia/marsmedia_test.go index 6c75ef76c37..4164d433fd3 100644 --- a/adapters/marsmedia/marsmedia_test.go +++ b/adapters/marsmedia/marsmedia_test.go @@ -3,9 +3,9 @@ package marsmedia import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/marsmedia/marsmediatest/supplemental/missing-param.json b/adapters/marsmedia/marsmediatest/supplemental/missing-param.json index e68b3f529e0..b88fba5a8a1 100644 --- a/adapters/marsmedia/marsmediatest/supplemental/missing-param.json +++ b/adapters/marsmedia/marsmediatest/supplemental/missing-param.json @@ -27,7 +27,7 @@ }, "expectedMakeRequestsErrors": [ { - "value": "ext.bidder.zoneId not provided", + "value": "zoneId is empty", "comparison": "literal" } ] diff --git a/adapters/marsmedia/params_test.go b/adapters/marsmedia/params_test.go index ee79015b05c..7961d21455f 100644 --- a/adapters/marsmedia/params_test.go +++ b/adapters/marsmedia/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/marsmedia.json diff --git a/adapters/mediago/mediago.go b/adapters/mediago/mediago.go new file mode 100644 index 00000000000..dc7ee01b9f3 --- /dev/null +++ b/adapters/mediago/mediago.go @@ -0,0 +1,211 @@ +package mediago + +import ( + "encoding/json" + "errors" + "fmt" + "net/http" + "net/url" + "text/template" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" +) + +type adapter struct { + EndpointTemplate *template.Template +} + +type mediagoResponseBidExt struct { + MediaType string `json:"mediaType"` +} + +// Builder builds a new instance of the MediaGo adapter for the given bidder with the given config. +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + endpoint, err := template.New("endpointTemplate").Parse(config.Endpoint) + if err != nil { + return nil, fmt.Errorf("unable to parse endpoint url template: %v", err) + } + bidder := &adapter{ + EndpointTemplate: endpoint, + } + return bidder, nil +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + var adapterRequests []*adapters.RequestData + var errs []error + + adapterRequest, err := a.makeRequest(request) + if err == nil { + adapterRequests = append(adapterRequests, adapterRequest) + } else { + errs = append(errs, err) + } + return adapterRequests, errs +} + +func (a *adapter) makeRequest(request *openrtb2.BidRequest) (*adapters.RequestData, error) { + + mediagoExt, err := getMediaGoExt(request) + if err != nil { + return nil, err + } + endPoint, err := a.getEndPoint(mediagoExt) + if err != nil { + return nil, err + } + + preProcess(request) + reqBody, err := json.Marshal(request) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + headers.Add("Accept", "application/json") + headers.Add("x-openrtb-version", "2.5") + + return &adapters.RequestData{ + Method: "POST", + Uri: endPoint, + Body: reqBody, + Headers: headers, + ImpIDs: openrtb_ext.GetImpIDs(request.Imp), + }, nil +} + +// getMediaGoExt get MediaGoExt From ext.bidderparams or ext of First Imp. Only check and get first Imp.Ext.Bidder to ExtImpMediago +func getMediaGoExt(request *openrtb2.BidRequest) (*openrtb_ext.ExtMediaGo, error) { + var extMediaGo openrtb_ext.ExtMediaGo + var extBidder adapters.ExtImpBidder + + // first get the mediago ext from ext.bidderparams + reqExt := &openrtb_ext.ExtRequest{} + err := jsonutil.Unmarshal(request.Ext, &reqExt) + if err != nil { + err = jsonutil.Unmarshal(reqExt.Prebid.BidderParams, &extMediaGo) + if err != nil && extMediaGo.Token != "" { + return &extMediaGo, nil + } + } + + // fallback to get token and region from first imp + imp := request.Imp[0] + err = jsonutil.Unmarshal(imp.Ext, &extBidder) + if err != nil { + return nil, err + } + + var extImpMediaGo openrtb_ext.ExtImpMediaGo + err = jsonutil.Unmarshal(extBidder.Bidder, &extImpMediaGo) + if err != nil { + return nil, err + } + if extImpMediaGo.Token != "" { + extMediaGo.Token = extImpMediaGo.Token + extMediaGo.Region = extImpMediaGo.Region + + return &extMediaGo, nil + } + return nil, errors.New("mediago token not found") + +} + +func getRegionInfo(region string) string { + switch region { + case "APAC": + return "jp" + case "EU": + return "eu" + case "US": + return "us" + default: + return "us" + } +} + +func (a *adapter) getEndPoint(ext *openrtb_ext.ExtMediaGo) (string, error) { + endPointParams := macros.EndpointTemplateParams{ + AccountID: url.PathEscape(ext.Token), + Host: url.PathEscape(getRegionInfo(ext.Region)), + } + return macros.ResolveMacros(a.EndpointTemplate, endPointParams) +} + +func preProcess(request *openrtb2.BidRequest) { + for i := range request.Imp { + if request.Imp[i].Banner != nil { + banner := *request.Imp[i].Banner + if (banner.W == nil || banner.H == nil || *banner.W == 0 || *banner.H == 0) && len(banner.Format) > 0 { + firstFormat := banner.Format[0] + banner.W = &firstFormat.W + banner.H = &firstFormat.H + request.Imp[i].Banner = &banner + } + } + } +} + +func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if adapters.IsResponseStatusCodeNoContent(response) { + return nil, nil + } + if err := adapters.CheckResponseStatusCodeForErrors(response); err != nil { + return nil, []error{err} + } + + var bidResp openrtb2.BidResponse + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { + return nil, []error{err} + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(1) + var errs []error + + for _, seatBid := range bidResp.SeatBid { + for idx := range seatBid.Bid { + mediaType, err := getBidType(seatBid.Bid[idx], internalRequest.Imp) + if err != nil { + errs = append(errs, err) + } else { + bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ + Bid: &seatBid.Bid[idx], + BidType: mediaType, + }) + } + } + } + + return bidResponse, errs +} + +func getBidType(bid openrtb2.Bid, imps []openrtb2.Imp) (openrtb_ext.BidType, error) { + switch bid.MType { + case openrtb2.MarkupBanner: + return openrtb_ext.BidTypeBanner, nil + case openrtb2.MarkupNative: + return openrtb_ext.BidTypeNative, nil + default: + for _, imp := range imps { + if imp.ID == bid.ImpID { + if imp.Banner != nil { + return openrtb_ext.BidTypeBanner, nil + } + if imp.Native != nil { + return openrtb_ext.BidTypeNative, nil + } + } + } + return "", &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Unsupported MType %d", bid.MType), + } + } + +} diff --git a/adapters/mediago/mediago_test.go b/adapters/mediago/mediago_test.go new file mode 100644 index 00000000000..d6a480c8288 --- /dev/null +++ b/adapters/mediago/mediago_test.go @@ -0,0 +1,28 @@ +package mediago + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderMediaGo, config.Adapter{ + Endpoint: "https://REGION.mediago.io/api/bid?tn={{.AccountID}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "mediagotest", bidder) +} + +func TestEndpointTemplateMalformed(t *testing.T) { + _, buildErr := Builder(openrtb_ext.BidderMediaGo, config.Adapter{Endpoint: "{{Malformed}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + assert.Error(t, buildErr) +} diff --git a/adapters/mediago/mediagotest/exemplary/sample-banner-apac.json b/adapters/mediago/mediagotest/exemplary/sample-banner-apac.json new file mode 100644 index 00000000000..79105827da3 --- /dev/null +++ b/adapters/mediago/mediagotest/exemplary/sample-banner-apac.json @@ -0,0 +1,114 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 320, "h": 50}] + }, + "ext": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b", + "placementId": "testPlacementId", + "region": "APAC" + } + } + } + ], + "site": { + "id": "test-site-id", + "page": "https://www.example.com/" + }, + "ext": { + "prebid": { + "bidderparams": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b", + "region": "APAC" + } + } + } + } + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://REGION.mediago.io/api/bid?tn=f9f2b1ef23fe2759c2cad0953029a94b", + "body": { + "id": "test-request-id", + "imp": [ + { + "id":"test-imp-id", + "banner": { + "format": [{"w": 320, "h": 50}], + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b", + "region": "APAC", + "placementId": "testPlacementId" + } + } + } + ], + "site": { + "id": "test-site-id", + "page": "https://www.example.com/" + }, + "ext": { + "prebid": { + "bidderparams": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b", + "region": "APAC" + } + } + } + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "mediago", + "bid": [{ + "id": "test-imp-id", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-ads", + "crid": "crid_testid" + }] + } + ], + "cur": "USD" + } + } + } + ], + + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-imp-id", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-ads", + "crid": "crid_testid" + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/mediago/mediagotest/exemplary/sample-banner-euc.json b/adapters/mediago/mediagotest/exemplary/sample-banner-euc.json new file mode 100644 index 00000000000..98e37ab9912 --- /dev/null +++ b/adapters/mediago/mediagotest/exemplary/sample-banner-euc.json @@ -0,0 +1,114 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 320, "h": 50}] + }, + "ext": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b", + "placementId": "testPlacementId", + "region": "EU" + } + } + } + ], + "site": { + "id": "test-site-id", + "page": "https://www.example.com/" + }, + "ext": { + "prebid": { + "bidderparams": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b", + "region": "EU" + } + } + } + } + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://REGION.mediago.io/api/bid?tn=f9f2b1ef23fe2759c2cad0953029a94b", + "body": { + "id": "test-request-id", + "imp": [ + { + "id":"test-imp-id", + "banner": { + "format": [{"w": 320, "h": 50}], + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b", + "region": "EU", + "placementId": "testPlacementId" + } + } + } + ], + "site": { + "id": "test-site-id", + "page": "https://www.example.com/" + }, + "ext": { + "prebid": { + "bidderparams": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b", + "region": "EU" + } + } + } + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "mediago", + "bid": [{ + "id": "test-imp-id", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-ads", + "crid": "crid_testid" + }] + } + ], + "cur": "USD" + } + } + } + ], + + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-imp-id", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-ads", + "crid": "crid_testid" + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/mediago/mediagotest/exemplary/sample-banner-fallback-to-first-imp-to-get-ep.json b/adapters/mediago/mediagotest/exemplary/sample-banner-fallback-to-first-imp-to-get-ep.json new file mode 100644 index 00000000000..b396be54bf6 --- /dev/null +++ b/adapters/mediago/mediagotest/exemplary/sample-banner-fallback-to-first-imp-to-get-ep.json @@ -0,0 +1,94 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 320, "h": 50}] + }, + "ext": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b", + "placementId": "testPlacementId", + "region": "US" + } + } + } + ], + "site": { + "id": "test-site-id", + "page": "https://www.example.com/" + } + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://REGION.mediago.io/api/bid?tn=f9f2b1ef23fe2759c2cad0953029a94b", + "body": { + "id": "test-request-id", + "imp": [ + { + "id":"test-imp-id", + "banner": { + "format": [{"w": 320, "h": 50}], + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b", + "region": "US", + "placementId": "testPlacementId" + } + } + } + ], + "site": { + "id": "test-site-id", + "page": "https://www.example.com/" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "mediago", + "bid": [{ + "id": "test-imp-id", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-ads", + "crid": "crid_testid" + }] + } + ], + "cur": "USD" + } + } + } + ], + + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-imp-id", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-ads", + "crid": "crid_testid" + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/mediago/mediagotest/exemplary/sample-banner-use.json b/adapters/mediago/mediagotest/exemplary/sample-banner-use.json new file mode 100644 index 00000000000..b157b5a6a57 --- /dev/null +++ b/adapters/mediago/mediagotest/exemplary/sample-banner-use.json @@ -0,0 +1,114 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 320, "h": 50}] + }, + "ext": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b", + "placementId": "testPlacementId", + "region": "US" + } + } + } + ], + "site": { + "id": "test-site-id", + "page": "https://www.example.com/" + }, + "ext": { + "prebid": { + "bidderparams": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b", + "region": "US" + } + } + } + } + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://REGION.mediago.io/api/bid?tn=f9f2b1ef23fe2759c2cad0953029a94b", + "body": { + "id": "test-request-id", + "imp": [ + { + "id":"test-imp-id", + "banner": { + "format": [{"w": 320, "h": 50}], + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b", + "region": "US", + "placementId": "testPlacementId" + } + } + } + ], + "site": { + "id": "test-site-id", + "page": "https://www.example.com/" + }, + "ext": { + "prebid": { + "bidderparams": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b", + "region": "US" + } + } + } + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "mediago", + "bid": [{ + "id": "test-imp-id", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-ads", + "crid": "crid_testid" + }] + } + ], + "cur": "USD" + } + } + } + ], + + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-imp-id", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-ads", + "crid": "crid_testid" + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/mediago/mediagotest/exemplary/sample-banner.json b/adapters/mediago/mediagotest/exemplary/sample-banner.json new file mode 100644 index 00000000000..41effb8509b --- /dev/null +++ b/adapters/mediago/mediagotest/exemplary/sample-banner.json @@ -0,0 +1,112 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 320, "h": 50}] + }, + "ext": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b", + "placementId": "testPlacementId" + } + } + } + ], + "site": { + "id": "test-site-id", + "page": "https://www.example.com/" + }, + "ext": { + "prebid": { + "bidderparams": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b", + "region": "US" + } + } + } + } + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://REGION.mediago.io/api/bid?tn=f9f2b1ef23fe2759c2cad0953029a94b", + "body": { + "id": "test-request-id", + "imp": [ + { + "id":"test-imp-id", + "banner": { + "format": [{"w": 320, "h": 50}], + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b", + "placementId": "testPlacementId" + } + } + } + ], + "site": { + "id": "test-site-id", + "page": "https://www.example.com/" + }, + "ext": { + "prebid": { + "bidderparams": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b", + "region": "US" + } + } + } + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "mediago", + "bid": [{ + "id": "test-imp-id", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-ads", + "crid": "crid_testid" + }] + } + ], + "cur": "USD" + } + } + } + ], + + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-imp-id", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-ads", + "crid": "crid_testid" + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/mediago/mediagotest/exemplary/sample-native.json b/adapters/mediago/mediagotest/exemplary/sample-native.json new file mode 100644 index 00000000000..eb302df2375 --- /dev/null +++ b/adapters/mediago/mediagotest/exemplary/sample-native.json @@ -0,0 +1,91 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "native": { + "request": "{\"ver\":\"1.2\",\"context\":1,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":2,\"required\":1,\"title\":{\"len\":90}},{\"id\":6,\"required\":1,\"img\":{\"type\":3,\"wmin\":128,\"hmin\":128,\"mimes\":[\"image/jpg\",\"image/jpeg\",\"image/png\"]}},{\"id\":7,\"required\":1,\"data\":{\"type\":2,\"len\":120}}]}", + "ver": "1.2" + }, + "ext": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b", + "placementId": "testPlacementId" + } + } + } + ], + "site": { + "id": "test-site-id", + "page": "https://www.example.com/" + } + }, + "httpcalls": [ + { + "expectedRequest": { + "uri": "https://REGION.mediago.io/api/bid?tn=f9f2b1ef23fe2759c2cad0953029a94b", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "native": { + "request": "{\"ver\":\"1.2\",\"context\":1,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":2,\"required\":1,\"title\":{\"len\":90}},{\"id\":6,\"required\":1,\"img\":{\"type\":3,\"wmin\":128,\"hmin\":128,\"mimes\":[\"image/jpg\",\"image/jpeg\",\"image/png\"]}},{\"id\":7,\"required\":1,\"data\":{\"type\":2,\"len\":120}}]}", + "ver": "1.2" + }, + "ext": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b", + "placementId": "testPlacementId" + } + } + } + ], + "site": { + "id": "test-site-id", + "page": "https://www.example.com/" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test-imp-id", + "impid": "test-imp-id", + "price": 1.2, + "adm": "some ads", + "crid": "crid_testid" + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-imp-id", + "impid": "test-imp-id", + "price": 1.2, + "adm": "some ads", + "crid": "crid_testid" + + }, + "type": "native" + } + ] + } + ] +} diff --git a/adapters/mediago/mediagotest/exemplary/sample-nobid.json b/adapters/mediago/mediagotest/exemplary/sample-nobid.json new file mode 100644 index 00000000000..7c2d7e351b3 --- /dev/null +++ b/adapters/mediago/mediagotest/exemplary/sample-nobid.json @@ -0,0 +1,62 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 320, "h": 50}] + }, + "ext": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b", + "placementId": "testPlacementId" + } + } + } + ], + "site": { + "id": "test-site-id", + "page": "https://www.example.com/" + } + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://REGION.mediago.io/api/bid?tn=f9f2b1ef23fe2759c2cad0953029a94b", + "body": { + "id": "test-request-id", + "imp": [ + { + "id":"test-imp-id", + "banner": { + "format": [{"w": 320, "h": 50}], + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b", + "placementId": "testPlacementId" + } + } + } + ], + "site": { + "id": "test-site-id", + "page": "https://www.example.com/" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 204, + "body": {} + } + } + ], + + "expectedBidResponses": [] + +} diff --git a/adapters/mediago/mediagotest/exemplary/sample-with-mtype.json b/adapters/mediago/mediagotest/exemplary/sample-with-mtype.json new file mode 100644 index 00000000000..609b916757e --- /dev/null +++ b/adapters/mediago/mediagotest/exemplary/sample-with-mtype.json @@ -0,0 +1,152 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 320, "h": 50}] + }, + "ext": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b" + } + } + }, + { + "id":"test-imp-id2", + "native": { + "request": "{\"ver\":\"1.2\",\"context\":1,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":2,\"required\":1,\"title\":{\"len\":90}},{\"id\":6,\"required\":1,\"img\":{\"type\":3,\"wmin\":128,\"hmin\":128,\"mimes\":[\"image/jpg\",\"image/jpeg\",\"image/png\"]}},{\"id\":7,\"required\":1,\"data\":{\"type\":2,\"len\":120}}]}", + "ver": "1.2" + }, + "ext": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b" + } + } + } + ], + "site": { + "id": "test-site-id", + "page": "https://www.example.com/" + }, + "ext": { + "prebid": { + "bidderparams": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b" + } + } + } + } + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://REGION.mediago.io/api/bid?tn=f9f2b1ef23fe2759c2cad0953029a94b", + "body": { + "id": "test-request-id", + "imp": [ + { + "id":"test-imp-id", + "banner": { + "format": [{"w": 320, "h": 50}], + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b" + } + } + }, + { + "id":"test-imp-id2", + "native": { + "request": "{\"ver\":\"1.2\",\"context\":1,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":2,\"required\":1,\"title\":{\"len\":90}},{\"id\":6,\"required\":1,\"img\":{\"type\":3,\"wmin\":128,\"hmin\":128,\"mimes\":[\"image/jpg\",\"image/jpeg\",\"image/png\"]}},{\"id\":7,\"required\":1,\"data\":{\"type\":2,\"len\":120}}]}", + "ver": "1.2" + }, + "ext": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b" + } + } + } + ], + "site": { + "id": "test-site-id", + "page": "https://www.example.com/" + }, + "ext": { + "prebid": { + "bidderparams": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b" + } + } + } + } + }, + "impIDs":["test-imp-id", "test-imp-id2"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "mediago", + "bid": [{ + "id": "test-imp-id", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-ads", + "crid": "crid_testid", + "mtype": 1 + }, { + "id": "test-imp-id2", + "impid": "test-imp-id2", + "price": 1.2, + "adm": "some ads", + "crid": "crid_testid", + "mtype": 4 + }] + } + ], + "cur": "USD" + } + } + } + ], + + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-imp-id", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-ads", + "crid": "crid_testid", + "mtype": 1 + }, + "type": "banner" + }, + { + "bid": { + "id": "test-imp-id2", + "impid": "test-imp-id2", + "price": 1.2, + "adm": "some ads", + "crid": "crid_testid", + "mtype": 4 + }, + "type": "native" + } + ] + } + ] +} diff --git a/adapters/mediago/mediagotest/supplemental/bad_400_reponse.json b/adapters/mediago/mediagotest/supplemental/bad_400_reponse.json new file mode 100644 index 00000000000..c40f0db418b --- /dev/null +++ b/adapters/mediago/mediagotest/supplemental/bad_400_reponse.json @@ -0,0 +1,65 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 320, "h": 50}] + }, + "ext": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b", + "placementId": "testPlacementId" + } + } + } + ], + "site": { + "id": "test-site-id", + "page": "https://www.example.com/" + } + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://REGION.mediago.io/api/bid?tn=f9f2b1ef23fe2759c2cad0953029a94b", + "body": { + "id": "test-request-id", + "imp": [ + { + "id":"test-imp-id", + "banner": { + "format": [{"w": 320, "h": 50}], + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b", + "placementId": "testPlacementId" + } + } + } + ], + "site": { + "id": "test-site-id", + "page": "https://www.example.com/" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 400 + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} diff --git a/adapters/mediago/mediagotest/supplemental/bad_500_reponse.json b/adapters/mediago/mediagotest/supplemental/bad_500_reponse.json new file mode 100644 index 00000000000..b653b33eaac --- /dev/null +++ b/adapters/mediago/mediagotest/supplemental/bad_500_reponse.json @@ -0,0 +1,66 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 320, "h": 50}] + }, + "ext": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b", + "placementId": "testPlacementId" + } + } + } + ], + "site": { + "id": "test-site-id", + "page": "https://www.example.com/" + } + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://REGION.mediago.io/api/bid?tn=f9f2b1ef23fe2759c2cad0953029a94b", + "body": { + "id": "test-request-id", + "imp": [ + { + "id":"test-imp-id", + "banner": { + "format": [{"w": 320, "h": 50}], + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b", + "placementId": "testPlacementId" + } + } + } + ], + "site": { + "id": "test-site-id", + "page": "https://www.example.com/" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 500 + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 500. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] + +} diff --git a/adapters/mediago/mediagotest/supplemental/bad_imp_ext.json b/adapters/mediago/mediagotest/supplemental/bad_imp_ext.json new file mode 100644 index 00000000000..9c510cf16f2 --- /dev/null +++ b/adapters/mediago/mediagotest/supplemental/bad_imp_ext.json @@ -0,0 +1,25 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 320, "h": 50}] + }, + "ext": "badExt" + } + ], + "site": { + "id": "test-site-id", + "page": "https://www.example.com/" + } + }, + + "expectedMakeRequestsErrors": [ + { + "value": "expect { or n, but found \"", + "comparison": "literal" + } + ] +} diff --git a/adapters/mediago/mediagotest/supplemental/bad_impext_bidder.json b/adapters/mediago/mediagotest/supplemental/bad_impext_bidder.json new file mode 100644 index 00000000000..a5776adaed7 --- /dev/null +++ b/adapters/mediago/mediagotest/supplemental/bad_impext_bidder.json @@ -0,0 +1,27 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 320, "h": 50}] + }, + "ext": { + "bidder": "badBidder" + } + } + ], + "site": { + "id": "test-site-id", + "page": "https://www.example.com/" + } + }, + + "expectedMakeRequestsErrors": [ + { + "value": "expect { or n, but found \"", + "comparison": "literal" + } + ] +} diff --git a/adapters/mediago/mediagotest/supplemental/bad_request_no_token.json b/adapters/mediago/mediagotest/supplemental/bad_request_no_token.json new file mode 100644 index 00000000000..51034b2eefd --- /dev/null +++ b/adapters/mediago/mediagotest/supplemental/bad_request_no_token.json @@ -0,0 +1,30 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 320, "h": 50}] + }, + "ext": { + "bidder": { + "placementId": "testPlacementId", + "region": "APAC" + } + } + } + ], + "site": { + "id": "test-site-id", + "page": "https://www.example.com/" + } + }, + + "expectedMakeRequestsErrors": [ + { + "value": "mediago token not found", + "comparison": "literal" + } + ] +} diff --git a/adapters/mediago/mediagotest/supplemental/bad_response.json b/adapters/mediago/mediagotest/supplemental/bad_response.json new file mode 100644 index 00000000000..922e1debf40 --- /dev/null +++ b/adapters/mediago/mediagotest/supplemental/bad_response.json @@ -0,0 +1,66 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 320, "h": 50}] + }, + "ext": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b", + "placementId": "testPlacementId" + } + } + } + ], + "site": { + "id": "test-site-id", + "page": "https://www.example.com/" + } + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://REGION.mediago.io/api/bid?tn=f9f2b1ef23fe2759c2cad0953029a94b", + "body": { + "id": "test-request-id", + "imp": [ + { + "id":"test-imp-id", + "banner": { + "format": [{"w": 320, "h": 50}], + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b", + "placementId": "testPlacementId" + } + } + } + ], + "site": { + "id": "test-site-id", + "page": "https://www.example.com/" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": "{\"id\":test-request-id" + } + } + ], + + "expectedMakeBidsErrors": [ + { + "comparison": "literal", + "value": "expect { or n, but found \"" + } + ] +} diff --git a/adapters/mediago/mediagotest/supplemental/bad_response_error_mtype.json b/adapters/mediago/mediagotest/supplemental/bad_response_error_mtype.json new file mode 100644 index 00000000000..65167e04c5a --- /dev/null +++ b/adapters/mediago/mediagotest/supplemental/bad_response_error_mtype.json @@ -0,0 +1,134 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [{"w": 320, "h": 50}] + }, + "ext": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b" + } + } + }, + { + "id":"test-imp-id2", + "native": { + "request": "{\"ver\":\"1.2\",\"context\":1,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":2,\"required\":1,\"title\":{\"len\":90}},{\"id\":6,\"required\":1,\"img\":{\"type\":3,\"wmin\":128,\"hmin\":128,\"mimes\":[\"image/jpg\",\"image/jpeg\",\"image/png\"]}},{\"id\":7,\"required\":1,\"data\":{\"type\":2,\"len\":120}}]}", + "ver": "1.2" + }, + "ext": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b" + } + } + } + ], + "site": { + "id": "test-site-id", + "page": "https://www.example.com/" + }, + "ext": { + "prebid": { + "bidderparams": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b" + } + } + } + } + }, + + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://REGION.mediago.io/api/bid?tn=f9f2b1ef23fe2759c2cad0953029a94b", + "body": { + "id": "test-request-id", + "imp": [ + { + "id":"test-imp-id", + "banner": { + "format": [{"w": 320, "h": 50}], + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b" + } + } + }, + { + "id":"test-imp-id2", + "native": { + "request": "{\"ver\":\"1.2\",\"context\":1,\"plcmttype\":4,\"plcmtcnt\":1,\"assets\":[{\"id\":2,\"required\":1,\"title\":{\"len\":90}},{\"id\":6,\"required\":1,\"img\":{\"type\":3,\"wmin\":128,\"hmin\":128,\"mimes\":[\"image/jpg\",\"image/jpeg\",\"image/png\"]}},{\"id\":7,\"required\":1,\"data\":{\"type\":2,\"len\":120}}]}", + "ver": "1.2" + }, + "ext": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b" + } + } + } + ], + "site": { + "id": "test-site-id", + "page": "https://www.example.com/" + }, + "ext": { + "prebid": { + "bidderparams": { + "bidder": { + "token": "f9f2b1ef23fe2759c2cad0953029a94b" + } + } + } + } + }, + "impIDs":["test-imp-id", "test-imp-id2"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "mediago", + "bid": [{ + "id": "test-imp-id", + "price": 0.5, + "adm": "some-ads", + "crid": "crid_testid", + "mtype": 2 + }, { + "id": "test-imp-id2", + "price": 1.2, + "adm": "some ads", + "crid": "crid_testid", + "mtype": 5 + }] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [{ + "currency": "USD", + "bids": [] + }], + "expectedMakeBidsErrors": [ + { + "value": "Unsupported MType 2", + "comparison": "literal" + }, + { + "value": "Unsupported MType 5", + "comparison": "literal" + } + ] +} diff --git a/adapters/mediago/params_test.go b/adapters/mediago/params_test.go new file mode 100644 index 00000000000..c1a7fbd3e43 --- /dev/null +++ b/adapters/mediago/params_test.go @@ -0,0 +1,50 @@ +package mediago + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v3/openrtb_ext" +) + +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schemas. %v", err) + } + + for _, validParam := range validParams { + if err := validator.Validate(openrtb_ext.BidderMediaGo, json.RawMessage(validParam)); err != nil { + t.Errorf("Schema rejected mediago params: %s", validParam) + } + } +} + +// TestInvalidParams makes sure that the mediago schema rejects all the imp.ext fields we don't support. +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schemas. %v", err) + } + + for _, invalidParam := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderMediaGo, json.RawMessage(invalidParam)); err == nil { + t.Errorf("Schema allowed unexpected params: %s", invalidParam) + } + } +} + +var validParams = []string{ + `{"token": "f9f2b1ef23fe2759c2cad0953029a94b"}`, + `{"token": "f9f2b1ef23fe2759c2cad0953029a94b", "region": "APAC"}`, + `{"token": "f9f2b1ef23fe2759c2cad0953029a94b", "region": "US"}`, + `{"token": "f9f2b1ef23fe2759c2cad0953029a94b", "region": "EU"}`, +} + +var invalidParams = []string{ + `{}`, + `{"tn": "f9f2b1ef23fe2759c2cad0953029a94b"}`, + `{"region": "APAC"}`, + `{"region": "US"}`, + `{"tn": "f9f2b1ef23fe2759c2cad0953029a94b", "region": "EU"}`, +} diff --git a/adapters/medianet/medianet.go b/adapters/medianet/medianet.go index a6a3bd4709a..08a1ae021f4 100644 --- a/adapters/medianet/medianet.go +++ b/adapters/medianet/medianet.go @@ -7,10 +7,11 @@ import ( "net/url" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -59,7 +60,7 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } diff --git a/adapters/medianet/medianet_test.go b/adapters/medianet/medianet_test.go index 097e8e48727..8721c6984cd 100644 --- a/adapters/medianet/medianet_test.go +++ b/adapters/medianet/medianet_test.go @@ -5,9 +5,9 @@ import ( "github.com/stretchr/testify/assert" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/medianet/params_test.go b/adapters/medianet/params_test.go index 7c999a66428..15cd4acbab3 100644 --- a/adapters/medianet/params_test.go +++ b/adapters/medianet/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/medianet.json diff --git a/adapters/melozen/melozen.go b/adapters/melozen/melozen.go new file mode 100644 index 00000000000..d49cc287846 --- /dev/null +++ b/adapters/melozen/melozen.go @@ -0,0 +1,186 @@ +package melozen + +import ( + "encoding/json" + "fmt" + "net/http" + "strings" + "text/template" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" +) + +type adapter struct { + endpointTemplate *template.Template +} + +// Builder builds a new instance of the MeloZen adapter for the given bidder with the given config. +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + template, err := template.New("endpointTemplate").Parse(config.Endpoint) + if err != nil { + return nil, fmt.Errorf("unable to parse endpoint url template: %v", err) + } + + bidder := &adapter{ + endpointTemplate: template, + } + + return bidder, nil +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + var requests []*adapters.RequestData + var errors []error + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + headers.Add("Accept", "application/json") + + requestCopy := *request + for _, imp := range request.Imp { + // Extract Melozen Params + var strImpExt adapters.ExtImpBidder + if err := jsonutil.Unmarshal(imp.Ext, &strImpExt); err != nil { + errors = append(errors, err) + continue + } + var strImpParams openrtb_ext.ImpExtMeloZen + if err := jsonutil.Unmarshal(strImpExt.Bidder, &strImpParams); err != nil { + errors = append(errors, err) + continue + } + + url, err := macros.ResolveMacros(a.endpointTemplate, macros.EndpointTemplateParams{PublisherID: strImpParams.PubId}) + if err != nil { + errors = append(errors, err) + continue + } + // Convert Floor into USD + if imp.BidFloor > 0 && imp.BidFloorCur != "" && !strings.EqualFold(imp.BidFloorCur, "USD") { + convertedValue, err := reqInfo.ConvertCurrency(imp.BidFloor, imp.BidFloorCur, "USD") + if err != nil { + errors = append(errors, err) + continue + } + imp.BidFloorCur = "USD" + imp.BidFloor = convertedValue + } + + impressionsByMediaType, err := splitImpressionsByMediaType(&imp) + if err != nil { + errors = append(errors, err) + continue + } + + for _, impression := range impressionsByMediaType { + requestCopy.Imp = []openrtb2.Imp{impression} + + requestJSON, err := json.Marshal(requestCopy) + if err != nil { + errors = append(errors, err) + continue + } + + requestData := &adapters.RequestData{ + Method: "POST", + Uri: url, + Body: requestJSON, + Headers: headers, + ImpIDs: openrtb_ext.GetImpIDs(requestCopy.Imp), + } + requests = append(requests, requestData) + } + } + + return requests, errors +} + +func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if adapters.IsResponseStatusCodeNoContent(response) { + return nil, nil + } + + if err := adapters.CheckResponseStatusCodeForErrors(response); err != nil { + return nil, []error{err} + } + + var bidReq openrtb2.BidRequest + if err := jsonutil.Unmarshal(requestData.Body, &bidReq); err != nil { + return nil, []error{err} + } + + var bidResp openrtb2.BidResponse + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { + return nil, []error{err} + } + + bidderResponse := adapters.NewBidderResponse() + var errors []error + for _, seatBid := range bidResp.SeatBid { + for i := range seatBid.Bid { + bid := &seatBid.Bid[i] + bidType, err := getMediaTypeForBid(*bid) + if err != nil { + errors = append(errors, err) + continue + } + + bidderResponse.Bids = append(bidderResponse.Bids, &adapters.TypedBid{ + BidType: bidType, + Bid: bid, + }) + } + } + return bidderResponse, errors +} + +func splitImpressionsByMediaType(impression *openrtb2.Imp) ([]openrtb2.Imp, error) { + if impression.Banner == nil && impression.Native == nil && impression.Video == nil { + return nil, &errortypes.BadInput{Message: "Invalid MediaType. MeloZen only supports Banner, Video and Native."} + } + + impressions := make([]openrtb2.Imp, 0, 2) + + if impression.Banner != nil { + impCopy := *impression + impCopy.Video = nil + impCopy.Native = nil + impressions = append(impressions, impCopy) + } + + if impression.Video != nil { + impCopy := *impression + impCopy.Banner = nil + impCopy.Native = nil + impressions = append(impressions, impCopy) + } + + if impression.Native != nil { + impCopy := *impression + impCopy.Banner = nil + impCopy.Video = nil + impressions = append(impressions, impCopy) + } + + return impressions, nil +} + +func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) { + + if bid.Ext != nil { + var bidExt openrtb_ext.ExtBid + err := jsonutil.Unmarshal(bid.Ext, &bidExt) + if err == nil && bidExt.Prebid != nil { + return openrtb_ext.ParseBidType(string(bidExt.Prebid.Type)) + } + } + + return "", &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Failed to parse bid mediatype for impression \"%s\"", bid.ImpID), + } +} diff --git a/adapters/melozen/melozen_test.go b/adapters/melozen/melozen_test.go new file mode 100644 index 00000000000..cf6189c6abc --- /dev/null +++ b/adapters/melozen/melozen_test.go @@ -0,0 +1,30 @@ +package melozen + +import ( + "testing" + + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/stretchr/testify/assert" +) + +func TestJsonSamples(t *testing.T) { + + bidder, buildErr := Builder(openrtb_ext.BidderMeloZen, config.Adapter{ + Endpoint: "https://example.com/rtb/v2/bid?publisher_id={{.PublisherID}}", + }, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "melozentest", bidder) +} + +func TestEndpointTemplateMalformed(t *testing.T) { + _, buildErr := Builder(openrtb_ext.BidderMeloZen, config.Adapter{ + Endpoint: "{{Malformed}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + assert.Error(t, buildErr) +} diff --git a/adapters/melozen/melozentest/exemplary/app-banner.json b/adapters/melozen/melozentest/exemplary/app-banner.json new file mode 100644 index 00000000000..6cdb82bf5ad --- /dev/null +++ b/adapters/melozen/melozentest/exemplary/app-banner.json @@ -0,0 +1,132 @@ +{ + "mockBidRequest": { + "id": "web-banner", + "tmax": 3000, + "imp": [ + { + "id": "banner-imp-id", + "ext": { + "bidder": { + "pubId": "386276e072" + } + }, + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + } + } + ], + "app": { + "bundle": "com.fake.app", + "publisher": { + "id": "42", + "name": "whatever.pub" + } + }, + "device": { + "w": 1200, + "h": 900 + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.com/rtb/v2/bid?publisher_id=386276e072", + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"] + }, + "body": { + "id": "web-banner", + "tmax": 3000, + "imp": [ + { + "id": "banner-imp-id", + "ext": { + "bidder": { + "pubId": "386276e072" + } + }, + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + } + } + ], + "device": { + "w": 1200, + "h": 900 + }, + "app": { + "bundle": "com.fake.app", + "publisher": { + "id": "42", + "name": "whatever.pub" + } + } + }, + "impIDs":["banner-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "web-banner", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "web-banner", + "impid": "banner-imp-id", + "crid": "some-creative-id", + "adm": "
Ad
", + "price": 20, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "web-banner", + "impid": "banner-imp-id", + "crid": "some-creative-id", + "adm": "
Ad
", + "price": 20, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] + } + \ No newline at end of file diff --git a/adapters/melozen/melozentest/exemplary/app-native.json b/adapters/melozen/melozentest/exemplary/app-native.json new file mode 100644 index 00000000000..f93abd44bea --- /dev/null +++ b/adapters/melozen/melozentest/exemplary/app-native.json @@ -0,0 +1,100 @@ +{ + "mockBidRequest": { + "id": "web-native", + "imp": [ + { + "id": "native-imp-id", + "ext": { + "bidder": { + "pubId": "386276e072" + } + }, + "native": { + "ver": "1.2", + "request": "placeholder request" + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.com/rtb/v2/bid?publisher_id=386276e072", + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"] + }, + "body": { + "id": "web-native", + "imp": [ + { + "id": "native-imp-id", + "ext": { + "bidder": { + "pubId": "386276e072" + } + }, + "native": { + "ver": "1.2", + "request": "placeholder request" + } + } + ] + }, + "impIDs":["native-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "web-native", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "web-native", + "impid": "native-imp-id", + "crid": "some-creative-id", + "adm": "
Ad
", + "price": 20, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "native" + } + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "web-native", + "impid": "native-imp-id", + "crid": "some-creative-id", + "adm": "
Ad
", + "price": 20, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "native" + } + } + }, + "type": "native" + } + ] + } + ] + } + \ No newline at end of file diff --git a/adapters/melozen/melozentest/exemplary/app-video.json b/adapters/melozen/melozentest/exemplary/app-video.json new file mode 100644 index 00000000000..3d913c43e44 --- /dev/null +++ b/adapters/melozen/melozentest/exemplary/app-video.json @@ -0,0 +1,137 @@ +{ + "mockBidRequest": { + "id": "app-video", + "tmax": 3000, + "imp": [ + { + "id": "video-imp-id", + "ext": { + "bidder": { + "pubId": "386276e072" + } + }, + "video": { + "w": 640, + "h": 480, + "mimes": [ + "video/mp4" + ], + "placement": 1 + } + } + ], + "app": { + "bundle": "com.fake.app", + "publisher": { + "id": "42", + "name": "whatever.pub" + } + }, + "device": { + "w": 1200, + "h": 900 + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.com/rtb/v2/bid?publisher_id=386276e072", + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ] + }, + "body": { + "id": "app-video", + "tmax": 3000, + "imp": [ + { + "id": "video-imp-id", + "ext": { + "bidder": { + "pubId": "386276e072" + } + }, + "video": { + "w": 640, + "h": 480, + "mimes": [ + "video/mp4" + ], + "placement": 1 + } + } + ], + "app": { + "bundle": "com.fake.app", + "publisher": { + "id": "42", + "name": "whatever.pub" + } + }, + "device": { + "w": 1200, + "h": 900 + } + }, + "impIDs": [ + "video-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "app-video", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "app-video", + "impid": "video-imp-id", + "crid": "some-creative-id", + "adm": "TAG", + "price": 20, + "w": 640, + "h": 480, + "ext": { + "prebid": { + "type": "video" + } + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "app-video", + "impid": "video-imp-id", + "crid": "some-creative-id", + "adm": "TAG", + "price": 20, + "w": 640, + "h": 480, + "ext": { + "prebid": { + "type": "video" + } + } + }, + "type": "video" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/melozen/melozentest/exemplary/multi-imps.json b/adapters/melozen/melozentest/exemplary/multi-imps.json new file mode 100644 index 00000000000..916c74cb685 --- /dev/null +++ b/adapters/melozen/melozentest/exemplary/multi-imps.json @@ -0,0 +1,239 @@ +{ + "mockBidRequest": { + "id": "web-banner", + "tmax": 3000, + "imp": [ + { + "id": "banner-imp-id-1", + "ext": { + "bidder": { + "pubId": "386276e072" + } + }, + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + } + }, + { + "id": "banner-imp-id-2", + "ext": { + "bidder": { + "pubId": "386276e072" + } + }, + "banner": { + "format": [ + { + "w": 300, + "h": 600 + } + ] + } + } + ], + "site": { + "publisher": { + "id": "1" + }, + "page": "https://some-site.com", + "ref": "https://some-site.com" + }, + "device": { + "w": 1200, + "h": 900 + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.com/rtb/v2/bid?publisher_id=386276e072", + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"] + }, + "body": { + "id": "web-banner", + "tmax": 3000, + "imp": [ + { + "id": "banner-imp-id-1", + "ext": { + "bidder": { + "pubId": "386276e072" + } + }, + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + } + } + ], + "site": { + "publisher": { + "id": "1" + }, + "page": "https://some-site.com", + "ref": "https://some-site.com" + }, + "device": { + "w": 1200, + "h": 900 + } + }, + "impIDs":["banner-imp-id-1"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "web-banner", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "web-banner", + "impid": "banner-imp-id-1", + "crid": "some-creative-id", + "adm": "
Ad
", + "price": 20, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ] + } + ] + } + } + }, + { + "expectedRequest": { + "uri": "https://example.com/rtb/v2/bid?publisher_id=386276e072", + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"] + }, + "body": { + "id": "web-banner", + "tmax": 3000, + "imp": [ + { + "id": "banner-imp-id-2", + "ext": { + "bidder": { + "pubId": "386276e072" + } + }, + "banner": { + "format": [ + { + "w": 300, + "h": 600 + } + ] + } + } + ], + "site": { + "publisher": { + "id": "1" + }, + "page": "https://some-site.com", + "ref": "https://some-site.com" + }, + "device": { + "w": 1200, + "h": 900 + } + }, + "impIDs":["banner-imp-id-2"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "web-banner", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "web-banner", + "impid": "banner-imp-id-2", + "crid": "some-creative-id", + "adm": "
Ad
", + "price": 20, + "w": 300, + "h": 600, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "web-banner", + "impid": "banner-imp-id-1", + "crid": "some-creative-id", + "adm": "
Ad
", + "price": 20, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + }, + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "web-banner", + "impid": "banner-imp-id-2", + "crid": "some-creative-id", + "adm": "
Ad
", + "price": 20, + "w": 300, + "h": 600, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/melozen/melozentest/exemplary/web-banner.json b/adapters/melozen/melozentest/exemplary/web-banner.json new file mode 100644 index 00000000000..0439baa1033 --- /dev/null +++ b/adapters/melozen/melozentest/exemplary/web-banner.json @@ -0,0 +1,138 @@ +{ + "mockBidRequest": { + "id": "web-banner", + "tmax": 3000, + "imp": [ + { + "id": "baner-imp-id", + "ext": { + "bidder": { + "pubId": "386276e072" + } + }, + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + } + } + ], + "test": 0, + "site": { + "publisher": { + "id": "1" + }, + "page": "https://some-site.com", + "ref": "https://some-site.com" + }, + "device": { + "w": 1200, + "h": 900 + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.com/rtb/v2/bid?publisher_id=386276e072", + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ] + }, + "body": { + "id": "web-banner", + "tmax": 3000, + "imp": [ + { + "id": "baner-imp-id", + "ext": { + "bidder": { + "pubId": "386276e072" + } + }, + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + } + } + ], + "site": { + "publisher": { + "id": "1" + }, + "page": "https://some-site.com", + "ref": "https://some-site.com" + }, + "device": { + "w": 1200, + "h": 900 + } + }, + "impIDs": [ + "baner-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "web-banner", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "web-banner", + "impid": "baner-imp-id", + "crid": "some-creative-id", + "adm": "
Ad
", + "price": 20, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "web-banner", + "impid": "baner-imp-id", + "crid": "some-creative-id", + "adm": "
Ad
", + "price": 20, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/melozen/melozentest/exemplary/web-video.json b/adapters/melozen/melozentest/exemplary/web-video.json new file mode 100644 index 00000000000..b4f179bdc55 --- /dev/null +++ b/adapters/melozen/melozentest/exemplary/web-video.json @@ -0,0 +1,129 @@ +{ + "mockBidRequest": { + "id": "web-video", + "tmax": 3000, + "imp": [ + { + "id": "video-imp-id", + "ext": { + "bidder": { + "pubId": "386276e072" + } + }, + "video": { + "w": 640, + "h": 480, + "mimes": ["video/mp4"], + "placement": 1 + } + } + ], + "test": 0, + "site": { + "publisher": { + "id": "1" + }, + "page": "https://some-site.com", + "ref": "https://some-site.com" + }, + "device": { + "w": 1200, + "h": 900 + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.com/rtb/v2/bid?publisher_id=386276e072", + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"] + }, + "body": { + "id": "web-video", + "tmax": 3000, + "imp": [ + { + "id": "video-imp-id", + "ext": { + "bidder": { + "pubId": "386276e072" + } + }, + "video": { + "w": 640, + "h": 480, + "mimes": ["video/mp4"], + "placement": 1 + } + } + ], + "site": { + "publisher": { + "id": "1" + }, + "page": "https://some-site.com", + "ref": "https://some-site.com" + }, + "device": { + "w": 1200, + "h": 900 + } + }, + "impIDs":["video-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "web-video", + "cur": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "web-video", + "impid": "video-imp-id", + "crid": "some-creative-id", + "adm": "TAG", + "price": 20, + "w": 640, + "h": 480, + "ext": { + "prebid": { + "type": "video" + } + } + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "web-video", + "impid": "video-imp-id", + "crid": "some-creative-id", + "adm": "TAG", + "price": 20, + "w": 640, + "h": 480, + "ext": { + "prebid": { + "type": "video" + } + } + }, + "type": "video" + } + ] + } + ] + } + \ No newline at end of file diff --git a/adapters/melozen/melozentest/supplemental/bad-media-type-request.json b/adapters/melozen/melozentest/supplemental/bad-media-type-request.json new file mode 100644 index 00000000000..f6c17a70b8f --- /dev/null +++ b/adapters/melozen/melozentest/supplemental/bad-media-type-request.json @@ -0,0 +1,28 @@ +{ + "mockBidRequest": { + "id": "unsupported-request", + "imp": [ + { + "id": "unsupported-imp", + "unupported": { + }, + "ext": { + "bidder": { + "pubId": "386276e072" + } + } + } + ], + "site": { + "id": "siteID" + } + }, + + "expectedMakeRequestsErrors": [ + { + "value": "Invalid MediaType. MeloZen only supports Banner, Video and Native.", + "comparison": "literal" + } + ] + } + \ No newline at end of file diff --git a/adapters/melozen/melozentest/supplemental/no-fill.json b/adapters/melozen/melozentest/supplemental/no-fill.json new file mode 100644 index 00000000000..7dd600a72b6 --- /dev/null +++ b/adapters/melozen/melozentest/supplemental/no-fill.json @@ -0,0 +1,90 @@ +{ + "mockBidRequest": { + "id": "web-banner", + "tmax": 3000, + "imp": [ + { + "id": "banner-imp-id", + "ext": { + "bidder": { + "pubId": "386276e072" + } + }, + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + } + } + ], + "app": { + "bundle": "com.fake.app", + "publisher": { + "id": "42", + "name": "whatever.pub" + } + }, + "device": { + "w": 1200, + "h": 900 + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.com/rtb/v2/bid?publisher_id=386276e072", + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ] + }, + "body": { + "id": "web-banner", + "tmax": 3000, + "imp": [ + { + "id": "banner-imp-id", + "ext": { + "bidder": { + "pubId": "386276e072" + } + }, + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + } + } + ], + "device": { + "w": 1200, + "h": 900 + }, + "app": { + "bundle": "com.fake.app", + "publisher": { + "id": "42", + "name": "whatever.pub" + } + } + }, + "impIDs": [ + "banner-imp-id" + ] + }, + "mockResponse": { + "status": 204 + } + } + ], + "expectedMakeBidsErrors": [] +} \ No newline at end of file diff --git a/adapters/melozen/melozentest/supplemental/response-status-400.json b/adapters/melozen/melozentest/supplemental/response-status-400.json new file mode 100644 index 00000000000..969875b86ec --- /dev/null +++ b/adapters/melozen/melozentest/supplemental/response-status-400.json @@ -0,0 +1,95 @@ +{ + "mockBidRequest": { + "id": "web-banner", + "tmax": 3000, + "imp": [ + { + "id": "banner-imp-id", + "ext": { + "bidder": { + "pubId": "386276e072" + } + }, + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + } + } + ], + "app": { + "bundle": "com.fake.app", + "publisher": { + "id": "42", + "name": "whatever.pub" + } + }, + "device": { + "w": 1200, + "h": 900 + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.com/rtb/v2/bid?publisher_id=386276e072", + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ] + }, + "body": { + "id": "web-banner", + "tmax": 3000, + "imp": [ + { + "id": "banner-imp-id", + "ext": { + "bidder": { + "pubId": "386276e072" + } + }, + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + } + } + ], + "device": { + "w": 1200, + "h": 900 + }, + "app": { + "bundle": "com.fake.app", + "publisher": { + "id": "42", + "name": "whatever.pub" + } + } + }, + "impIDs": [ + "banner-imp-id" + ] + }, + "mockResponse": { + "status": 400 + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/melozen/melozentest/supplemental/response-status-not-200.json b/adapters/melozen/melozentest/supplemental/response-status-not-200.json new file mode 100644 index 00000000000..9b26ee58091 --- /dev/null +++ b/adapters/melozen/melozentest/supplemental/response-status-not-200.json @@ -0,0 +1,84 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "pubId": "386276e072" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.test.testapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://example.com/rtb/v2/bid?publisher_id=386276e072", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "pubId": "386276e072" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.test.testapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 404, + "body": {} + } + }], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 404. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} diff --git a/adapters/melozen/melozentest/supplemental/wrong-bid-ext.json b/adapters/melozen/melozentest/supplemental/wrong-bid-ext.json new file mode 100644 index 00000000000..b6a1c1f7268 --- /dev/null +++ b/adapters/melozen/melozentest/supplemental/wrong-bid-ext.json @@ -0,0 +1,85 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "w": 900, + "h": 250, + "mimes": [ + "video/x-flv", + "video/mp4" + ] + }, + "ext": { + "bidder": { + "pubId": "386276e072" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://example.com/rtb/v2/bid?publisher_id=386276e072", + "headers": { + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"] + }, + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "w": 900, + "h": 250, + "mimes": [ + "video/x-flv", + "video/mp4" + ] + }, + "ext": { + "bidder": { + "pubId": "386276e072" + } + } + } + ] + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test-bid-id", + "impid": "another-imp-id", + "price": 3.5, + "w": 900, + "h": 250, + "ext": {} + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [{"currency":"USD","bids":[]}], + "expectedMakeBidsErrors": [ + { + "value": "Failed to parse bid mediatype for impression \"another-imp-id\"", + "comparison": "regex" + } + ] +} \ No newline at end of file diff --git a/adapters/melozen/params_test.go b/adapters/melozen/params_test.go new file mode 100644 index 00000000000..42a4b38ec8d --- /dev/null +++ b/adapters/melozen/params_test.go @@ -0,0 +1,50 @@ +package melozen + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v3/openrtb_ext" +) + +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the JSON schema. %v", err) + } + + for _, p := range validParams { + if err := validator.Validate(openrtb_ext.BidderMeloZen, json.RawMessage(p)); err != nil { + t.Errorf("Schema rejected valid params: %s", p) + } + } +} + +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the JSON schema. %v", err) + } + + for _, p := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderMeloZen, json.RawMessage(p)); err == nil { + t.Errorf("Schema allowed invalid params: %s", p) + } + } +} + +var validParams = []string{ + `{"pubId": "12345"}`, +} + +var invalidParams = []string{ + ``, + `null`, + `true`, + `5`, + `4.2`, + `[]`, + `{}`, + `{"pubId": ""}`, + `{"pubId": 12345}`, +} diff --git a/adapters/metax/metax.go b/adapters/metax/metax.go new file mode 100644 index 00000000000..bd1f6272bea --- /dev/null +++ b/adapters/metax/metax.go @@ -0,0 +1,195 @@ +package metax + +import ( + "encoding/json" + "errors" + "fmt" + "net/http" + "strconv" + "text/template" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/ptrutil" +) + +type adapter struct { + template *template.Template +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + errs := make([]error, 0, len(request.Imp)) + + // split impressions + reqDatas := make([]*adapters.RequestData, 0, len(request.Imp)) + for _, imp := range request.Imp { + metaxExt, err := parseBidderExt(&imp) + if err != nil { + errs = append(errs, err) + continue + } + + if err := preprocessImp(&imp); err != nil { + errs = append(errs, err) + continue + } + + endpoint, err := a.getEndpoint(metaxExt) + if err != nil { + errs = append(errs, err) + continue + } + + requestCopy := *request + requestCopy.Imp = []openrtb2.Imp{imp} + reqJSON, err := json.Marshal(requestCopy) + if err != nil { + errs = append(errs, err) + return nil, errs + } + + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + headers.Add("Accept", "application/json") + reqDatas = append(reqDatas, &adapters.RequestData{ + Method: "POST", + Uri: endpoint, + Body: reqJSON, + Headers: headers, + ImpIDs: openrtb_ext.GetImpIDs(requestCopy.Imp), + }) + } + + return reqDatas, errs +} + +func (a *adapter) MakeBids(bidReq *openrtb2.BidRequest, reqData *adapters.RequestData, respData *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if adapters.IsResponseStatusCodeNoContent(respData) { + return nil, nil + } + + if err := adapters.CheckResponseStatusCodeForErrors(respData); err != nil { + return nil, []error{err} + } + + var bidResp openrtb2.BidResponse + if err := jsonutil.Unmarshal(respData.Body, &bidResp); err != nil { + return nil, []error{err} + } + + // additional no content check + if len(bidResp.SeatBid) == 0 || len(bidResp.SeatBid[0].Bid) == 0 { + return nil, nil + } + + resp := adapters.NewBidderResponseWithBidsCapacity(len(bidResp.SeatBid[0].Bid)) + if len(bidResp.Cur) != 0 { + resp.Currency = bidResp.Cur + } + for _, sb := range bidResp.SeatBid { + for i := range sb.Bid { + bid := &sb.Bid[i] + bidType, err := getBidType(bid) + if err != nil { + return nil, []error{err} + } + resp.Bids = append(resp.Bids, &adapters.TypedBid{ + Bid: bid, + BidType: bidType, + }) + } + } + return resp, nil +} + +func (a *adapter) getEndpoint(ext *openrtb_ext.ExtImpMetaX) (string, error) { + params := macros.EndpointTemplateParams{ + PublisherID: strconv.Itoa(ext.PublisherID), + AdUnit: strconv.Itoa(ext.Adunit), + } + return macros.ResolveMacros(a.template, params) +} + +func parseBidderExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpMetaX, error) { + var bidderExt adapters.ExtImpBidder + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { + return nil, err + } + + var metaxExt openrtb_ext.ExtImpMetaX + if err := jsonutil.Unmarshal(bidderExt.Bidder, &metaxExt); err != nil { + return nil, errors.New("Wrong MetaX bidder ext") + } + + return &metaxExt, nil +} + +func preprocessImp(imp *openrtb2.Imp) error { + if imp == nil { + return errors.New("imp is nil") + } + + if imp.Banner != nil { + imp.Banner = assignBannerSize(imp.Banner) + } + + return nil +} + +func assignBannerSize(banner *openrtb2.Banner) *openrtb2.Banner { + if banner.W != nil && banner.H != nil { + return banner + } + + if len(banner.Format) == 0 { + return banner + } + + return assignBannerWidthAndHeight(banner, banner.Format[0].W, banner.Format[0].H) +} + +func assignBannerWidthAndHeight(banner *openrtb2.Banner, w, h int64) *openrtb2.Banner { + bannerCopy := *banner + bannerCopy.W = ptrutil.ToPtr(w) + bannerCopy.H = ptrutil.ToPtr(h) + return &bannerCopy +} + +func getBidType(bid *openrtb2.Bid) (openrtb_ext.BidType, error) { + switch bid.MType { + case openrtb2.MarkupBanner: + return openrtb_ext.BidTypeBanner, nil + case openrtb2.MarkupVideo: + return openrtb_ext.BidTypeVideo, nil + case openrtb2.MarkupNative: + return openrtb_ext.BidTypeNative, nil + case openrtb2.MarkupAudio: + return openrtb_ext.BidTypeAudio, nil + default: + return "", &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Unsupported MType %d", bid.MType), + } + } +} + +// Builder builds a new instance of the MetaX adapter for the given bidder with the given config. +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + if config.Endpoint == "" { + return nil, errors.New("endpoint is empty") + } + + templ, err := template.New("endpointTemplate").Parse(config.Endpoint) + if err != nil { + return nil, fmt.Errorf("unable to parse endpoint: %v", err) + } + + bidder := &adapter{ + template: templ, + } + return bidder, nil +} diff --git a/adapters/metax/metax_test.go b/adapters/metax/metax_test.go new file mode 100644 index 00000000000..cd1e39ad6c4 --- /dev/null +++ b/adapters/metax/metax_test.go @@ -0,0 +1,214 @@ +package metax + +import ( + "encoding/json" + "testing" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/ptrutil" + "github.com/stretchr/testify/assert" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder( + openrtb_ext.BidderMetaX, + config.Adapter{ + Endpoint: "https://hb.metaxads.com/prebid?sid={{.PublisherID}}&adunit={{.AdUnit}}&source=prebid-server", + }, + config.Server{ + ExternalUrl: "http://hosturl.com", + GvlID: 1301, + DataCenter: "2", + }, + ) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "metaxtest", bidder) +} + +func TestParseBidderExt(t *testing.T) { + data := ` +{ + "bidder": { + "publisherId": 1000, + "adunit": 200 + } +}` + imp := &openrtb2.Imp{ + Ext: json.RawMessage([]byte(data)), + } + metaxExt, err := parseBidderExt(imp) + assert.Nil(t, err) + assert.Equal(t, 1000, metaxExt.PublisherID) + assert.Equal(t, 200, metaxExt.Adunit) +} + +func TestPreprocessImp(t *testing.T) { + assert.NotNil(t, preprocessImp(nil)) + + imp1 := &openrtb2.Imp{ + Banner: &openrtb2.Banner{ + Format: []openrtb2.Format{ + {W: 300, H: 250}, + {W: 728, H: 90}, + }, + }, + } + err1 := preprocessImp(imp1) + assert.Nil(t, err1) + + imp2 := &openrtb2.Imp{ + Video: &openrtb2.Video{ + W: ptrutil.ToPtr(int64(1920)), + H: ptrutil.ToPtr(int64(1920)), + }, + } + err2 := preprocessImp(imp2) + assert.Nil(t, err2) +} + +func TestAssignBannerSize(t *testing.T) { + b1 := &openrtb2.Banner{ + Format: []openrtb2.Format{ + {W: 300, H: 250}, + {W: 728, H: 90}, + }, + } + b1n := assignBannerSize(b1) + assert.Equal(t, b1n.W, ptrutil.ToPtr(int64(300))) + assert.Equal(t, b1n.H, ptrutil.ToPtr(int64(250))) + assert.NotSame(t, b1, b1n) + + b2 := &openrtb2.Banner{ + Format: []openrtb2.Format{ + {W: 300, H: 250}, + {W: 728, H: 90}, + }, + W: ptrutil.ToPtr(int64(336)), + H: ptrutil.ToPtr(int64(280)), + } + b2n := assignBannerSize(b2) + assert.Equal(t, b2n.W, ptrutil.ToPtr(int64(336))) + assert.Equal(t, b2n.H, ptrutil.ToPtr(int64(280))) + assert.Same(t, b2, b2n) + + b3 := &openrtb2.Banner{ + W: ptrutil.ToPtr(int64(336)), + H: ptrutil.ToPtr(int64(280)), + } + b3n := assignBannerSize(b3) + assert.Equal(t, b3n.W, ptrutil.ToPtr(int64(336))) + assert.Equal(t, b3n.H, ptrutil.ToPtr(int64(280))) + assert.Same(t, b3, b3n) + + b4 := &openrtb2.Banner{ + Format: []openrtb2.Format{ + {W: 300, H: 250}, + {W: 728, H: 90}, + }, + W: ptrutil.ToPtr(int64(336)), + } + b4n := assignBannerSize(b4) + assert.Equal(t, b4n.W, ptrutil.ToPtr(int64(300))) + assert.Equal(t, b4n.H, ptrutil.ToPtr(int64(250))) + assert.NotSame(t, b4, b4n) + + b5 := &openrtb2.Banner{} + b5n := assignBannerSize(b5) + assert.Nil(t, b5n.W) + assert.Nil(t, b5n.H) + assert.Same(t, b5, b5n) +} + +func TestGetBidType(t *testing.T) { + tests := []struct { + bid *openrtb2.Bid + bidtype openrtb_ext.BidType + }{ + {&openrtb2.Bid{AdM: "", MType: openrtb2.MarkupBanner}, openrtb_ext.BidTypeBanner}, + {&openrtb2.Bid{AdM: "", MType: openrtb2.MarkupVideo}, openrtb_ext.BidTypeVideo}, + {&openrtb2.Bid{AdM: "", MType: openrtb2.MarkupNative}, openrtb_ext.BidTypeNative}, + {&openrtb2.Bid{AdM: "", MType: openrtb2.MarkupAudio}, openrtb_ext.BidTypeAudio}, + {&openrtb2.Bid{AdM: "", MType: 0}, ""}, + } + + for _, test := range tests { + bidType, err := getBidType(test.bid) + assert.Equal(t, test.bidtype, bidType) + if bidType == "" { + assert.NotNil(t, err) + } + } +} + +func TestBuilder(t *testing.T) { + serverCfg := config.Server{} + + cfg1 := config.Adapter{Endpoint: "https://hb.metaxads.com/prebid"} + builder1, err1 := Builder("test", cfg1, serverCfg) + assert.NotNil(t, builder1) + assert.Nil(t, err1) + + // empty endpoint + cfg2 := config.Adapter{Endpoint: ""} + builder2, err2 := Builder("test2", cfg2, serverCfg) + assert.Nil(t, builder2) + assert.NotNil(t, err2) + + // invalid endpoint + cfg3 := config.Adapter{Endpoint: "https://hb.metaxads.com/prebid?a={{}}"} + builder3, err3 := Builder("test3", cfg3, serverCfg) + assert.Nil(t, builder3) + assert.NotNil(t, err3) +} + +func TestMakeRequests(t *testing.T) { + builder1, _ := Builder("metax", config.Adapter{Endpoint: "https://hb.metaxads.com/prebid?sid={{.PublisherId}}"}, config.Server{}) + reqDatas1, err1 := builder1.MakeRequests(&openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + { + Ext: []byte(` + { + "bidder": { + "publisherId": 100, + "adunit": 2 + } + } + `), + }, + }, + Ext: []byte(`{invalid json}`), + }, &adapters.ExtraRequestInfo{}) + assert.Equal(t, 0, len(reqDatas1)) + assert.Equal(t, 1, len(err1)) + + builder2, _ := Builder( + "metax", + config.Adapter{Endpoint: "https://hb.metaxads.com/prebid?sid={{.PublisherID}}&adunit={{.AdUnit}}&source=prebid-server"}, + config.Server{}, + ) + reqDatas2, err2 := builder2.MakeRequests(&openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + { + Ext: []byte(` + { + "bidder": { + "publisherId": 100, + "adunit": 2 + } + } + `), + }, + }, + Ext: []byte(`{invalid json}`), + }, &adapters.ExtraRequestInfo{}) + assert.Equal(t, 0, len(reqDatas2)) + assert.Equal(t, 1, len(err2)) +} diff --git a/adapters/metax/metaxtest/exemplary/app-formats.json b/adapters/metax/metaxtest/exemplary/app-formats.json new file mode 100644 index 00000000000..013436f20bb --- /dev/null +++ b/adapters/metax/metaxtest/exemplary/app-formats.json @@ -0,0 +1,156 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "bundle": "com.prebid" + }, + "device": { + "ifa": "ec943cb9-61ec-460f-a925-6489c3fcc4e3" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 3, + 5, + 6 + ], + "w": 1024, + "h": 576 + }, + "native": { + "request": "{json string 1}", + "ver": "1.2" + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://hb.metaxads.com/prebid?sid=10000000&adunit=100000&source=prebid-server", + "body": { + "id": "test-request-id", + "app": { + "bundle": "com.prebid" + }, + "device": { + "ifa": "ec943cb9-61ec-460f-a925-6489c3fcc4e3" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ], + "w": 728, + "h": 90 + }, + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 3, + 5, + 6 + ], + "w": 1024, + "h": 576 + }, + "native": { + "request": "{json string 1}", + "ver": "1.2" + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + } + ] + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ] + }, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "metax", + "bid": [ + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "test-crid", + "w": 728, + "h": 90, + "mtype": 1 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "crid": "test-crid", + "w": 728, + "h": 90, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/metax/metaxtest/exemplary/app-imps.json b/adapters/metax/metaxtest/exemplary/app-imps.json new file mode 100644 index 00000000000..cc77a34baaf --- /dev/null +++ b/adapters/metax/metaxtest/exemplary/app-imps.json @@ -0,0 +1,351 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "bundle": "com.prebid" + }, + "device": { + "ifa": "ec943cb9-61ec-460f-a925-6489c3fcc4e3" + }, + "imp": [ + { + "id": "imp-1", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 3, + 5, + 6 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + }, + { + "id": "imp-2", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 3, + 5, + 6 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + }, + { + "id": "imp-3", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://hb.metaxads.com/prebid?sid=10000000&adunit=100000&source=prebid-server", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ] + }, + "body": { + "id": "test-request-id", + "app": { + "bundle": "com.prebid" + }, + "device": { + "ifa": "ec943cb9-61ec-460f-a925-6489c3fcc4e3" + }, + "imp": [ + { + "id": "imp-1", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 3, + 5, + 6 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + } + ] + }, + "impIDs": [ + "imp-1" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [ + { + "seat": "metax", + "bid": [ + { + "id": "bid-1", + "impid": "imp-1", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "test-crid", + "w": 1024, + "h": 576, + "mtype": 2 + } + ] + } + ] + } + } + }, + { + "expectedRequest": { + "uri": "https://hb.metaxads.com/prebid?sid=10000000&adunit=100000&source=prebid-server", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ] + }, + "body": { + "id": "test-request-id", + "app": { + "bundle": "com.prebid" + }, + "device": { + "ifa": "ec943cb9-61ec-460f-a925-6489c3fcc4e3" + }, + "imp": [ + { + "id": "imp-2", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 3, + 5, + 6 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + } + ] + }, + "impIDs": [ + "imp-2" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [ + { + "seat": "metax", + "bid": [ + { + "id": "bid-2", + "impid": "imp-2", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "test-crid", + "w": 1024, + "h": 576, + "mtype": 2 + } + ] + } + ] + } + } + }, + { + "expectedRequest": { + "uri": "https://hb.metaxads.com/prebid?sid=10000000&adunit=100000&source=prebid-server", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ] + }, + "body": { + "id": "test-request-id", + "app": { + "bundle": "com.prebid" + }, + "device": { + "ifa": "ec943cb9-61ec-460f-a925-6489c3fcc4e3" + }, + "imp": [ + { + "id": "imp-3", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ], + "w": 728, + "h": 90 + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + } + ] + }, + "impIDs": [ + "imp-3" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [ + { + "seat": "metax", + "bid": [ + { + "id": "bid-3", + "impid": "imp-3", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "test-crid", + "w": 728, + "h": 90, + "mtype": 1 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "bid-1", + "impid": "imp-1", + "price": 0.5, + "adm": "some-test-ad", + "crid": "test-crid", + "w": 1024, + "h": 576, + "mtype": 2 + }, + "type": "video" + } + ] + }, + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "bid-2", + "impid": "imp-2", + "price": 0.5, + "adm": "some-test-ad", + "crid": "test-crid", + "w": 1024, + "h": 576, + "mtype": 2 + }, + "type": "video" + } + ] + }, + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "bid-3", + "impid": "imp-3", + "price": 0.5, + "adm": "some-test-ad", + "crid": "test-crid", + "w": 728, + "h": 90, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} + + + diff --git a/adapters/metax/metaxtest/exemplary/no-bid.json b/adapters/metax/metaxtest/exemplary/no-bid.json new file mode 100644 index 00000000000..3eb1b79a2eb --- /dev/null +++ b/adapters/metax/metaxtest/exemplary/no-bid.json @@ -0,0 +1,92 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "bundle": "com.prebid" + }, + "device": { + "ifa": "ec943cb9-61ec-460f-a925-6489c3fcc4e3" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 3, + 5, + 6 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://hb.metaxads.com/prebid?sid=10000000&adunit=100000&source=prebid-server", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ] + }, + "body": { + "id": "test-request-id", + "app": { + "bundle": "com.prebid" + }, + "device": { + "ifa": "ec943cb9-61ec-460f-a925-6489c3fcc4e3" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 3, + 5, + 6 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + } + ] + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 204, + "body": { + } + } + } + ], + "expectedBidResponses": [] +} diff --git a/adapters/metax/metaxtest/exemplary/no-seat-bid.json b/adapters/metax/metaxtest/exemplary/no-seat-bid.json new file mode 100644 index 00000000000..fe166b1b634 --- /dev/null +++ b/adapters/metax/metaxtest/exemplary/no-seat-bid.json @@ -0,0 +1,99 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "bundle": "com.prebid" + }, + "device": { + "ifa": "ec943cb9-61ec-460f-a925-6489c3fcc4e3" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 3, + 5, + 6 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://hb.metaxads.com/prebid?sid=10000000&adunit=100000&source=prebid-server", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ] + }, + "body": { + "id": "test-request-id", + "app": { + "bundle": "com.prebid" + }, + "device": { + "ifa": "ec943cb9-61ec-460f-a925-6489c3fcc4e3" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 3, + 5, + 6 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + } + ] + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "metax", + "bid": [] + } + ] + } + } + } + ], + "expectedBidResponses": [] +} \ No newline at end of file diff --git a/adapters/metax/metaxtest/exemplary/no-seat.json b/adapters/metax/metaxtest/exemplary/no-seat.json new file mode 100644 index 00000000000..ea83df7f83a --- /dev/null +++ b/adapters/metax/metaxtest/exemplary/no-seat.json @@ -0,0 +1,94 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "bundle": "com.prebid" + }, + "device": { + "ifa": "ec943cb9-61ec-460f-a925-6489c3fcc4e3" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 3, + 5, + 6 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://hb.metaxads.com/prebid?sid=10000000&adunit=100000&source=prebid-server", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ] + }, + "body": { + "id": "test-request-id", + "app": { + "bundle": "com.prebid" + }, + "device": { + "ifa": "ec943cb9-61ec-460f-a925-6489c3fcc4e3" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 3, + 5, + 6 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + } + ] + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [] + } + } + } + ], + "expectedBidResponses": [] +} \ No newline at end of file diff --git a/adapters/metax/metaxtest/exemplary/simple-app-audio.json b/adapters/metax/metaxtest/exemplary/simple-app-audio.json new file mode 100644 index 00000000000..5bd6a102fb7 --- /dev/null +++ b/adapters/metax/metaxtest/exemplary/simple-app-audio.json @@ -0,0 +1,110 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "bundle": "com.prebid" + }, + "device": { + "ifa": "ec943cb9-61ec-460f-a925-6489c3fcc4e3" + }, + "imp": [ + { + "id": "test-imp-id", + "audio": { + "mimes": [ + "audio/mp4" + ], + "protocols": [ + 9, + 10 + ] + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://hb.metaxads.com/prebid?sid=10000000&adunit=100000&source=prebid-server", + "body": { + "id": "test-request-id", + "app": { + "bundle": "com.prebid" + }, + "device": { + "ifa": "ec943cb9-61ec-460f-a925-6489c3fcc4e3" + }, + "imp": [ + { + "id": "test-imp-id", + "audio": { + "mimes": [ + "audio/mp4" + ], + "protocols": [ + 9, + 10 + ] + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + } + ] + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "metax", + "bid": [ + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "test-crid", + "mtype": 3 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "crid": "test-crid", + "mtype": 3 + }, + "type": "audio" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/metax/metaxtest/exemplary/simple-app-banner.json b/adapters/metax/metaxtest/exemplary/simple-app-banner.json new file mode 100644 index 00000000000..329e00a2f59 --- /dev/null +++ b/adapters/metax/metaxtest/exemplary/simple-app-banner.json @@ -0,0 +1,122 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "bundle": "com.prebid" + }, + "device": { + "ifa": "ec943cb9-61ec-460f-a925-6489c3fcc4e3" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://hb.metaxads.com/prebid?sid=10000000&adunit=100000&source=prebid-server", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ] + }, + "body": { + "id": "test-request-id", + "app": { + "bundle": "com.prebid" + }, + "device": { + "ifa": "ec943cb9-61ec-460f-a925-6489c3fcc4e3" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ], + "w": 728, + "h": 90 + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + } + ] + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "metax", + "bid": [ + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "test-crid", + "w": 728, + "h": 90, + "mtype": 1 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "crid": "test-crid", + "w": 728, + "h": 90, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/metax/metaxtest/exemplary/simple-app-native.json b/adapters/metax/metaxtest/exemplary/simple-app-native.json new file mode 100644 index 00000000000..52b4305ad70 --- /dev/null +++ b/adapters/metax/metaxtest/exemplary/simple-app-native.json @@ -0,0 +1,99 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "bundle": "com.prebid" + }, + "device": { + "ifa": "ec943cb9-61ec-460f-a925-6489c3fcc4e3" + }, + "imp": [ + { + "id": "test-imp-id", + "native": { + "request": "{\"ver\":\"1.2\",\"context\":2,\"contextsubtype\":20,\"plcmttype\":11,\"plcmtcnt\":1,\"aurlsupport\":1,\"durlsupport\":1,\"assets\":[{\"id\":123,\"required\":1,\"title\":{\"len\":140}},{\"id\":128,\"required\":0,\"img\":{\"wmin\":836,\"hmin\":627,\"type\":3}}]}" + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + } + ] + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://hb.metaxads.com/prebid?sid=10000000&adunit=100000&source=prebid-server", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ] + }, + "body": { + "id": "test-request-id", + "app": { + "bundle": "com.prebid" + }, + "device": { + "ifa": "ec943cb9-61ec-460f-a925-6489c3fcc4e3" + }, + "imp": [ + { + "id": "test-imp-id", + "native": { + "request": "{\"ver\":\"1.2\",\"context\":2,\"contextsubtype\":20,\"plcmttype\":11,\"plcmtcnt\":1,\"aurlsupport\":1,\"durlsupport\":1,\"assets\":[{\"id\":123,\"required\":1,\"title\":{\"len\":140}},{\"id\":128,\"required\":0,\"img\":{\"wmin\":836,\"hmin\":627,\"type\":3}}]}" + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + } + ] + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "native-json", + "crid": "test-crid", + "mtype": 4 + } + ] + } + ] + } + } + }], + + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "native-json", + "crid": "test-crid", + "mtype": 4 + }, + "type": "native" + }] + }] +} diff --git a/adapters/metax/metaxtest/exemplary/simple-app-video.json b/adapters/metax/metaxtest/exemplary/simple-app-video.json new file mode 100644 index 00000000000..4f4272ee3db --- /dev/null +++ b/adapters/metax/metaxtest/exemplary/simple-app-video.json @@ -0,0 +1,130 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "bundle": "com.prebid" + }, + "device": { + "ifa": "ec943cb9-61ec-460f-a925-6489c3fcc4e3" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 3, + 5, + 6 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://hb.metaxads.com/prebid?sid=10000000&adunit=100000&source=prebid-server", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ] + }, + "body": { + "id": "test-request-id", + "app": { + "bundle": "com.prebid" + }, + "device": { + "ifa": "ec943cb9-61ec-460f-a925-6489c3fcc4e3" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 3, + 5, + 6 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + } + ] + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [ + { + "seat": "metax", + "bid": [ + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "test-crid", + "w": 1024, + "h": 576, + "mtype": 2 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "crid": "test-crid", + "w": 1024, + "h": 576, + "mtype": 2 + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/metax/metaxtest/exemplary/simple-site-audio.json b/adapters/metax/metaxtest/exemplary/simple-site-audio.json new file mode 100644 index 00000000000..ebc240ec9f4 --- /dev/null +++ b/adapters/metax/metaxtest/exemplary/simple-site-audio.json @@ -0,0 +1,110 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "prebid.org" + }, + "user": { + "buyeruid": "be5e209ad46927520000000000000000" + }, + "imp": [ + { + "id": "test-imp-id", + "audio": { + "mimes": [ + "audio/mp4" + ], + "protocols": [ + 9, + 10 + ] + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://hb.metaxads.com/prebid?sid=10000000&adunit=100000&source=prebid-server", + "body": { + "id": "test-request-id", + "site": { + "page": "prebid.org" + }, + "user": { + "buyeruid": "be5e209ad46927520000000000000000" + }, + "imp": [ + { + "id": "test-imp-id", + "audio": { + "mimes": [ + "audio/mp4" + ], + "protocols": [ + 9, + 10 + ] + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + } + ] + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "metax", + "bid": [ + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "test-crid", + "mtype": 3 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "crid": "test-crid", + "mtype": 3 + }, + "type": "audio" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/metax/metaxtest/exemplary/simple-site-banner.json b/adapters/metax/metaxtest/exemplary/simple-site-banner.json new file mode 100644 index 00000000000..cc631fac8a7 --- /dev/null +++ b/adapters/metax/metaxtest/exemplary/simple-site-banner.json @@ -0,0 +1,122 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "prebid.org" + }, + "user": { + "buyeruid": "be5e209ad46927520000000000000000" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://hb.metaxads.com/prebid?sid=10000000&adunit=100000&source=prebid-server", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ] + }, + "body": { + "id": "test-request-id", + "site": { + "page": "prebid.org" + }, + "user": { + "buyeruid": "be5e209ad46927520000000000000000" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ], + "w": 728, + "h": 90 + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + } + ] + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "metax", + "bid": [ + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "test-crid", + "w": 728, + "h": 90, + "mtype": 1 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "crid": "test-crid", + "w": 728, + "h": 90, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/metax/metaxtest/exemplary/simple-site-native.json b/adapters/metax/metaxtest/exemplary/simple-site-native.json new file mode 100644 index 00000000000..5955b1b86af --- /dev/null +++ b/adapters/metax/metaxtest/exemplary/simple-site-native.json @@ -0,0 +1,99 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "prebid.org" + }, + "user": { + "buyeruid": "be5e209ad46927520000000000000000" + }, + "imp": [ + { + "id": "test-imp-id", + "native": { + "request": "{\"ver\":\"1.2\",\"context\":2,\"contextsubtype\":20,\"plcmttype\":11,\"plcmtcnt\":1,\"aurlsupport\":1,\"durlsupport\":1,\"assets\":[{\"id\":123,\"required\":1,\"title\":{\"len\":140}},{\"id\":128,\"required\":0,\"img\":{\"wmin\":836,\"hmin\":627,\"type\":3}}]}" + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + } + ] + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://hb.metaxads.com/prebid?sid=10000000&adunit=100000&source=prebid-server", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ] + }, + "body": { + "id": "test-request-id", + "site": { + "page": "prebid.org" + }, + "user": { + "buyeruid": "be5e209ad46927520000000000000000" + }, + "imp": [ + { + "id": "test-imp-id", + "native": { + "request": "{\"ver\":\"1.2\",\"context\":2,\"contextsubtype\":20,\"plcmttype\":11,\"plcmtcnt\":1,\"aurlsupport\":1,\"durlsupport\":1,\"assets\":[{\"id\":123,\"required\":1,\"title\":{\"len\":140}},{\"id\":128,\"required\":0,\"img\":{\"wmin\":836,\"hmin\":627,\"type\":3}}]}" + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + } + ] + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "native-json", + "crid": "test-crid", + "mtype": 4 + } + ] + } + ] + } + } + }], + + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "native-json", + "crid": "test-crid", + "mtype": 4 + }, + "type": "native" + }] + }] +} diff --git a/adapters/metax/metaxtest/exemplary/simple-site-video.json b/adapters/metax/metaxtest/exemplary/simple-site-video.json new file mode 100644 index 00000000000..d6084603a0e --- /dev/null +++ b/adapters/metax/metaxtest/exemplary/simple-site-video.json @@ -0,0 +1,130 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "prebid.org" + }, + "user": { + "buyeruid": "be5e209ad46927520000000000000000" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 3, + 5, + 6 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://hb.metaxads.com/prebid?sid=10000000&adunit=100000&source=prebid-server", + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ] + }, + "body": { + "id": "test-request-id", + "site": { + "page": "prebid.org" + }, + "user": { + "buyeruid": "be5e209ad46927520000000000000000" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 3, + 5, + 6 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + } + ] + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [ + { + "seat": "metax", + "bid": [ + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "test-crid", + "w": 1024, + "h": 576, + "mtype": 2 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "crid": "test-crid", + "w": 1024, + "h": 576, + "mtype": 2 + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/metax/metaxtest/supplemental/invalid-adunit-error.json b/adapters/metax/metaxtest/supplemental/invalid-adunit-error.json new file mode 100644 index 00000000000..35ce462a422 --- /dev/null +++ b/adapters/metax/metaxtest/supplemental/invalid-adunit-error.json @@ -0,0 +1,35 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": "abc" + } + } + } + ], + "app": { + "bundle": "com.prebid" + }, + "device": { + "ifa": "ec943cb9-61ec-460f-a925-6489c3fcc4e3" + } + }, + "expectedMakeRequestsErrors": [ + { + "value": "Wrong MetaX bidder ext", + "comparison": "literal" + } + ] +} diff --git a/adapters/metax/metaxtest/supplemental/invalid-ext-bidder.json b/adapters/metax/metaxtest/supplemental/invalid-ext-bidder.json new file mode 100644 index 00000000000..7016e7dc08e --- /dev/null +++ b/adapters/metax/metaxtest/supplemental/invalid-ext-bidder.json @@ -0,0 +1,32 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": "bad string" + } + } + ], + "app": { + "bundle": "com.prebid" + }, + "device": { + "ifa": "ec943cb9-61ec-460f-a925-6489c3fcc4e3" + } + }, + "expectedMakeRequestsErrors": [ + { + "value": "Wrong MetaX bidder ext", + "comparison": "literal" + } + ] +} diff --git a/adapters/metax/metaxtest/supplemental/invalid-ext.json b/adapters/metax/metaxtest/supplemental/invalid-ext.json new file mode 100644 index 00000000000..7386b9ba62e --- /dev/null +++ b/adapters/metax/metaxtest/supplemental/invalid-ext.json @@ -0,0 +1,30 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": "" + } + ], + "app": { + "bundle": "com.prebid" + }, + "device": { + "ifa": "ec943cb9-61ec-460f-a925-6489c3fcc4e3" + } + }, + "expectedMakeRequestsErrors": [ + { + "value": "expect { or n, but found \"", + "comparison": "literal" + } + ] +} diff --git a/adapters/metax/metaxtest/supplemental/invalid-publisher-error.json b/adapters/metax/metaxtest/supplemental/invalid-publisher-error.json new file mode 100644 index 00000000000..2a16200f1c1 --- /dev/null +++ b/adapters/metax/metaxtest/supplemental/invalid-publisher-error.json @@ -0,0 +1,35 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "publisherId": "abc", + "adunit": 100000 + } + } + } + ], + "app": { + "bundle": "com.prebid" + }, + "device": { + "ifa": "ec943cb9-61ec-460f-a925-6489c3fcc4e3" + } + }, + "expectedMakeRequestsErrors": [ + { + "value": "Wrong MetaX bidder ext", + "comparison": "literal" + } + ] +} diff --git a/adapters/metax/metaxtest/supplemental/resp-bad-json.json b/adapters/metax/metaxtest/supplemental/resp-bad-json.json new file mode 100644 index 00000000000..5879dad6cab --- /dev/null +++ b/adapters/metax/metaxtest/supplemental/resp-bad-json.json @@ -0,0 +1,80 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "prebid.org" + }, + "user": { + "buyeruid": "be5e209ad46927520000000000000000" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://hb.metaxads.com/prebid?sid=10000000&adunit=100000&source=prebid-server", + "body": { + "id": "test-request-id", + "site": { + "page": "prebid.org" + }, + "user": { + "buyeruid": "be5e209ad46927520000000000000000" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ], + "w": 728, + "h": 90 + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + } + ] + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": "this is not a valid json" + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "expect { or n, but found \"", + "comparison": "literal" + } + ] +} diff --git a/adapters/metax/metaxtest/supplemental/resp-bad-markuptype.json b/adapters/metax/metaxtest/supplemental/resp-bad-markuptype.json new file mode 100644 index 00000000000..dae139bd452 --- /dev/null +++ b/adapters/metax/metaxtest/supplemental/resp-bad-markuptype.json @@ -0,0 +1,100 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "prebid.org" + }, + "user": { + "buyeruid": "be5e209ad46927520000000000000000" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://hb.metaxads.com/prebid?sid=10000000&adunit=100000&source=prebid-server", + "body": { + "id": "test-request-id", + "site": { + "page": "prebid.org" + }, + "user": { + "buyeruid": "be5e209ad46927520000000000000000" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ], + "w": 728, + "h": 90 + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + } + ] + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "metax", + "bid": [ + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "test-crid", + "w": 728, + "h": 90, + "mtype": 0 + } + ] + } + ], + "cur": "USD" + } + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unsupported MType 0", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/metax/metaxtest/supplemental/status-400.json b/adapters/metax/metaxtest/supplemental/status-400.json new file mode 100644 index 00000000000..63a86a5388b --- /dev/null +++ b/adapters/metax/metaxtest/supplemental/status-400.json @@ -0,0 +1,80 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "prebid.org" + }, + "user": { + "buyeruid": "be5e209ad46927520000000000000000" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://hb.metaxads.com/prebid?sid=10000000&adunit=100000&source=prebid-server", + "body": { + "id": "test-request-id", + "site": { + "page": "prebid.org" + }, + "user": { + "buyeruid": "be5e209ad46927520000000000000000" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ], + "w": 728, + "h": 90 + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + } + ] + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 400, + "body": "invalid params" + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} diff --git a/adapters/metax/metaxtest/supplemental/status-500.json b/adapters/metax/metaxtest/supplemental/status-500.json new file mode 100644 index 00000000000..79841569eb4 --- /dev/null +++ b/adapters/metax/metaxtest/supplemental/status-500.json @@ -0,0 +1,80 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "prebid.org" + }, + "user": { + "buyeruid": "be5e209ad46927520000000000000000" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://hb.metaxads.com/prebid?sid=10000000&adunit=100000&source=prebid-server", + "body": { + "id": "test-request-id", + "site": { + "page": "prebid.org" + }, + "user": { + "buyeruid": "be5e209ad46927520000000000000000" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ], + "w": 728, + "h": 90 + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + } + ] + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 500, + "body": "Internal Server Error" + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 500. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/metax/metaxtest/supplemental/status-503.json b/adapters/metax/metaxtest/supplemental/status-503.json new file mode 100644 index 00000000000..3c8220ee598 --- /dev/null +++ b/adapters/metax/metaxtest/supplemental/status-503.json @@ -0,0 +1,80 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "prebid.org" + }, + "user": { + "buyeruid": "be5e209ad46927520000000000000000" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ] + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://hb.metaxads.com/prebid?sid=10000000&adunit=100000&source=prebid-server", + "body": { + "id": "test-request-id", + "site": { + "page": "prebid.org" + }, + "user": { + "buyeruid": "be5e209ad46927520000000000000000" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 728, + "h": 90 + } + ], + "w": 728, + "h": 90 + }, + "ext": { + "bidder": { + "publisherId": 10000000, + "adunit": 100000 + } + } + } + ] + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 503, + "body": "" + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 503. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/metax/params_test.go b/adapters/metax/params_test.go new file mode 100644 index 00000000000..4487c23326c --- /dev/null +++ b/adapters/metax/params_test.go @@ -0,0 +1,60 @@ +package metax + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v3/openrtb_ext" +) + +// This file actually intends to test static/bidder-params/metax.json +// +// These also validate the format of the external API: request.imp[i].ext.prebid.bidder.metax + +// TestValidParams makes sure that the metax schema accepts all imp.ext fields which we intend to support. +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schemas. %v", err) + } + + for _, validParam := range validParams { + if err := validator.Validate(openrtb_ext.BidderMetaX, json.RawMessage(validParam)); err != nil { + t.Errorf("Schema rejected metax params: %s", validParam) + } + } +} + +// TestInvalidParams makes sure that the metax schema rejects all the imp.ext fields we don't support. +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schemas. %v", err) + } + + for _, invalidParam := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderMetaX, json.RawMessage(invalidParam)); err == nil { + t.Errorf("Schema allowed unexpected params: %s", invalidParam) + } + } +} + +var validParams = []string{ + `{"publisherId": 10000000, "adunit": 100000}`, +} + +var invalidParams = []string{ + ``, + `null`, + `undefined`, + `0`, + `{}`, + `[]`, + `{"publisherId": ""}`, + `{"adunit": ""}`, + `{"publisherId": "", "adunit": ""}`, + `{"publisherId": "10000000", "adunit": "100000"}`, + `{"publisherId": 0, "adunit": 0}`, + `{"publisherId": 10000000, "adunit": 0}`, + `{"publisherId": 0, "adunit": 100000}`, +} diff --git a/adapters/mgid/mgid.go b/adapters/mgid/mgid.go index 93398905da1..68a760a7f52 100644 --- a/adapters/mgid/mgid.go +++ b/adapters/mgid/mgid.go @@ -7,10 +7,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type MgidAdapter struct { @@ -74,7 +75,7 @@ func preprocess(request *openrtb2.BidRequest) (path string, err error) { var imp = request.Imp[i] var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return "", &errortypes.BadInput{ Message: err.Error(), } @@ -82,7 +83,7 @@ func preprocess(request *openrtb2.BidRequest) (path string, err error) { var mgidExt openrtb_ext.ExtImpMgid - if err := json.Unmarshal(bidderExt.Bidder, &mgidExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &mgidExt); err != nil { return "", &errortypes.BadInput{ Message: err.Error(), } @@ -143,7 +144,7 @@ func (a *MgidAdapter) MakeBids(bidReq *openrtb2.BidRequest, unused *adapters.Req var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } @@ -156,7 +157,7 @@ func (a *MgidAdapter) MakeBids(bidReq *openrtb2.BidRequest, unused *adapters.Req bidType := openrtb_ext.BidTypeBanner if len(sb.Bid[i].Ext) > 0 && bytes.Contains(sb.Bid[i].Ext, []byte("crtype")) { ext := RespBidExt{} - if err := json.Unmarshal(sb.Bid[i].Ext, &ext); err == nil && len(ext.CreativeType) > 0 { + if err := jsonutil.Unmarshal(sb.Bid[i].Ext, &ext); err == nil && len(ext.CreativeType) > 0 { bidType = ext.CreativeType } } diff --git a/adapters/mgid/mgid_test.go b/adapters/mgid/mgid_test.go index 21311f5477d..7dc7018b577 100644 --- a/adapters/mgid/mgid_test.go +++ b/adapters/mgid/mgid_test.go @@ -3,9 +3,9 @@ package mgid import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/mgidX/mgidX.go b/adapters/mgidX/mgidX.go index 6e6a3427fca..f952fc27ff0 100644 --- a/adapters/mgidX/mgidX.go +++ b/adapters/mgidX/mgidX.go @@ -7,9 +7,10 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -44,10 +45,10 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E var bidderExt adapters.ExtImpBidder var mgidXExt openrtb_ext.ImpExtMgidX - if err = json.Unmarshal(reqCopy.Imp[0].Ext, &bidderExt); err != nil { + if err = jsonutil.Unmarshal(reqCopy.Imp[0].Ext, &bidderExt); err != nil { return nil, []error{err} } - if err = json.Unmarshal(bidderExt.Bidder, &mgidXExt); err != nil { + if err = jsonutil.Unmarshal(bidderExt.Bidder, &mgidXExt); err != nil { return nil, []error{err} } @@ -115,7 +116,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } @@ -146,7 +147,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R func getBidMediaType(bid *openrtb2.Bid) (openrtb_ext.BidType, error) { var extBid openrtb_ext.ExtBid - err := json.Unmarshal(bid.Ext, &extBid) + err := jsonutil.Unmarshal(bid.Ext, &extBid) if err != nil { return "", fmt.Errorf("unable to deserialize imp %v bid.ext", bid.ImpID) } diff --git a/adapters/mgidX/mgidX_test.go b/adapters/mgidX/mgidX_test.go index 7ff4eb93627..90ea5c79042 100644 --- a/adapters/mgidX/mgidX_test.go +++ b/adapters/mgidX/mgidX_test.go @@ -3,9 +3,9 @@ package mgidX import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/mgidX/mgidXtest/supplemental/bad_response.json b/adapters/mgidX/mgidXtest/supplemental/bad_response.json index c732ba92c67..5cc4a338ac3 100644 --- a/adapters/mgidX/mgidXtest/supplemental/bad_response.json +++ b/adapters/mgidX/mgidXtest/supplemental/bad_response.json @@ -78,7 +78,7 @@ }], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/mgidX/params_test.go b/adapters/mgidX/params_test.go index b3d80207811..c5246fba4b9 100644 --- a/adapters/mgidX/params_test.go +++ b/adapters/mgidX/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/minutemedia/minutemedia.go b/adapters/minutemedia/minutemedia.go index 796f9ec6e6b..37bb9148312 100644 --- a/adapters/minutemedia/minutemedia.go +++ b/adapters/minutemedia/minutemedia.go @@ -10,10 +10,11 @@ import ( "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) // adapter is a MinuteMedia implementation of the adapters.Bidder interface. @@ -62,7 +63,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, _ *adapters.RequestData } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } @@ -96,12 +97,12 @@ func extractOrg(openRTBRequest *openrtb2.BidRequest) (string, error) { } var bidderExt adapters.ExtImpBidder - if err = json.Unmarshal(openRTBRequest.Imp[0].Ext, &bidderExt); err != nil { + if err = jsonutil.Unmarshal(openRTBRequest.Imp[0].Ext, &bidderExt); err != nil { return "", fmt.Errorf("failed to unmarshal bidderExt: %w", err) } var impExt openrtb_ext.ImpExtMinuteMedia - if err = json.Unmarshal(bidderExt.Bidder, &impExt); err != nil { + if err = jsonutil.Unmarshal(bidderExt.Bidder, &impExt); err != nil { return "", fmt.Errorf("failed to unmarshal ImpExtMinuteMedia: %w", err) } diff --git a/adapters/minutemedia/minutemedia_test.go b/adapters/minutemedia/minutemedia_test.go index 5ab59773ff7..aa3ce56ca29 100644 --- a/adapters/minutemedia/minutemedia_test.go +++ b/adapters/minutemedia/minutemedia_test.go @@ -3,9 +3,9 @@ package minutemedia import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) const testsDir = "minutemediatest" diff --git a/adapters/minutemedia/minutemediatest/supplemental/missing-bidder.json b/adapters/minutemedia/minutemediatest/supplemental/missing-bidder.json index c5724e88738..6ed87bbf7ec 100644 --- a/adapters/minutemedia/minutemediatest/supplemental/missing-bidder.json +++ b/adapters/minutemedia/minutemediatest/supplemental/missing-bidder.json @@ -41,8 +41,8 @@ }, "expectedMakeRequestsErrors": [ { - "value": "failed to extract org: failed to unmarshal ImpExtMinuteMedia: unexpected end of JSON input", - "comparison": "literal" + "value": "failed to extract org: failed to unmarshal ImpExtMinuteMedia: expect { or n, but found", + "comparison": "startswith" } ] } diff --git a/adapters/minutemedia/minutemediatest/supplemental/missing-extension.json b/adapters/minutemedia/minutemediatest/supplemental/missing-extension.json index bd0f87c3e59..02783e0b2d3 100644 --- a/adapters/minutemedia/minutemediatest/supplemental/missing-extension.json +++ b/adapters/minutemedia/minutemediatest/supplemental/missing-extension.json @@ -40,8 +40,8 @@ }, "expectedMakeRequestsErrors": [ { - "value": "failed to extract org: failed to unmarshal bidderExt: unexpected end of JSON input", - "comparison": "literal" + "value": "failed to extract org: failed to unmarshal bidderExt: expect { or n, but found", + "comparison": "startswith" } ] } diff --git a/adapters/missena/missena.go b/adapters/missena/missena.go new file mode 100644 index 00000000000..6068cf21897 --- /dev/null +++ b/adapters/missena/missena.go @@ -0,0 +1,216 @@ +package missena + +import ( + "encoding/json" + "fmt" + "net/http" + "text/template" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" +) + +type adapter struct { + endpoint string +} + +type MissenaAdRequest struct { + RequestId string `json:"request_id"` + Timeout int `json:"timeout"` + Referer string `json:"referer"` + RefererCanonical string `json:"referer_canonical"` + GDPRConsent string `json:"consent_string"` + GDPR bool `json:"consent_required"` + Placement string `json:"placement"` + TestMode string `json:"test"` +} + +type MissenaBidServerResponse struct { + Ad string `json:"ad"` + Cpm float64 `json:"cpm"` + Currency string `json:"currency"` + RequestId string `json:"requestId"` +} + +type MissenaInternalParams struct { + ApiKey string + RequestId string + Timeout int + Referer string + RefererCanonical string + GDPRConsent string + GDPR bool + Placement string + TestMode string +} + +type MissenaAdapter struct { + EndpointTemplate *template.Template +} + +// Builder builds a new instance of the Foo adapter for the given bidder with the given config. +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + bidder := &adapter{ + endpoint: config.Endpoint, + } + return bidder, nil +} + +func (a *adapter) makeRequest(missenaParams MissenaInternalParams, reqInfo *adapters.ExtraRequestInfo, impID string, request *openrtb2.BidRequest) (*adapters.RequestData, error) { + url := a.endpoint + "?t=" + missenaParams.ApiKey + + missenaRequest := MissenaAdRequest{ + RequestId: request.ID, + Timeout: 2000, + Referer: request.Site.Page, + RefererCanonical: request.Site.Domain, + GDPRConsent: missenaParams.GDPRConsent, + GDPR: missenaParams.GDPR, + Placement: missenaParams.Placement, + TestMode: missenaParams.TestMode, + } + + body, errm := json.Marshal(missenaRequest) + if errm != nil { + return nil, errm + } + + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + headers.Add("Accept", "application/json") + + if request.Device != nil { + headers.Add("User-Agent", request.Device.UA) + if request.Device.IP != "" { + headers.Add("X-Forwarded-For", request.Device.IP) + } else if request.Device.IPv6 != "" { + headers.Add("X-Forwarded-For", request.Device.IPv6) + } + } + if request.Site != nil { + headers.Add("Referer", request.Site.Page) + } + + return &adapters.RequestData{ + Method: "POST", + Uri: url, + Headers: headers, + Body: body, + ImpIDs: []string{impID}, + }, nil +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + + var httpRequests []*adapters.RequestData + var errors []error + gdprApplies, consentString := readGDPR(request) + + missenaInternalParams := MissenaInternalParams{ + GDPR: gdprApplies, + GDPRConsent: consentString, + } + + for _, imp := range request.Imp { + var bidderExt adapters.ExtImpBidder + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { + errors = append(errors, &errortypes.BadInput{ + Message: "Error parsing bidderExt object", + }) + continue + } + + var missenaExt openrtb_ext.ExtImpMissena + if err := jsonutil.Unmarshal(bidderExt.Bidder, &missenaExt); err != nil { + errors = append(errors, &errortypes.BadInput{ + Message: "Error parsing missenaExt parameters", + }) + continue + } + + missenaInternalParams.ApiKey = missenaExt.ApiKey + missenaInternalParams.Placement = missenaExt.Placement + missenaInternalParams.TestMode = missenaExt.TestMode + + newHttpRequest, err := a.makeRequest(missenaInternalParams, requestInfo, imp.ID, request) + if err != nil { + errors = append(errors, err) + continue + } + + httpRequests = append(httpRequests, newHttpRequest) + + break + } + + return httpRequests, errors +} + +func readGDPR(request *openrtb2.BidRequest) (bool, string) { + consentString := "" + if request.User != nil { + var extUser openrtb_ext.ExtUser + if err := jsonutil.Unmarshal(request.User.Ext, &extUser); err == nil { + consentString = extUser.Consent + } + } + gdprApplies := false + var extRegs openrtb_ext.ExtRegs + if request.Regs != nil { + if err := jsonutil.Unmarshal(request.Regs.Ext, &extRegs); err == nil { + if extRegs.GDPR != nil { + gdprApplies = (*extRegs.GDPR == 1) + } + } + } + return gdprApplies, consentString +} + +func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if responseData.StatusCode == http.StatusNoContent { + return nil, nil + } + + if responseData.StatusCode == http.StatusBadRequest { + err := &errortypes.BadInput{ + Message: "Unexpected status code: 400. Bad request from publisher. Run with request.debug = 1 for more info.", + } + return nil, []error{err} + } + + if responseData.StatusCode != http.StatusOK { + err := &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info.", responseData.StatusCode), + } + return nil, []error{err} + } + + var missenaResponse MissenaBidServerResponse + if err := jsonutil.Unmarshal(responseData.Body, &missenaResponse); err != nil { + return nil, []error{err} + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(1) + bidResponse.Currency = missenaResponse.Currency + + responseBid := &openrtb2.Bid{ + ID: request.ID, + Price: float64(missenaResponse.Cpm), + ImpID: request.Imp[0].ID, + AdM: missenaResponse.Ad, + CrID: missenaResponse.RequestId, + } + + b := &adapters.TypedBid{ + Bid: responseBid, + BidType: openrtb_ext.BidTypeBanner, + } + + bidResponse.Bids = append(bidResponse.Bids, b) + + return bidResponse, nil +} diff --git a/adapters/missena/missena_test.go b/adapters/missena/missena_test.go new file mode 100644 index 00000000000..e388eb357cd --- /dev/null +++ b/adapters/missena/missena_test.go @@ -0,0 +1,21 @@ +package missena + +import ( + "testing" + + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderMissena, config.Adapter{ + Endpoint: "http://example.com/"}, + config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "missenatest", bidder) +} diff --git a/adapters/missena/missenatest/exemplary/multiple-imps.json b/adapters/missena/missenatest/exemplary/multiple-imps.json new file mode 100644 index 00000000000..5b83f19ccd0 --- /dev/null +++ b/adapters/missena/missenatest/exemplary/multiple-imps.json @@ -0,0 +1,129 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "tmax": 500, + "at": 1, + "cur": [ + "EUR" + ], + "regs": { + "ext": { + "gdpr": 1 + } + }, + "user": { + "ext": { + "consent": "CO-X2XiO_eyUoAsAxBFRBECsA" + } + }, + "device": { + "ip": "123.123.123.123", + "ua": "test-user-agent" + }, + "site": { + "page": "https://example.com/page", + "domain": "example.com" + }, + "imp": [ + { + "id": "test-imp-id-1", + "banner": { + "h": 50, + "w": 320 + }, + "ext": { + "bidder": { + "apiKey": "test-api-key", + "placement": "test-placement-1", + "test": "1" + } + } + }, + { + "id": "test-imp-id-2", + "banner": { + "h": 50, + "w": 320 + }, + "ext": { + "bidder": { + "apiKey": "test-api-key", + "placement": "test-placement-2", + "test": "1" + } + } + }, + { + "id": "test-imp-id-3", + "banner": { + "h": 50, + "w": 320 + }, + "ext": { + "bidder": "abc" + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://example.com/?t=test-api-key", + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "User-Agent": [ + "test-user-agent" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ], + "Referer": [ + "https://example.com/page" + ] + }, + "body": { + "request_id": "test-request-id", + "timeout": 2000, + "referer": "https://example.com/page", + "referer_canonical": "example.com", + "consent_string": "CO-X2XiO_eyUoAsAxBFRBECsA", + "consent_required": true, + "placement": "test-placement-1", + "test": "1" + }, + "impIDs":["test-imp-id-1"] + }, + "mockResponse": { + "status": 200, + "body": { + "ad": "
test ad
", + "cpm": 1.5, + "currency": "EUR", + "requestId": "test-request-id" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids": [ + { + "bid": { + "id": "test-request-id", + "impid": "test-imp-id-1", + "price": 1.5, + "adm": "
test ad
", + "crid": "test-request-id" + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/missena/missenatest/exemplary/simple-banner-ipv6.json b/adapters/missena/missenatest/exemplary/simple-banner-ipv6.json new file mode 100644 index 00000000000..ea240f82e09 --- /dev/null +++ b/adapters/missena/missenatest/exemplary/simple-banner-ipv6.json @@ -0,0 +1,105 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "tmax": 500, + "at": 1, + "cur": [ + "EUR" + ], + "regs": { + "ext": { + "gdpr": 1 + } + }, + "user": { + "ext": { + "consent": "CO-X2XiO_eyUoAsAxBFRBECsA" + } + }, + "device": { + "ipv6": "2001:0000:130F:0000:0000:09C0:876A:130B", + "ua": "test-user-agent" + }, + "site": { + "page": "https://example.com/page", + "domain": "example.com" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "h": 50, + "w": 320 + }, + "ext": { + "bidder": { + "apiKey": "test-api-key", + "placement": "test-placement", + "test": "1" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://example.com/?t=test-api-key", + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "User-Agent": [ + "test-user-agent" + ], + "X-Forwarded-For": [ + "2001:0000:130F:0000:0000:09C0:876A:130B" + ], + "Referer": [ + "https://example.com/page" + ] + }, + "body": { + "request_id": "test-request-id", + "timeout": 2000, + "referer": "https://example.com/page", + "referer_canonical": "example.com", + "consent_string": "CO-X2XiO_eyUoAsAxBFRBECsA", + "consent_required": true, + "placement": "test-placement", + "test": "1" + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "ad": "
test ad
", + "cpm": 1.5, + "currency": "EUR", + "requestId": "test-request-id" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids": [ + { + "bid": { + "id": "test-request-id", + "impid": "test-imp-id", + "price": 1.5, + "adm": "
test ad
", + "crid": "test-request-id" + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/missena/missenatest/exemplary/simple-banner.json b/adapters/missena/missenatest/exemplary/simple-banner.json new file mode 100644 index 00000000000..74ff3abfd57 --- /dev/null +++ b/adapters/missena/missenatest/exemplary/simple-banner.json @@ -0,0 +1,105 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "tmax": 500, + "at": 1, + "cur": [ + "EUR" + ], + "regs": { + "ext": { + "gdpr": 1 + } + }, + "user": { + "ext": { + "consent": "CO-X2XiO_eyUoAsAxBFRBECsA" + } + }, + "device": { + "ip": "123.123.123.123", + "ua": "test-user-agent" + }, + "site": { + "page": "https://example.com/page", + "domain": "example.com" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "h": 50, + "w": 320 + }, + "ext": { + "bidder": { + "apiKey": "test-api-key", + "placement": "test-placement", + "test": "1" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://example.com/?t=test-api-key", + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "User-Agent": [ + "test-user-agent" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ], + "Referer": [ + "https://example.com/page" + ] + }, + "body": { + "request_id": "test-request-id", + "timeout": 2000, + "referer": "https://example.com/page", + "referer_canonical": "example.com", + "consent_string": "CO-X2XiO_eyUoAsAxBFRBECsA", + "consent_required": true, + "placement": "test-placement", + "test": "1" + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "ad": "
test ad
", + "cpm": 1.5, + "currency": "EUR", + "requestId": "test-request-id" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids": [ + { + "bid": { + "id": "test-request-id", + "impid": "test-imp-id", + "price": 1.5, + "adm": "
test ad
", + "crid": "test-request-id" + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/missena/missenatest/exemplary/valid-imp-error-imp.json b/adapters/missena/missenatest/exemplary/valid-imp-error-imp.json new file mode 100644 index 00000000000..61be3f78c4c --- /dev/null +++ b/adapters/missena/missenatest/exemplary/valid-imp-error-imp.json @@ -0,0 +1,129 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "tmax": 500, + "at": 1, + "cur": [ + "EUR" + ], + "regs": { + "ext": { + "gdpr": 1 + } + }, + "user": { + "ext": { + "consent": "CO-X2XiO_eyUoAsAxBFRBECsA" + } + }, + "device": { + "ip": "123.123.123.123", + "ua": "test-user-agent" + }, + "site": { + "page": "https://example.com/page", + "domain": "example.com" + }, + "imp": [ + { + "id": "test-imp-id-1", + "banner": { + "h": 50, + "w": 320 + }, + "ext": { + "bidder": { + "apiKey": "test-api-key", + "placement": "test-placement-1", + "test": "1" + } + } + }, + { + "id": "test-imp-id-2", + "banner": { + "h": 50, + "w": 320 + }, + "ext": { + "bidder": { + "apiKey": "test-api-key", + "placement": "test-placement-2", + "test": "1" + } + } + }, + { + "id": "test-imp-id-3", + "banner": { + "h": 50, + "w": 320 + }, + "ext": { + "bidder": "abc" + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://example.com/?t=test-api-key", + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "User-Agent": [ + "test-user-agent" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ], + "Referer": [ + "https://example.com/page" + ] + }, + "body": { + "request_id": "test-request-id", + "timeout": 2000, + "referer": "https://example.com/page", + "referer_canonical": "example.com", + "consent_string": "CO-X2XiO_eyUoAsAxBFRBECsA", + "consent_required": true, + "placement": "test-placement-1", + "test": "1" + }, + "impIDs": ["test-imp-id-1"] + }, + "mockResponse": { + "status": 200, + "body": { + "ad": "
test ad
", + "cpm": 1.5, + "currency": "EUR", + "requestId": "test-request-id" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "EUR", + "bids": [ + { + "bid": { + "id": "test-request-id", + "impid": "test-imp-id-1", + "price": 1.5, + "adm": "
test ad
", + "crid": "test-request-id" + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/missena/missenatest/supplemental/error-ext-bidder.json b/adapters/missena/missenatest/supplemental/error-ext-bidder.json new file mode 100644 index 00000000000..fdc08f4704b --- /dev/null +++ b/adapters/missena/missenatest/supplemental/error-ext-bidder.json @@ -0,0 +1,25 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "https://publisher.com/url" + }, + "user": { + "buyeruid": "1" + }, + "imp": [ + { + "id": "test-imp-id", + "ext": { + "bidder": "abc" + } + } + ] + }, + "expectedMakeRequestsErrors": [ + { + "value": "Error parsing missenaExt parameters", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/missena/missenatest/supplemental/error-imp-ext.json b/adapters/missena/missenatest/supplemental/error-imp-ext.json new file mode 100644 index 00000000000..3905efa6bab --- /dev/null +++ b/adapters/missena/missenatest/supplemental/error-imp-ext.json @@ -0,0 +1,23 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "page": "https://publisher.com/url" + }, + "user": { + "buyeruid": "1" + }, + "imp": [ + { + "id": "test-imp-id", + "ext": "error" + } + ] + }, + "expectedMakeRequestsErrors": [ + { + "value": "Error parsing bidderExt object", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/missena/missenatest/supplemental/status-204.json b/adapters/missena/missenatest/supplemental/status-204.json new file mode 100644 index 00000000000..59070ab4ecb --- /dev/null +++ b/adapters/missena/missenatest/supplemental/status-204.json @@ -0,0 +1,83 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "tmax": 500, + "at": 1, + "cur": [ + "EUR" + ], + "regs": { + "ext": { + "gdpr": 1 + } + }, + "user": { + "ext": { + "consent": "CO-X2XiO_eyUoAsAxBFRBECsA" + } + }, + "device": { + "ip": "123.123.123.123", + "ua": "test-user-agent" + }, + "site": { + "page": "https://example.com/page", + "domain": "example.com" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "h": 50, + "w": 320 + }, + "ext": { + "bidder": { + "apiKey": "test-api-key", + "placement": "test-placement", + "test": "1" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://example.com/?t=test-api-key", + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "User-Agent": [ + "test-user-agent" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ], + "Referer": [ + "https://example.com/page" + ] + }, + "body": { + "request_id": "test-request-id", + "timeout": 2000, + "referer": "https://example.com/page", + "referer_canonical": "example.com", + "consent_string": "CO-X2XiO_eyUoAsAxBFRBECsA", + "consent_required": true, + "placement": "test-placement", + "test": "1" + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 204 + } + } + ], + "expectedBidResponses": [] +} \ No newline at end of file diff --git a/adapters/missena/missenatest/supplemental/status-400.json b/adapters/missena/missenatest/supplemental/status-400.json new file mode 100644 index 00000000000..23a153208e3 --- /dev/null +++ b/adapters/missena/missenatest/supplemental/status-400.json @@ -0,0 +1,89 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "tmax": 500, + "at": 1, + "cur": [ + "EUR" + ], + "regs": { + "ext": { + "gdpr": 1 + } + }, + "user": { + "ext": { + "consent": "CO-X2XiO_eyUoAsAxBFRBECsA" + } + }, + "device": { + "ip": "123.123.123.123", + "ua": "test-user-agent" + }, + "site": { + "page": "https://example.com/page", + "domain": "example.com" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "h": 50, + "w": 320 + }, + "ext": { + "bidder": { + "apiKey": "test-api-key", + "placement": "test-placement", + "test": "1" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://example.com/?t=test-api-key", + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "User-Agent": [ + "test-user-agent" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ], + "Referer": [ + "https://example.com/page" + ] + }, + "body": { + "request_id": "test-request-id", + "timeout": 2000, + "referer": "https://example.com/page", + "referer_canonical": "example.com", + "consent_string": "CO-X2XiO_eyUoAsAxBFRBECsA", + "consent_required": true, + "placement": "test-placement", + "test": "1" + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 400, + "body": "Bad request from publisher." + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400. Bad request from publisher. Run with request.debug = 1 for more info.", + "comparison": "literal" + } + ] + } \ No newline at end of file diff --git a/adapters/missena/missenatest/supplemental/status-not-200.json b/adapters/missena/missenatest/supplemental/status-not-200.json new file mode 100644 index 00000000000..8c913791fc3 --- /dev/null +++ b/adapters/missena/missenatest/supplemental/status-not-200.json @@ -0,0 +1,89 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "tmax": 500, + "at": 1, + "cur": [ + "EUR" + ], + "regs": { + "ext": { + "gdpr": 1 + } + }, + "user": { + "ext": { + "consent": "CO-X2XiO_eyUoAsAxBFRBECsA" + } + }, + "device": { + "ip": "123.123.123.123", + "ua": "test-user-agent" + }, + "site": { + "page": "https://example.com/page", + "domain": "example.com" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "h": 50, + "w": 320 + }, + "ext": { + "bidder": { + "apiKey": "test-api-key", + "placement": "test-placement", + "test": "1" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://example.com/?t=test-api-key", + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "User-Agent": [ + "test-user-agent" + ], + "X-Forwarded-For": [ + "123.123.123.123" + ], + "Referer": [ + "https://example.com/page" + ] + }, + "body": { + "request_id": "test-request-id", + "timeout": 2000, + "referer": "https://example.com/page", + "referer_canonical": "example.com", + "consent_string": "CO-X2XiO_eyUoAsAxBFRBECsA", + "consent_required": true, + "placement": "test-placement", + "test": "1" + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 404, + "body": {} + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 404. Run with request.debug = 1 for more info.", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/missena/params_test.go b/adapters/missena/params_test.go new file mode 100644 index 00000000000..393561b43cf --- /dev/null +++ b/adapters/missena/params_test.go @@ -0,0 +1,50 @@ +package missena + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v3/openrtb_ext" +) + +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json schema. %v", err) + } + + for _, p := range validParams { + if err := validator.Validate(openrtb_ext.BidderMissena, json.RawMessage(p)); err != nil { + t.Errorf("Schema rejected valid params: %s", p) + } + } +} + +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json schema. %v", err) + } + + for _, p := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderMissena, json.RawMessage(p)); err == nil { + t.Errorf("Schema allowed invalid params: %s", p) + } + } +} + +var validParams = []string{ + `{"apiKey": "PA-123456"}`, + `{"apiKey": "PA-123456", "placement": "sticky"}`, + `{"apiKey": "PA-123456", "test": "native"}`, +} + +var invalidParams = []string{ + `{"apiKey": ""}`, + `{"apiKey": 42}`, + `{"placement": 111}`, + `{"placement": "sticky"}`, + `{"apiKey": "PA-123456", "placement": 111}`, + `{"test": "native"}`, + `{"apiKey": "PA-123456", "test": 111}`, +} diff --git a/adapters/mobfoxpb/mobfoxpb.go b/adapters/mobfoxpb/mobfoxpb.go index b7630d7f9e1..538e7f7bcee 100644 --- a/adapters/mobfoxpb/mobfoxpb.go +++ b/adapters/mobfoxpb/mobfoxpb.go @@ -8,10 +8,11 @@ import ( "github.com/buger/jsonparser" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) const ( @@ -113,7 +114,7 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } diff --git a/adapters/mobfoxpb/mobfoxpb_test.go b/adapters/mobfoxpb/mobfoxpb_test.go index b3aa4ae4b2c..cbcfd29ebc2 100644 --- a/adapters/mobfoxpb/mobfoxpb_test.go +++ b/adapters/mobfoxpb/mobfoxpb_test.go @@ -3,9 +3,9 @@ package mobfoxpb import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/mobfoxpb/mobfoxpbtest/supplemental/bad_response.json b/adapters/mobfoxpb/mobfoxpbtest/supplemental/bad_response.json index e4f246e7e0d..51a4eae8ef4 100644 --- a/adapters/mobfoxpb/mobfoxpbtest/supplemental/bad_response.json +++ b/adapters/mobfoxpb/mobfoxpbtest/supplemental/bad_response.json @@ -79,7 +79,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/mobfoxpb/params_test.go b/adapters/mobfoxpb/params_test.go index ea785163609..52b9ffb6273 100644 --- a/adapters/mobfoxpb/params_test.go +++ b/adapters/mobfoxpb/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // TestValidParams makes sure that the mobfoxpb schema accepts all imp.ext fields which we intend to support. diff --git a/adapters/mobilefuse/mobilefuse.go b/adapters/mobilefuse/mobilefuse.go index 6d0ab2ec3f5..5670c7157cc 100644 --- a/adapters/mobilefuse/mobilefuse.go +++ b/adapters/mobilefuse/mobilefuse.go @@ -8,11 +8,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type MobileFuseAdapter struct { @@ -75,7 +76,7 @@ func (adapter *MobileFuseAdapter) MakeBids(incomingRequest *openrtb2.BidRequest, var incomingBidResponse openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &incomingBidResponse); err != nil { + if err := jsonutil.Unmarshal(response.Body, &incomingBidResponse); err != nil { return nil, []error{err} } @@ -142,14 +143,14 @@ func getFirstMobileFuseExtension(request *openrtb2.BidRequest) (*openrtb_ext.Ext for _, imp := range request.Imp { var bidder_imp_extension adapters.ExtImpBidder - err := json.Unmarshal(imp.Ext, &bidder_imp_extension) + err := jsonutil.Unmarshal(imp.Ext, &bidder_imp_extension) if err != nil { errs = append(errs, err) continue } - err = json.Unmarshal(bidder_imp_extension.Bidder, &mobileFuseImpExtension) + err = jsonutil.Unmarshal(bidder_imp_extension.Bidder, &mobileFuseImpExtension) if err != nil { errs = append(errs, err) @@ -165,12 +166,12 @@ func getFirstMobileFuseExtension(request *openrtb2.BidRequest) (*openrtb_ext.Ext func getMobileFuseExtensionForImp(imp *openrtb2.Imp, mobileFuseImpExtension *openrtb_ext.ExtImpMobileFuse) error { var bidder_imp_extension adapters.ExtImpBidder - err := json.Unmarshal(imp.Ext, &bidder_imp_extension) + err := jsonutil.Unmarshal(imp.Ext, &bidder_imp_extension) if err != nil { return err } - return json.Unmarshal(bidder_imp_extension.Bidder, &mobileFuseImpExtension) + return jsonutil.Unmarshal(bidder_imp_extension.Bidder, &mobileFuseImpExtension) } func (adapter *MobileFuseAdapter) getEndpoint(ext *openrtb_ext.ExtImpMobileFuse) (string, error) { @@ -201,7 +202,7 @@ func getValidImps(bidRequest *openrtb2.BidRequest, ext *openrtb_ext.ExtImpMobile imp.TagID = strconv.Itoa(ext.PlacementId) var extSkadn ExtSkadn - err = json.Unmarshal(imp.Ext, &extSkadn) + err = jsonutil.Unmarshal(imp.Ext, &extSkadn) if err != nil { return nil, err } @@ -229,7 +230,7 @@ func getValidImps(bidRequest *openrtb2.BidRequest, ext *openrtb_ext.ExtImpMobile func getBidType(bid openrtb2.Bid) openrtb_ext.BidType { if bid.Ext != nil { var bidExt BidExt - err := json.Unmarshal(bid.Ext, &bidExt) + err := jsonutil.Unmarshal(bid.Ext, &bidExt) if err == nil { if bidExt.Mf.MediaType == "video" { return openrtb_ext.BidTypeVideo diff --git a/adapters/mobilefuse/mobilefuse_test.go b/adapters/mobilefuse/mobilefuse_test.go index e1a3a018bb9..41595c2256d 100644 --- a/adapters/mobilefuse/mobilefuse_test.go +++ b/adapters/mobilefuse/mobilefuse_test.go @@ -3,9 +3,9 @@ package mobilefuse import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/mobilefuse/mobilefusetest/supplemental/bad-ext-bidder.json b/adapters/mobilefuse/mobilefusetest/supplemental/bad-ext-bidder.json index 61cf115faea..759fffc7e8a 100644 --- a/adapters/mobilefuse/mobilefusetest/supplemental/bad-ext-bidder.json +++ b/adapters/mobilefuse/mobilefusetest/supplemental/bad-ext-bidder.json @@ -1,7 +1,7 @@ { "expectedMakeRequestsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb_ext.ExtImpMobileFuse", + "value": "expect { or n, but found \"", "comparison": "literal" } ], diff --git a/adapters/mobilefuse/mobilefusetest/supplemental/bad-ext.json b/adapters/mobilefuse/mobilefusetest/supplemental/bad-ext.json index f0c23aa27e3..598f1606796 100644 --- a/adapters/mobilefuse/mobilefusetest/supplemental/bad-ext.json +++ b/adapters/mobilefuse/mobilefusetest/supplemental/bad-ext.json @@ -1,7 +1,7 @@ { "expectedMakeRequestsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type adapters.ExtImpBidder", + "value": "expect { or n, but found \"", "comparison": "literal" } ], diff --git a/adapters/mobilefuse/params_test.go b/adapters/mobilefuse/params_test.go index 8599af5ece0..363830c0537 100644 --- a/adapters/mobilefuse/params_test.go +++ b/adapters/mobilefuse/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(test *testing.T) { diff --git a/adapters/motorik/motorik.go b/adapters/motorik/motorik.go index 73cfccde107..5256605ec8b 100644 --- a/adapters/motorik/motorik.go +++ b/adapters/motorik/motorik.go @@ -7,11 +7,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -82,13 +83,13 @@ func (a *adapter) MakeRequests(openRTBRequest *openrtb2.BidRequest, reqInfo *ada func getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtMotorik, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: "Error parsing motorikExt - " + err.Error(), } } var motorikExt openrtb_ext.ExtMotorik - if err := json.Unmarshal(bidderExt.Bidder, &motorikExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &motorikExt); err != nil { return nil, &errortypes.BadInput{ Message: "Error parsing bidderExt - " + err.Error(), } @@ -124,7 +125,7 @@ func (a *adapter) MakeBids(openRTBRequest *openrtb2.BidRequest, requestToBidder responseBody := bidderRawResponse.Body var bidResp openrtb2.BidResponse - if err := json.Unmarshal(responseBody, &bidResp); err != nil { + if err := jsonutil.Unmarshal(responseBody, &bidResp); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: "Bad Server Response", }} diff --git a/adapters/motorik/motorik_test.go b/adapters/motorik/motorik_test.go index 5bdd102ddd3..5d99d05012e 100644 --- a/adapters/motorik/motorik_test.go +++ b/adapters/motorik/motorik_test.go @@ -3,9 +3,9 @@ package motorik import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/motorik/motoriktest/supplemental/invalid-bidder-ext-object.json b/adapters/motorik/motoriktest/supplemental/invalid-bidder-ext-object.json index fb89a5894a5..016fbd43490 100644 --- a/adapters/motorik/motoriktest/supplemental/invalid-bidder-ext-object.json +++ b/adapters/motorik/motoriktest/supplemental/invalid-bidder-ext-object.json @@ -1,7 +1,7 @@ { "expectedMakeRequestsErrors": [ { - "value": "Error parsing bidderExt - json: cannot unmarshal string into Go value of type openrtb_ext.ExtMotorik", + "value": "Error parsing bidderExt - expect { or n, but found \"", "comparison": "literal" } ], diff --git a/adapters/motorik/motoriktest/supplemental/invalid-motorik-ext-object.json b/adapters/motorik/motoriktest/supplemental/invalid-motorik-ext-object.json index 1b2cce8db49..ee1d473feab 100644 --- a/adapters/motorik/motoriktest/supplemental/invalid-motorik-ext-object.json +++ b/adapters/motorik/motoriktest/supplemental/invalid-motorik-ext-object.json @@ -1,7 +1,7 @@ { "expectedMakeRequestsErrors": [ { - "value": "Error parsing motorikExt - json: cannot unmarshal string into Go value of type adapters.ExtImpBidder", + "value": "Error parsing motorikExt - expect { or n, but found \"", "comparison": "literal" } ], diff --git a/adapters/motorik/params_test.go b/adapters/motorik/params_test.go index 2cfdf0f965b..9c8dc2f5d18 100644 --- a/adapters/motorik/params_test.go +++ b/adapters/motorik/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/nextmillennium/nextmillennium.go b/adapters/nextmillennium/nextmillennium.go index 38d1c72549e..cae3e03be19 100644 --- a/adapters/nextmillennium/nextmillennium.go +++ b/adapters/nextmillennium/nextmillennium.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -74,13 +75,13 @@ func getImpressionsInfo(imps []openrtb2.Imp) (resImps []*openrtb_ext.ImpExtNextM func getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ImpExtNextMillennium, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: err.Error(), } } var nextMillenniumExt openrtb_ext.ImpExtNextMillennium - if err := json.Unmarshal(bidderExt.Bidder, &nextMillenniumExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &nextMillenniumExt); err != nil { return nil, &errortypes.BadInput{ Message: err.Error(), } @@ -169,7 +170,7 @@ func (adapter *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalR } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { msg = fmt.Sprintf("Bad server response: %d", err) return nil, []error{&errortypes.BadServerResponse{Message: msg}} } @@ -200,7 +201,7 @@ func (adapter *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalR func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { var info nmExtNMM if config.ExtraAdapterInfo != "" { - if err := json.Unmarshal([]byte(config.ExtraAdapterInfo), &info); err != nil { + if err := jsonutil.Unmarshal([]byte(config.ExtraAdapterInfo), &info); err != nil { return nil, fmt.Errorf("invalid extra info: %v", err) } } diff --git a/adapters/nextmillennium/nextmillennium_test.go b/adapters/nextmillennium/nextmillennium_test.go index 6e51edc5e17..1ffe49540bf 100644 --- a/adapters/nextmillennium/nextmillennium_test.go +++ b/adapters/nextmillennium/nextmillennium_test.go @@ -3,9 +3,9 @@ package nextmillennium import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/nextmillennium/nextmillenniumtest/supplemental/ext.json b/adapters/nextmillennium/nextmillenniumtest/supplemental/ext.json index 58fefc6349f..68584236617 100644 --- a/adapters/nextmillennium/nextmillenniumtest/supplemental/ext.json +++ b/adapters/nextmillennium/nextmillenniumtest/supplemental/ext.json @@ -26,8 +26,8 @@ }, "expectedMakeRequestsErrors": [ { - "value": "unexpected end of JSON input", - "comparison": "literal" + "value": "expect { or n, but found", + "comparison": "startswith" } ] } diff --git a/adapters/nextmillennium/params_test.go b/adapters/nextmillennium/params_test.go index d8ae93d2c5a..3833c474a34 100644 --- a/adapters/nextmillennium/params_test.go +++ b/adapters/nextmillennium/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/nobid/nobid.go b/adapters/nobid/nobid.go index 9c91c78dd2b..811ef3363ed 100644 --- a/adapters/nobid/nobid.go +++ b/adapters/nobid/nobid.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) // NoBidAdapter - NoBid Adapter definition @@ -73,7 +74,7 @@ func (a *NoBidAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRe var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } diff --git a/adapters/nobid/nobid_test.go b/adapters/nobid/nobid_test.go index 8b48a303053..6b4a7346cff 100644 --- a/adapters/nobid/nobid_test.go +++ b/adapters/nobid/nobid_test.go @@ -3,9 +3,9 @@ package nobid import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/nobid/params_test.go b/adapters/nobid/params_test.go index 395230df797..375237f3446 100644 --- a/adapters/nobid/params_test.go +++ b/adapters/nobid/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/oms/oms.go b/adapters/oms/oms.go index c2e7c394cb5..201162b5699 100644 --- a/adapters/oms/oms.go +++ b/adapters/oms/oms.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -61,7 +62,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } diff --git a/adapters/oms/oms_test.go b/adapters/oms/oms_test.go index 9c3c4119f10..e0555b3c755 100644 --- a/adapters/oms/oms_test.go +++ b/adapters/oms/oms_test.go @@ -3,9 +3,9 @@ package oms import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/oms/params_test.go b/adapters/oms/params_test.go index daa78fe7ddf..00b92699455 100644 --- a/adapters/oms/params_test.go +++ b/adapters/oms/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/oms.json diff --git a/adapters/onetag/onetag.go b/adapters/onetag/onetag.go index 938414c2759..c0972816e6a 100644 --- a/adapters/onetag/onetag.go +++ b/adapters/onetag/onetag.go @@ -7,11 +7,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -76,14 +77,14 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte func getImpressionExt(imp openrtb2.Imp) (*openrtb_ext.ExtImpOnetag, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: "Bidder extension not provided or can't be unmarshalled", } } var onetagExt openrtb_ext.ExtImpOnetag - if err := json.Unmarshal(bidderExt.Bidder, &onetagExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &onetagExt); err != nil { return nil, &errortypes.BadInput{ Message: "Error while unmarshaling bidder extension", } @@ -110,7 +111,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } diff --git a/adapters/onetag/onetag_test.go b/adapters/onetag/onetag_test.go index 7a1e539ca29..23a28717580 100644 --- a/adapters/onetag/onetag_test.go +++ b/adapters/onetag/onetag_test.go @@ -3,9 +3,9 @@ package onetag import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/onetag/params_test.go b/adapters/onetag/params_test.go index bfc7c6ac27a..6ccf0606967 100644 --- a/adapters/onetag/params_test.go +++ b/adapters/onetag/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/openweb/openweb.go b/adapters/openweb/openweb.go index b74e97dfc3f..7a9914b2726 100644 --- a/adapters/openweb/openweb.go +++ b/adapters/openweb/openweb.go @@ -2,189 +2,134 @@ package openweb import ( "encoding/json" + "errors" "fmt" "net/http" + "strconv" + "strings" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { endpoint string } -type openwebImpExt struct { - OpenWeb openrtb_ext.ExtImpOpenWeb `json:"openweb"` -} - -func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { - totalImps := len(request.Imp) - errors := make([]error, 0, totalImps) - sourceIdToImpIds := make(map[int][]int) - var sourceIds []int - - for i := 0; i < totalImps; i++ { - - sourceId, err := validateImpression(&request.Imp[i]) - - if err != nil { - errors = append(errors, err) - continue - } - - if _, ok := sourceIdToImpIds[sourceId]; !ok { - sourceIdToImpIds[sourceId] = make([]int, 0, totalImps-i) - sourceIds = append(sourceIds, sourceId) - } - - sourceIdToImpIds[sourceId] = append(sourceIdToImpIds[sourceId], i) - +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, _ *adapters.ExtraRequestInfo) (requestsToBidder []*adapters.RequestData, errs []error) { + org, err := checkExtAndExtractOrg(request) + if err != nil { + errs = append(errs, fmt.Errorf("checkExtAndExtractOrg: %w", err)) + return nil, errs } - totalReqs := len(sourceIdToImpIds) - if totalReqs == 0 { - return nil, errors + requestJSON, err := json.Marshal(request) + if err != nil { + errs = append(errs, fmt.Errorf("marshal bidRequest: %w", err)) + return nil, errs } headers := http.Header{} headers.Add("Content-Type", "application/json;charset=utf-8") - headers.Add("Accept", "application/json") - reqs := make([]*adapters.RequestData, 0, totalReqs) + return append(requestsToBidder, &adapters.RequestData{ + Method: http.MethodPost, + Uri: a.endpoint + "?publisher_id=" + org, + Body: requestJSON, + Headers: headers, + ImpIDs: openrtb_ext.GetImpIDs(request.Imp), + }), nil +} - imps := request.Imp - reqCopy := *request - reqCopy.Imp = make([]openrtb2.Imp, totalImps) - for _, sourceId := range sourceIds { - impIds := sourceIdToImpIds[sourceId] - reqCopy.Imp = reqCopy.Imp[:0] +// checkExtAndExtractOrg checks the presence of required parameters and extracts the Org ID string. +func checkExtAndExtractOrg(request *openrtb2.BidRequest) (string, error) { + var err error + for _, imp := range request.Imp { + var bidderExt adapters.ExtImpBidder + if err = jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { + return "", fmt.Errorf("unmarshal bidderExt: %w", err) + } - for i := 0; i < len(impIds); i++ { - reqCopy.Imp = append(reqCopy.Imp, imps[impIds[i]]) + var impExt openrtb_ext.ExtImpOpenWeb + if err = jsonutil.Unmarshal(bidderExt.Bidder, &impExt); err != nil { + return "", fmt.Errorf("unmarshal ExtImpOpenWeb: %w", err) } - body, err := json.Marshal(reqCopy) - if err != nil { - errors = append(errors, fmt.Errorf("error while encoding bidRequest, err: %s", err)) - return nil, errors + if impExt.PlacementID == "" { + return "", errors.New("no placement id supplied") } - reqs = append(reqs, &adapters.RequestData{ - Method: "POST", - Uri: a.endpoint + fmt.Sprintf("?aid=%d", sourceId), - Body: body, - Headers: headers, - ImpIDs: openrtb_ext.GetImpIDs(reqCopy.Imp), - }) - } + if impExt.Org != "" { + return strings.TrimSpace(impExt.Org), nil + } - return reqs, errors + if impExt.Aid != 0 { + return strconv.Itoa(impExt.Aid), nil + } + } + return "", errors.New("no org or aid supplied") } -func (a *adapter) MakeBids(bidReq *openrtb2.BidRequest, unused *adapters.RequestData, httpRes *adapters.ResponseData) (*adapters.BidderResponse, []error) { - - if httpRes.StatusCode == http.StatusNoContent { +func (a *adapter) MakeBids(request *openrtb2.BidRequest, _ *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if adapters.IsResponseStatusCodeNoContent(responseData) { return nil, nil } - if httpRes.StatusCode != http.StatusOK { - return nil, []error{&errortypes.BadServerResponse{ - Message: fmt.Sprintf("Remote server error: %s", httpRes.Body), - }} - } - var bidResp openrtb2.BidResponse - if err := json.Unmarshal(httpRes.Body, &bidResp); err != nil { - return nil, []error{&errortypes.BadServerResponse{ - Message: fmt.Sprintf("error while decoding response, err: %s", err), - }} + if err := adapters.CheckResponseStatusCodeForErrors(responseData); err != nil { + return nil, []error{err} } - bidResponse := adapters.NewBidderResponse() - var errors []error + var response openrtb2.BidResponse + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { + return nil, []error{err} + } - for _, sb := range bidResp.SeatBid { - for i := 0; i < len(sb.Bid); i++ { + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) + if response.Cur != "" { + bidResponse.Currency = response.Cur + } - bid := sb.Bid[i] + var errs []error - mediaType, impOK := getBidType(bidReq.Imp, bid.ImpID) - if !impOK { - errors = append(errors, &errortypes.BadServerResponse{ - Message: fmt.Sprintf("ignoring bid id=%s, request doesn't contain any impression with id=%s", bid.ID, bid.ImpID), - }) + for _, seatBid := range response.SeatBid { + for i, bid := range seatBid.Bid { + bidType, err := getMediaTypeForBid(bid) + if err != nil { + errs = append(errs, err) continue } bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ - Bid: &bid, - BidType: mediaType, + Bid: &seatBid.Bid[i], + BidType: bidType, }) } } - return bidResponse, errors + return bidResponse, errs } -func getBidType(imps []openrtb2.Imp, impId string) (mediaType openrtb_ext.BidType, ok bool) { - mediaType = openrtb_ext.BidTypeBanner - for _, imp := range imps { - if imp.ID == impId { - ok = true - - if imp.Video != nil { - mediaType = openrtb_ext.BidTypeVideo - } - - break - } - } - - return -} - -func validateImpression(imp *openrtb2.Imp) (int, error) { - var bidderExt adapters.ExtImpBidder - - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { - return 0, &errortypes.BadInput{ - Message: fmt.Sprintf("ignoring imp id=%s, error while decoding extImpBidder, err: %s", imp.ID, err), - } - } - - impExt := openrtb_ext.ExtImpOpenWeb{} - err := json.Unmarshal(bidderExt.Bidder, &impExt) - if err != nil { - return 0, &errortypes.BadInput{ - Message: fmt.Sprintf("ignoring imp id=%s, error while decoding impExt, err: %s", imp.ID, err), +func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) { + switch bid.MType { + case openrtb2.MarkupBanner: + return openrtb_ext.BidTypeBanner, nil + case openrtb2.MarkupVideo: + return openrtb_ext.BidTypeVideo, nil + default: + return "", &errortypes.BadServerResponse{ + Message: fmt.Sprintf("unsupported MType %d", bid.MType), } } - - var impExtBuffer []byte - - impExtBuffer, err = json.Marshal(&openwebImpExt{ - OpenWeb: impExt, - }) - if err != nil { - return 0, &errortypes.BadInput{ - Message: fmt.Sprintf("ignoring imp id=%s, error while encoding impExt, err: %s", imp.ID, err), - } - } - - if impExt.BidFloor > 0 { - imp.BidFloor = impExt.BidFloor - } - - imp.Ext = impExtBuffer - - return impExt.SourceID, nil } // Builder builds a new instance of the OpenWeb adapter for the given bidder with the given config. -func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { +func Builder(_ openrtb_ext.BidderName, config config.Adapter, _ config.Server) (adapters.Bidder, error) { bidder := &adapter{ endpoint: config.Endpoint, } diff --git a/adapters/openweb/openweb_test.go b/adapters/openweb/openweb_test.go index a63dafd06c2..a08788e7db8 100644 --- a/adapters/openweb/openweb_test.go +++ b/adapters/openweb/openweb_test.go @@ -3,14 +3,14 @@ package openweb import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { bidder, buildErr := Builder(openrtb_ext.BidderOpenWeb, config.Adapter{ - Endpoint: "http://ghb.spotim.market/pbs/ortb"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + Endpoint: "https://pbs.openwebmp.com/pbs"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) if buildErr != nil { t.Fatalf("Builder returned unexpected error %v", buildErr) diff --git a/adapters/openweb/openwebtest/exemplary/multiple-imps-same-aid.json b/adapters/openweb/openwebtest/exemplary/multiple-imps-same-aid.json deleted file mode 100644 index 2fd7c195b3e..00000000000 --- a/adapters/openweb/openwebtest/exemplary/multiple-imps-same-aid.json +++ /dev/null @@ -1,175 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 600 - } - ] - }, - "bidfloor": 30, - "ext": { - "bidder": { - "aid": 1000, - "siteId": 1234, - "bidFloor": 20 - } - } - }, - { - "id": "test-imp-id-2", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 600 - } - ] - }, - "bidfloor": 30, - "ext": { - "bidder": { - "aid": 1000, - "siteId": 4321, - "bidFloor": 20 - } - } - } - ] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://ghb.spotim.market/pbs/ortb?aid=1000", - "body": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 600 - } - ] - }, - "bidfloor": 20, - "ext": { - "openweb": { - "aid": 1000, - "siteId": 1234, - "bidFloor": 20 - } - } - }, - { - "id": "test-imp-id-2", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 600 - } - ] - }, - "bidfloor": 20, - "ext": { - "openweb": { - "aid": 1000, - "siteId": 4321, - "bidFloor": 20 - } - } - } - ] - }, - "impIDs":["test-imp-id","test-imp-id-2"] - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "seat": "test-seat", - "bid": [ - { - "id": "test-bid-id", - "impid": "test-imp-id", - "price": 30, - "adm": "some-test-ad", - "crid": "crid_10", - "h": 250, - "w": 300 - }, - { - "id": "test-bid-id-2", - "impid": "test-imp-id-2", - "price": 30, - "adm": "some-test-ad", - "crid": "crid_10", - "h": 250, - "w": 300 - } - ] - } - ], - "cur": "USD" - } - } - } - ], - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "test-bid-id", - "impid": "test-imp-id", - "price": 30, - "adm": "some-test-ad", - "crid": "crid_10", - "w": 300, - "h": 250 - }, - "type": "banner" - }, - { - "bid": { - "id": "test-bid-id-2", - "impid": "test-imp-id-2", - "price": 30, - "adm": "some-test-ad", - "crid": "crid_10", - "w": 300, - "h": 250 - }, - "type": "banner" - } - ] - } - ] -} diff --git a/adapters/openweb/openwebtest/exemplary/simple-banner.json b/adapters/openweb/openwebtest/exemplary/simple-banner.json index b742fa50eb9..e6c1abd7cc6 100644 --- a/adapters/openweb/openwebtest/exemplary/simple-banner.json +++ b/adapters/openweb/openwebtest/exemplary/simple-banner.json @@ -16,12 +16,10 @@ } ] }, - "bidfloor": 30, "ext": { "bidder": { - "aid": 1000, - "siteId": 1234, - "bidFloor": 20 + "org": "777", + "placementId": "1" } } }, @@ -39,94 +37,70 @@ } ] }, - "bidfloor": 30, "ext": { "bidder": { - "aid": 2000, - "siteId": 4321, - "bidFloor": 20 + "org": "777", + "placementId": "1" } } } ] }, - "httpCalls": [ { "expectedRequest": { - "uri": "http://ghb.spotim.market/pbs/ortb?aid=1000", + "uri": "https://pbs.openwebmp.com/pbs?publisher_id=777", "body": { "id": "test-request-id", "imp": [ { - "id":"test-imp-id", + "id": "test-imp-id", "banner": { "format": [ - {"w":300,"h":250}, - {"w":300,"h":600} + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } ] }, - "bidfloor": 20, "ext": { - "openweb": { - "aid": 1000, - "siteId": 1234, - "bidFloor": 20 + "bidder": { + "org": "777", + "placementId": "1" } } - } - ] - }, - "impIDs":["test-imp-id"] - }, - "mockResponse": { - "status": 200, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "seat": "test-seat", - "bid": [{ - "id": "test-bid-id", - "impid": "test-imp-id", - "price": 30, - "adm": "some-test-ad", - "crid": "crid_10", - "h": 250, - "w": 300 - }] - } - ], - "cur": "USD" - } - } - }, - { - "expectedRequest": { - "uri": "http://ghb.spotim.market/pbs/ortb?aid=2000", - "body": { - "id": "test-request-id", - "imp": [ + }, { - "id":"test-imp-id-2", + "id": "test-imp-id-2", "banner": { "format": [ - {"w":300,"h":250}, - {"w":300,"h":600} + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } ] }, - "bidfloor": 20, "ext": { - "openweb": { - "aid": 2000, - "siteId": 4321, - "bidFloor": 20 + "bidder": { + "org": "777", + "placementId": "1" } } } ] }, - "impIDs":["test-imp-id-2"] + "impIDs": [ + "test-imp-id", + "test-imp-id-2" + ] }, "mockResponse": { "status": 200, @@ -134,16 +108,19 @@ "id": "test-request-id", "seatbid": [ { - "seat": "test-seat-2", - "bid": [{ - "id": "test-bid-id-2", - "impid": "test-imp-id-2", - "price": 30, - "adm": "some-test-ad", - "crid": "crid_10", - "h": 250, - "w": 300 - }] + "seat": "test-seat", + "bid": [ + { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 30, + "adm": "some-test-ad", + "crid": "crid_10", + "h": 250, + "w": 300, + "mtype": 1 + } + ] } ], "cur": "USD" @@ -163,24 +140,8 @@ "adm": "some-test-ad", "crid": "crid_10", "w": 300, - "h": 250 - }, - "type": "banner" - } - ] - }, - { - "currency": "USD", - "bids": [ - { - "bid": { - "id": "test-bid-id-2", - "impid": "test-imp-id-2", - "price": 30, - "adm": "some-test-ad", - "crid": "crid_10", - "w": 300, - "h": 250 + "h": 250, + "mtype": 1 }, "type": "banner" } diff --git a/adapters/openweb/openwebtest/exemplary/simple-video.json b/adapters/openweb/openwebtest/exemplary/simple-video.json index e8052e7ebf2..199607cbe32 100644 --- a/adapters/openweb/openwebtest/exemplary/simple-video.json +++ b/adapters/openweb/openwebtest/exemplary/simple-video.json @@ -14,22 +14,22 @@ }, "ext": { "bidder": { - "aid": 1000 + "aid": 777, + "placementId": "1" } } } ] }, - "httpCalls": [ { "expectedRequest": { - "uri": "http://ghb.spotim.market/pbs/ortb?aid=1000", + "uri": "https://pbs.openwebmp.com/pbs?publisher_id=777", "body": { "id": "test-request-id", "imp": [ { - "id":"test-imp-id", + "id": "test-imp-id", "video": { "w": 900, "h": 250, @@ -39,14 +39,17 @@ ] }, "ext": { - "openweb": { - "aid": 1000 + "bidder": { + "aid": 777, + "placementId": "1" } } } ] }, - "impIDs":["test-imp-id"] + "impIDs": [ + "test-imp-id" + ] }, "mockResponse": { "status": 200, @@ -60,7 +63,8 @@ "impid": "test-imp-id", "price": 3.5, "w": 900, - "h": 250 + "h": 250, + "mtype": 2 } ] } @@ -79,7 +83,8 @@ "impid": "test-imp-id", "price": 3.5, "w": 900, - "h": 250 + "h": 250, + "mtype": 2 }, "type": "video" } diff --git a/adapters/openweb/openwebtest/supplemental/missing-mtype.json b/adapters/openweb/openwebtest/supplemental/missing-mtype.json new file mode 100644 index 00000000000..68b487216c0 --- /dev/null +++ b/adapters/openweb/openwebtest/supplemental/missing-mtype.json @@ -0,0 +1,93 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "w": 900, + "h": 250, + "mimes": [ + "video/x-flv", + "video/mp4" + ] + }, + "ext": { + "bidder": { + "org": "777", + "placementId": "1" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://pbs.openwebmp.com/pbs?publisher_id=777", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "w": 900, + "h": 250, + "mimes": [ + "video/x-flv", + "video/mp4" + ] + }, + "ext": { + "bidder": { + "org": "777", + "placementId": "1" + } + } + } + ] + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [ + { + "seat": "958", + "bid": [ + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "w": 900, + "h": 250, + "mimes": [ + "video/x-flv", + "video/mp4" + ] + } + ] + } + ] + } + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "unsupported MType 0", + "comparison": "literal" + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [] + } + ] +} diff --git a/adapters/openweb/openwebtest/supplemental/no-valid-imps.json b/adapters/openweb/openwebtest/supplemental/missing-org-and-aid.json similarity index 78% rename from adapters/openweb/openwebtest/supplemental/no-valid-imps.json rename to adapters/openweb/openwebtest/supplemental/missing-org-and-aid.json index 3335639d59f..6d156985029 100644 --- a/adapters/openweb/openwebtest/supplemental/no-valid-imps.json +++ b/adapters/openweb/openwebtest/supplemental/missing-org-and-aid.json @@ -14,16 +14,16 @@ }, "ext": { "bidder": { - "aid": "not valid value" + "org": "", + "placementId": "1" } } } ] }, - "expectedMakeRequestsErrors": [ { - "value": "^ignoring imp id=test-imp-id, error while decoding impExt", + "value": "no org or aid supplied", "comparison": "regex" } ] diff --git a/adapters/openweb/openwebtest/supplemental/missing-placement-id.json b/adapters/openweb/openwebtest/supplemental/missing-placement-id.json new file mode 100644 index 00000000000..d7159e2f638 --- /dev/null +++ b/adapters/openweb/openwebtest/supplemental/missing-placement-id.json @@ -0,0 +1,29 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "w": 900, + "h": 250, + "mimes": [ + "video/x-flv", + "video/mp4" + ] + }, + "ext": { + "bidder": { + "org": "777" + } + } + } + ] + }, + "expectedMakeRequestsErrors": [ + { + "value": "no placement id supplied", + "comparison": "regex" + } + ] +} diff --git a/adapters/openweb/openwebtest/supplemental/status-500.json b/adapters/openweb/openwebtest/supplemental/status-500.json deleted file mode 100644 index 48cfab3b7fa..00000000000 --- a/adapters/openweb/openwebtest/supplemental/status-500.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "video": { - "w": 900, - "h": 250, - "mimes": [ - "video/x-flv", - "video/mp4" - ] - }, - "ext": { - "bidder": { - "aid": 1000 - } - } - } - ] - }, - - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://ghb.spotim.market/pbs/ortb?aid=1000", - "body": { - "id": "test-request-id", - "imp": [ - { - "id":"test-imp-id", - "video": { - "w": 900, - "h": 250, - "mimes": [ - "video/x-flv", - "video/mp4" - ] - }, - "ext": { - "openweb": { - "aid": 1000 - } - } - } - ] - }, - "impIDs":["test-imp-id"] - }, - "mockResponse": { - "status": 500, - "body": "Internal error" - } - } - ], - - "expectedMakeBidsErrors": [ - { - "value": "Remote server error: \"Internal error\"", - "comparison": "literal" - } - ], - - "expectedBidResponses": [] -} diff --git a/adapters/openweb/params_test.go b/adapters/openweb/params_test.go index 7a53124fa30..73fb20a7e9b 100644 --- a/adapters/openweb/params_test.go +++ b/adapters/openweb/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/openweb.json @@ -39,10 +39,8 @@ func TestInvalidParams(t *testing.T) { } var validParams = []string{ - `{"aid":123}`, - `{"aid":123,"placementId":1234}`, - `{"aid":123,"siteId":4321}`, - `{"aid":123,"siteId":0,"bidFloor":0}`, + `{"aid":123,"placementId":"1234"}`, + `{"org":"123","placementId":"1234"}`, } var invalidParams = []string{ @@ -53,8 +51,10 @@ var invalidParams = []string{ `4.2`, `[]`, `{}`, - `{"aid":"some string instead of int"}`, - `{"aid":"0"}`, + `{"org":123}`, + `{"org":0}`, + `{"org":"123","placementId":123}`, + `{"org":123, "placementId":"123"}`, + `{"aid":123}`, `{"aid":"123","placementId":"123"}`, - `{"aid":123, "placementId":"123", "siteId":"321"}`, } diff --git a/adapters/openx/openx.go b/adapters/openx/openx.go index e59dab534a4..5ba3a2991cc 100644 --- a/adapters/openx/openx.go +++ b/adapters/openx/openx.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) const hbconfig = "hb_pbs_1.0.0" @@ -117,14 +118,14 @@ func (a *OpenxAdapter) makeRequest(request *openrtb2.BidRequest) (*adapters.Requ // Mutate the imp to get it ready to send to openx. func preprocess(imp *openrtb2.Imp, reqExt *openxReqExt) error { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return &errortypes.BadInput{ Message: err.Error(), } } var openxExt openrtb_ext.ExtImpOpenx - if err := json.Unmarshal(bidderExt.Bidder, &openxExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &openxExt); err != nil { return &errortypes.BadInput{ Message: err.Error(), } @@ -133,14 +134,17 @@ func preprocess(imp *openrtb2.Imp, reqExt *openxReqExt) error { reqExt.DelDomain = openxExt.DelDomain reqExt.Platform = openxExt.Platform - imp.TagID = openxExt.Unit - if imp.BidFloor == 0 && openxExt.CustomFloor > 0 { - imp.BidFloor = openxExt.CustomFloor + imp.TagID = openxExt.Unit.String() + if imp.BidFloor == 0 { + customFloor, err := openxExt.CustomFloor.Float64() + if err == nil && customFloor > 0 { + imp.BidFloor = customFloor + } } // outgoing imp.ext should be same as incoming imp.ext minus prebid and bidder impExt := openxImpExt{} - if err := json.Unmarshal(imp.Ext, &impExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &impExt); err != nil { return &errortypes.BadInput{ Message: err.Error(), } @@ -170,7 +174,7 @@ func preprocess(imp *openrtb2.Imp, reqExt *openxReqExt) error { if imp.Video != nil { videoCopy := *imp.Video - if bidderExt.Prebid != nil && bidderExt.Prebid.IsRewardedInventory != nil && *bidderExt.Prebid.IsRewardedInventory == 1 { + if imp.Rwdd == 1 { videoCopy.Ext = json.RawMessage(`{"rewarded":1}`) } else { videoCopy.Ext = nil @@ -199,7 +203,7 @@ func (a *OpenxAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRe } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } @@ -212,7 +216,7 @@ func (a *OpenxAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRe if bidResp.Ext != nil { var bidRespExt openxRespExt - if err := json.Unmarshal(bidResp.Ext, &bidRespExt); err == nil && bidRespExt.FledgeAuctionConfigs != nil { + if err := jsonutil.Unmarshal(bidResp.Ext, &bidRespExt); err == nil && bidRespExt.FledgeAuctionConfigs != nil { bidResponse.FledgeAuctionConfigs = make([]*openrtb_ext.FledgeAuctionConfig, 0, len(bidRespExt.FledgeAuctionConfigs)) for impId, config := range bidRespExt.FledgeAuctionConfigs { fledgeAuctionConfig := &openrtb_ext.FledgeAuctionConfig{ @@ -228,14 +232,26 @@ func (a *OpenxAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRe for _, sb := range bidResp.SeatBid { for i := range sb.Bid { bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ - Bid: &sb.Bid[i], - BidType: getMediaTypeForImp(sb.Bid[i].ImpID, internalRequest.Imp), + Bid: &sb.Bid[i], + BidType: getMediaTypeForImp(sb.Bid[i].ImpID, internalRequest.Imp), + BidVideo: getBidVideo(&sb.Bid[i]), }) } } return bidResponse, nil } +func getBidVideo(bid *openrtb2.Bid) *openrtb_ext.ExtBidPrebidVideo { + var primaryCategory string + if len(bid.Cat) > 0 { + primaryCategory = bid.Cat[0] + } + return &openrtb_ext.ExtBidPrebidVideo{ + PrimaryCategory: primaryCategory, + Duration: int(bid.Dur), + } +} + // getMediaTypeForImp figures out which media type this bid is for. // // OpenX doesn't support multi-type impressions. diff --git a/adapters/openx/openx_test.go b/adapters/openx/openx_test.go index 6f3796929a5..092e9190f90 100644 --- a/adapters/openx/openx_test.go +++ b/adapters/openx/openx_test.go @@ -5,10 +5,10 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/openx/openxtest/exemplary/optional-params.json b/adapters/openx/openxtest/exemplary/optional-params.json index ff8c9f56549..7486cc756d1 100644 --- a/adapters/openx/openxtest/exemplary/optional-params.json +++ b/adapters/openx/openxtest/exemplary/optional-params.json @@ -12,7 +12,7 @@ "unit": "539439964", "delDomain": "se-demo-d.openx.net", "platform": "PLATFORM", - "customFloor": 0.1, + "customFloor": "0.4", "customParams": {"foo": "bar"} } } @@ -25,7 +25,7 @@ }, "ext": { "bidder": { - "unit": "539439964", + "unit": 539439964, "delDomain": "se-demo-d.openx.net", "platform": "PLATFORM", "customFloor": 0.1 @@ -48,7 +48,7 @@ "format": [{"w": 728, "h": 90}] }, "tagid": "539439964", - "bidfloor": 0.1, + "bidfloor": 0.4, "ext": { "customParams": {"foo": "bar"} } diff --git a/adapters/openx/openxtest/exemplary/simple-video.json b/adapters/openx/openxtest/exemplary/simple-video.json index 4b7d7798b96..e6b67775999 100644 --- a/adapters/openx/openxtest/exemplary/simple-video.json +++ b/adapters/openx/openxtest/exemplary/simple-video.json @@ -60,7 +60,10 @@ "adm": "some-test-ad", "crid": "crid_10", "w": 1024, - "h": 576 + "h": 576, + "cattax": 1, + "cat": ["IAB20"], + "dur": 30 }] } ] @@ -82,7 +85,14 @@ "adm": "some-test-ad", "crid": "crid_10", "w": 1024, - "h": 576 + "h": 576, + "cattax": 1, + "cat": ["IAB20"], + "dur": 30 + }, + "video": { + "duration": 30, + "primary_category": "IAB20" }, "type": "video" } diff --git a/adapters/openx/openxtest/exemplary/video-rewarded.json b/adapters/openx/openxtest/exemplary/video-rewarded.json index f2eee34b465..58eadd7df9f 100644 --- a/adapters/openx/openxtest/exemplary/video-rewarded.json +++ b/adapters/openx/openxtest/exemplary/video-rewarded.json @@ -14,13 +14,11 @@ } }, "instl": 1, + "rwdd": 1, "ext": { "bidder": { "unit": "539439964", "delDomain": "se-demo-d.openx.net" - }, - "prebid": { - "is_rewarded_inventory": 1 } } } @@ -46,7 +44,8 @@ } }, "tagid": "539439964", - "instl": 1 + "instl": 1, + "rwdd": 1 } ], "ext": { diff --git a/adapters/openx/openxtest/supplemental/multi-imp.json b/adapters/openx/openxtest/supplemental/multi-imp.json index c6b770e3a85..d49660a1541 100644 --- a/adapters/openx/openxtest/supplemental/multi-imp.json +++ b/adapters/openx/openxtest/supplemental/multi-imp.json @@ -7,7 +7,7 @@ "banner": {}, "ext": { "bidder": { - "unit": "banner-unit-1", + "unit": "111", "delDomain": "se-demo-d.openx.net" } } @@ -17,7 +17,7 @@ "video": {"mimes": ["video/mp4"]}, "ext": { "bidder": { - "unit": "video-unit-1", + "unit": "333", "delDomain": "se-demo-d.openx.net" } } @@ -27,7 +27,7 @@ "banner": {}, "ext": { "bidder": { - "unit": "banner-unit-2", + "unit": "222", "delDomain": "se-demo-d.openx.net" } } @@ -37,7 +37,7 @@ "video": {"mimes": ["video/mp4"]}, "ext": { "bidder": { - "unit": "video-unit-2", + "unit": "444", "delDomain": "se-demo-d.openx.net" } } @@ -48,7 +48,7 @@ "video": {"mimes": ["video/mp4"]}, "ext": { "bidder": { - "unit": "multi-type-unit", + "unit": "555", "delDomain": "se-demo-d.openx.net" } } @@ -66,18 +66,18 @@ { "id": "banner-imp-1", "banner": {}, - "tagid": "banner-unit-1" + "tagid": "111" }, { "id": "banner-imp-2", "banner": {}, - "tagid": "banner-unit-2" + "tagid": "222" }, { "id": "multi-type-imp", "banner": {}, "video": {"mimes": ["video/mp4"]}, - "tagid": "multi-type-unit" + "tagid": "555" } ], "ext": { @@ -125,7 +125,7 @@ { "id": "video-imp-1", "video": {"mimes": ["video/mp4"]}, - "tagid": "video-unit-1" + "tagid": "333" } ], "ext": { @@ -163,7 +163,7 @@ { "id": "video-imp-2", "video": {"mimes": ["video/mp4"]}, - "tagid": "video-unit-2" + "tagid": "444" } ], "ext": { diff --git a/adapters/openx/params_test.go b/adapters/openx/params_test.go index 4e081dba7e5..0becd9b206e 100644 --- a/adapters/openx/params_test.go +++ b/adapters/openx/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/openx.json @@ -40,14 +40,17 @@ func TestInvalidParams(t *testing.T) { } var validParams = []string{ + `{"unit": 123, "delDomain": "foo.ba"}`, `{"unit": "123", "delDomain": "foo.ba"}`, `{"unit": "123", "delDomain": "foo.bar"}`, `{"unit": "123", "delDomain": "foo.bar", "customFloor": 0.1}`, + `{"unit": "123", "delDomain": "foo.bar", "customFloor": "0.1"}`, `{"unit": "123", "delDomain": "foo.bar", "customParams": {"foo": "bar"}}`, `{"unit": "123", "delDomain": "foo.bar", "customParams": {"foo": ["bar", "baz"]}}`, } var invalidParams = []string{ + `{"unit": "", "delDomain": "foo.bar"}`, `{"unit": "123"}`, `{"delDomain": "foo.bar"}`, `{"unit": "", "delDomain": "foo.bar"}`, @@ -56,7 +59,10 @@ var invalidParams = []string{ `{"unit": "123", "delDomain": "foo.b"}`, `{"unit": "123", "delDomain": "foo.barr"}`, `{"unit": "123", "delDomain": ".bar"}`, - `{"unit": "123", "delDomain": "foo.bar", "customFloor": "0.1"}`, + `{"unit": "123", "delDomain": "foo.bar", "customFloor": ""}`, + `{"unit": "123", "delDomain": "foo.bar", "customFloor": "1."}`, + `{"unit": "123", "delDomain": "foo.bar", "customFloor": "1.0x"}`, + `{"unit": "123", "delDomain": "foo.bar", "customFloor": "-0.1"}`, `{"unit": "123", "delDomain": "foo.bar", "customFloor": -0.1}`, `{"unit": "123", "delDomain": "foo.bar", "customParams": "foo: bar"}`, } diff --git a/adapters/operaads/operaads.go b/adapters/operaads/operaads.go index 21aecd63226..47c372becaf 100644 --- a/adapters/operaads/operaads.go +++ b/adapters/operaads/operaads.go @@ -8,12 +8,13 @@ import ( "strings" "text/template" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/ptrutil" "github.com/prebid/openrtb/v20/openrtb2" ) @@ -57,14 +58,14 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E for _, imp := range request.Imp { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { errs = append(errs, &errortypes.BadInput{ Message: err.Error(), }) continue } var operaadsExt openrtb_ext.ImpExtOperaads - if err := json.Unmarshal(bidderExt.Bidder, &operaadsExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &operaadsExt); err != nil { errs = append(errs, &errortypes.BadInput{ Message: err.Error(), }) @@ -158,7 +159,7 @@ func convertImpression(imp *openrtb2.Imp) error { } if imp.Native != nil && imp.Native.Request != "" { v := make(map[string]interface{}) - err := json.Unmarshal([]byte(imp.Native.Request), &v) + err := jsonutil.Unmarshal([]byte(imp.Native.Request), &v) if err != nil { return err } @@ -214,7 +215,7 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest } var parsedResponse openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &parsedResponse); err != nil { + if err := jsonutil.Unmarshal(response.Body, &parsedResponse); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: err.Error(), }} diff --git a/adapters/operaads/operaads_test.go b/adapters/operaads/operaads_test.go index 4e51c8393aa..8614e77e7e4 100644 --- a/adapters/operaads/operaads_test.go +++ b/adapters/operaads/operaads_test.go @@ -3,9 +3,9 @@ package operaads import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/operaads/params_test.go b/adapters/operaads/params_test.go index 1da80aa8ce3..b845fde89b3 100644 --- a/adapters/operaads/params_test.go +++ b/adapters/operaads/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/operaads.json diff --git a/adapters/oraki/oraki.go b/adapters/oraki/oraki.go new file mode 100644 index 00000000000..db6876f2e03 --- /dev/null +++ b/adapters/oraki/oraki.go @@ -0,0 +1,153 @@ +package oraki + +import ( + "encoding/json" + "fmt" + "net/http" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" +) + +type adapter struct { + endpoint string +} + +type reqBodyExt struct { + OrakiBidderExt reqBodyExtBidder `json:"bidder"` +} + +type reqBodyExtBidder struct { + Type string `json:"type"` + PlacementID string `json:"placementId,omitempty"` + EndpointID string `json:"endpointId,omitempty"` +} + +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + bidder := &adapter{ + endpoint: config.Endpoint, + } + return bidder, nil +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + var errs []error + var adapterRequests []*adapters.RequestData + + reqCopy := *request + for _, imp := range request.Imp { + reqCopy.Imp = []openrtb2.Imp{imp} + + var bidderExt adapters.ExtImpBidder + var orakiExt openrtb_ext.ImpExtOraki + + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { + errs = append(errs, err) + continue + } + if err := jsonutil.Unmarshal(bidderExt.Bidder, &orakiExt); err != nil { + errs = append(errs, err) + continue + } + + impExt := reqBodyExt{OrakiBidderExt: reqBodyExtBidder{}} + + if orakiExt.PlacementID != "" { + impExt.OrakiBidderExt.PlacementID = orakiExt.PlacementID + impExt.OrakiBidderExt.Type = "publisher" + } else if orakiExt.EndpointID != "" { + impExt.OrakiBidderExt.EndpointID = orakiExt.EndpointID + impExt.OrakiBidderExt.Type = "network" + } + + finalyImpExt, err := json.Marshal(impExt) + if err != nil { + errs = append(errs, err) + continue + } + + reqCopy.Imp[0].Ext = finalyImpExt + + adapterReq, err := a.makeRequest(&reqCopy) + if err != nil { + errs = append(errs, err) + continue + } + + adapterRequests = append(adapterRequests, adapterReq) + } + + return adapterRequests, nil +} + +func (a *adapter) makeRequest(request *openrtb2.BidRequest) (*adapters.RequestData, error) { + reqJSON, err := json.Marshal(request) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + headers.Add("Accept", "application/json") + return &adapters.RequestData{ + Method: "POST", + Uri: a.endpoint, + Body: reqJSON, + Headers: headers, + ImpIDs: openrtb_ext.GetImpIDs(request.Imp), + }, nil +} + +func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if adapters.IsResponseStatusCodeNoContent(responseData) { + return nil, nil + } + + if err := adapters.CheckResponseStatusCodeForErrors(responseData); err != nil { + return nil, []error{err} + } + + var response openrtb2.BidResponse + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { + return nil, []error{err} + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) + if len(response.Cur) != 0 { + bidResponse.Currency = response.Cur + } + + for _, seatBid := range response.SeatBid { + for i := range seatBid.Bid { + bid := seatBid.Bid[i] + bidType, err := getBidType(bid) + if err != nil { + return nil, []error{err} + } + + b := &adapters.TypedBid{ + Bid: &seatBid.Bid[i], + BidType: bidType, + } + bidResponse.Bids = append(bidResponse.Bids, b) + } + } + return bidResponse, nil +} + +func getBidType(bid openrtb2.Bid) (openrtb_ext.BidType, error) { + // determinate media type by bid response field mtype + switch bid.MType { + case openrtb2.MarkupBanner: + return openrtb_ext.BidTypeBanner, nil + case openrtb2.MarkupVideo: + return openrtb_ext.BidTypeVideo, nil + case openrtb2.MarkupNative: + return openrtb_ext.BidTypeNative, nil + } + + return "", fmt.Errorf("could not define media type for impression: %s", bid.ImpID) +} diff --git a/adapters/oraki/oraki_test.go b/adapters/oraki/oraki_test.go new file mode 100644 index 00000000000..753357c29fd --- /dev/null +++ b/adapters/oraki/oraki_test.go @@ -0,0 +1,20 @@ +package oraki + +import ( + "testing" + + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderOraki, config.Adapter{ + Endpoint: "https://fake.test.io/pserver"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "orakitest", bidder) +} diff --git a/adapters/oraki/orakitest/exemplary/endpointId.json b/adapters/oraki/orakitest/exemplary/endpointId.json new file mode 100644 index 00000000000..fb211d4e765 --- /dev/null +++ b/adapters/oraki/orakitest/exemplary/endpointId.json @@ -0,0 +1,136 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "endpointId": "test" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://fake.test.io/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "endpointId": "test", + "type": "network" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ], + "seat": "oraki" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/oraki/orakitest/exemplary/multi-format.json b/adapters/oraki/orakitest/exemplary/multi-format.json new file mode 100644 index 00000000000..cb1c6ffd9c6 --- /dev/null +++ b/adapters/oraki/orakitest/exemplary/multi-format.json @@ -0,0 +1,105 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "endpointId": "test" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://fake.test.io/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "endpointId": "test", + "type": "network" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 204 + } + } + ], + "expectedBidResponses": [] +} \ No newline at end of file diff --git a/adapters/oraki/orakitest/exemplary/multi-imp.json b/adapters/oraki/orakitest/exemplary/multi-imp.json new file mode 100644 index 00000000000..43bbf483960 --- /dev/null +++ b/adapters/oraki/orakitest/exemplary/multi-imp.json @@ -0,0 +1,253 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id1", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "endpointId": "test" + } + } + }, + { + "id": "test-imp-id2", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "endpointId": "test" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://fake.test.io/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id1", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "endpointId": "test", + "type": "network" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + } + }, + "impIDs":["test-imp-id1"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id1", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ], + "seat": "oraki" + } + ], + "cur": "USD" + } + } + }, + { + "expectedRequest": { + "uri": "https://fake.test.io/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id2", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "endpointId": "test", + "type": "network" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + } + }, + "impIDs":["test-imp-id2"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id2", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ], + "seat": "oraki" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id1", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + }, + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id2", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/oraki/orakitest/exemplary/simple-banner.json b/adapters/oraki/orakitest/exemplary/simple-banner.json new file mode 100644 index 00000000000..ee6352c92c9 --- /dev/null +++ b/adapters/oraki/orakitest/exemplary/simple-banner.json @@ -0,0 +1,136 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://fake.test.io/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ], + "seat": "oraki" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/oraki/orakitest/exemplary/simple-native.json b/adapters/oraki/orakitest/exemplary/simple-native.json new file mode 100644 index 00000000000..f517a686ccd --- /dev/null +++ b/adapters/oraki/orakitest/exemplary/simple-native.json @@ -0,0 +1,120 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "native": { + "request": "{\"ver\":\"1.1\",\"layout\":1,\"adunit\":2,\"plcmtcnt\":6,\"plcmttype\":4,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"wmin\":492,\"hmin\":328,\"type\":3,\"mimes\":[\"image/jpeg\",\"image/jpg\",\"image/png\"]}},{\"id\":4,\"required\":0,\"data\":{\"type\":6}},{\"id\":5,\"required\":0,\"data\":{\"type\":7}},{\"id\":6,\"required\":0,\"data\":{\"type\":1,\"len\":20}}]}", + "ver": "1.1" + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://fake.test.io/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "native": { + "request": "{\"ver\":\"1.1\",\"layout\":1,\"adunit\":2,\"plcmtcnt\":6,\"plcmttype\":4,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"wmin\":492,\"hmin\":328,\"type\":3,\"mimes\":[\"image/jpeg\",\"image/jpg\",\"image/png\"]}},{\"id\":4,\"required\":0,\"data\":{\"type\":6}},{\"id\":5,\"required\":0,\"data\":{\"type\":7}},{\"id\":6,\"required\":0,\"data\":{\"type\":1,\"len\":20}}]}", + "ver": "1.1" + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 4, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "native" + } + } + } + ], + "seat": "oraki" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 4, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "native" + } + } + }, + "type": "native" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/oraki/orakitest/exemplary/simple-video.json b/adapters/oraki/orakitest/exemplary/simple-video.json new file mode 100644 index 00000000000..d51d8b59f75 --- /dev/null +++ b/adapters/oraki/orakitest/exemplary/simple-video.json @@ -0,0 +1,131 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://fake.test.io/pserver", + "body": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ] + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "00:01:00", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 2, + "ext": { + "prebid": { + "type": "video" + } + } + } + ], + "seat": "oraki" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "00:01:00", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 2, + "ext": { + "prebid": { + "type": "video" + } + } + }, + "type": "video" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/oraki/orakitest/exemplary/simple-web-banner.json b/adapters/oraki/orakitest/exemplary/simple-web-banner.json new file mode 100644 index 00000000000..7b890db4e9f --- /dev/null +++ b/adapters/oraki/orakitest/exemplary/simple-web-banner.json @@ -0,0 +1,136 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "site": { + "id": "1", + "domain": "test.com" + }, + "device": { + "ip": "123.123.123.123", + "ua": "Ubuntu" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://fake.test.io/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "site": { + "id": "1", + "domain": "test.com" + }, + "device": { + "ip": "123.123.123.123", + "ua": "Ubuntu" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 468, + "h": 60, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ], + "seat": "oraki" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 468, + "h": 60, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/oraki/orakitest/supplemental/bad_media_type.json b/adapters/oraki/orakitest/supplemental/bad_media_type.json new file mode 100644 index 00000000000..0708ed4ae31 --- /dev/null +++ b/adapters/oraki/orakitest/supplemental/bad_media_type.json @@ -0,0 +1,83 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://fake.test.io/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "w": 300, + "h": 250, + "ext": {} + } + ], + "seat": "oraki" + } + ], + "cur": "USD" + } + } + }], + "expectedMakeBidsErrors": [ + { + "value": "could not define media type for impression: test-imp-id", + "comparison": "literal" + } + ] +} diff --git a/adapters/oraki/orakitest/supplemental/bad_response.json b/adapters/oraki/orakitest/supplemental/bad_response.json new file mode 100644 index 00000000000..4fe8d572c46 --- /dev/null +++ b/adapters/oraki/orakitest/supplemental/bad_response.json @@ -0,0 +1,85 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://fake.test.io/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": "" + } + }], + "expectedMakeBidsErrors": [ + { + "value": "expect { or n, but found \"", + "comparison": "literal" + } + ] +} diff --git a/adapters/oraki/orakitest/supplemental/status-204.json b/adapters/oraki/orakitest/supplemental/status-204.json new file mode 100644 index 00000000000..f72a2eb0607 --- /dev/null +++ b/adapters/oraki/orakitest/supplemental/status-204.json @@ -0,0 +1,80 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://fake.test.io/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 204, + "body": {} + } + }], + "expectedBidResponses": [] +} diff --git a/adapters/oraki/orakitest/supplemental/status-not-200.json b/adapters/oraki/orakitest/supplemental/status-not-200.json new file mode 100644 index 00000000000..218aa632618 --- /dev/null +++ b/adapters/oraki/orakitest/supplemental/status-not-200.json @@ -0,0 +1,85 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://fake.test.io/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 404, + "body": {} + } + }], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 404. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} diff --git a/adapters/oraki/params_test.go b/adapters/oraki/params_test.go new file mode 100644 index 00000000000..24fc6ea29ef --- /dev/null +++ b/adapters/oraki/params_test.go @@ -0,0 +1,47 @@ +package oraki + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v3/openrtb_ext" +) + +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json schema. %v", err) + } + + for _, p := range validParams { + if err := validator.Validate(openrtb_ext.BidderOraki, json.RawMessage(p)); err != nil { + t.Errorf("Schema rejected valid params: %s", p) + } + } +} + +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json schema. %v", err) + } + + for _, p := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderOraki, json.RawMessage(p)); err == nil { + t.Errorf("Schema allowed invalid params: %s", p) + } + } +} + +var validParams = []string{ + `{"placementId": "test"}`, + `{"placementId": "1"}`, + `{"endpointId": "test"}`, + `{"endpointId": "1"}`, +} + +var invalidParams = []string{ + `{"placementId": 42}`, + `{"endpointId": 42}`, + `{"placementId": "1", "endpointId": "1"}`, +} diff --git a/adapters/orbidder/orbidder.go b/adapters/orbidder/orbidder.go index 0e8edaeb0bb..b2f6705273f 100644 --- a/adapters/orbidder/orbidder.go +++ b/adapters/orbidder/orbidder.go @@ -8,10 +8,11 @@ import ( "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type OrbidderAdapter struct { @@ -68,14 +69,14 @@ func getValidImpressions(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRe func preprocessExtensions(imp *openrtb2.Imp) error { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return &errortypes.BadInput{ Message: err.Error(), } } var orbidderExt openrtb_ext.ExtImpOrbidder - if err := json.Unmarshal(bidderExt.Bidder, &orbidderExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &orbidderExt); err != nil { return &errortypes.BadInput{ Message: "Wrong orbidder bidder ext: " + err.Error(), } @@ -122,7 +123,7 @@ func (rcv OrbidderAdapter) MakeBids(_ *openrtb2.BidRequest, _ *adapters.RequestD } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } diff --git a/adapters/orbidder/orbidder_test.go b/adapters/orbidder/orbidder_test.go index a97fc307c92..ce26bdd7f2b 100644 --- a/adapters/orbidder/orbidder_test.go +++ b/adapters/orbidder/orbidder_test.go @@ -8,10 +8,10 @@ import ( "github.com/prebid/openrtb/v20/openrtb2" "github.com/stretchr/testify/mock" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/orbidder/orbiddertest/supplemental/ext-unmarshall-error.json b/adapters/orbidder/orbiddertest/supplemental/ext-unmarshall-error.json index 447e2985f92..6f9372baa9c 100644 --- a/adapters/orbidder/orbiddertest/supplemental/ext-unmarshall-error.json +++ b/adapters/orbidder/orbiddertest/supplemental/ext-unmarshall-error.json @@ -25,7 +25,7 @@ }, "expectedMakeRequestsErrors": [ { - "value": "Wrong orbidder bidder ext: json: cannot unmarshal array into Go struct field ExtImpOrbidder.accountId of type string", + "value": "Wrong orbidder bidder ext: cannot unmarshal openrtb_ext.ExtImpOrbidder.AccountId: expects \" or n, but found [", "comparison": "literal" } ] diff --git a/adapters/orbidder/orbiddertest/supplemental/valid-and-invalid-imps.json b/adapters/orbidder/orbiddertest/supplemental/valid-and-invalid-imps.json index f12e26e18e2..8f95e6c5ec9 100644 --- a/adapters/orbidder/orbiddertest/supplemental/valid-and-invalid-imps.json +++ b/adapters/orbidder/orbiddertest/supplemental/valid-and-invalid-imps.json @@ -120,8 +120,8 @@ ], "expectedMakeRequestsErrors": [ { - "value": "unexpected end of JSON input", - "comparison": "literal" + "value": "expect { or n, but found", + "comparison": "startswith" } ] } diff --git a/adapters/orbidder/params_test.go b/adapters/orbidder/params_test.go index cd95e222aee..bb557faa2c6 100644 --- a/adapters/orbidder/params_test.go +++ b/adapters/orbidder/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/orbidder.json diff --git a/adapters/outbrain/outbrain.go b/adapters/outbrain/outbrain.go index 9e588d8640c..612a9a0cbe3 100644 --- a/adapters/outbrain/outbrain.go +++ b/adapters/outbrain/outbrain.go @@ -8,10 +8,11 @@ import ( "github.com/prebid/openrtb/v20/native1" nativeResponse "github.com/prebid/openrtb/v20/native1/response" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -35,11 +36,11 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte imp := reqCopy.Imp[i] var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { errs = append(errs, err) continue } - if err := json.Unmarshal(bidderExt.Bidder, &outbrainExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &outbrainExt); err != nil { errs = append(errs, err) continue } @@ -107,7 +108,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } @@ -125,7 +126,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } if bidType == openrtb_ext.BidTypeNative { var nativePayload nativeResponse.Response - if err := json.Unmarshal(json.RawMessage(bid.AdM), &nativePayload); err != nil { + if err := jsonutil.Unmarshal(json.RawMessage(bid.AdM), &nativePayload); err != nil { errs = append(errs, err) continue } diff --git a/adapters/outbrain/outbrain_test.go b/adapters/outbrain/outbrain_test.go index 4a42679f660..1e1fc1e803d 100644 --- a/adapters/outbrain/outbrain_test.go +++ b/adapters/outbrain/outbrain_test.go @@ -3,9 +3,9 @@ package outbrain import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/outbrain/params_test.go b/adapters/outbrain/params_test.go index 666724cd6eb..e6d76d94728 100644 --- a/adapters/outbrain/params_test.go +++ b/adapters/outbrain/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/ownadx/ownadx.go b/adapters/ownadx/ownadx.go index 5c54b395ddc..737adfa30d4 100644 --- a/adapters/ownadx/ownadx.go +++ b/adapters/ownadx/ownadx.go @@ -7,11 +7,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -56,23 +57,23 @@ func createBidRequest(rtbBidRequest *openrtb2.BidRequest, imps []openrtb2.Imp) * } func (adapter *adapter) buildEndpointURL(params *openrtb_ext.ExtImpOwnAdx) (string, error) { endpointParams := macros.EndpointTemplateParams{ - ZoneID: params.SspId, - AccountID: params.SeatId, - SourceId: params.TokenId, + SspID: params.SspId, // Macro + SeatID: params.SeatId, + TokenID: params.TokenId, } return macros.ResolveMacros(adapter.endpoint, endpointParams) } func getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpOwnAdx, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: "Bidder extension not valid or can't be unmarshalled", } } var ownAdxExt openrtb_ext.ExtImpOwnAdx - if err := json.Unmarshal(bidderExt.Bidder, &ownAdxExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &ownAdxExt); err != nil { return nil, &errortypes.BadInput{ Message: "Error while unmarshaling bidder extension", } @@ -124,6 +125,7 @@ func groupImpsByExt(imps []openrtb2.Imp) (map[openrtb_ext.ExtImpOwnAdx][]openrtb } func (adapter *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if response.StatusCode == http.StatusNoContent { return nil, nil } @@ -142,7 +144,7 @@ func (adapter *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalR } } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{ &errortypes.BadServerResponse{ Message: "Bad server response ", @@ -159,6 +161,7 @@ func (adapter *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalR seatBid := bidResp.SeatBid[0] bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(bidResp.SeatBid[0].Bid)) + if len(seatBid.Bid) == 0 { return nil, []error{ &errortypes.BadServerResponse{ @@ -169,7 +172,6 @@ func (adapter *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalR for i := 0; i < len(seatBid.Bid); i++ { var bidType openrtb_ext.BidType bid := seatBid.Bid[i] - bidType, err := getMediaType(bid) if err != nil { return nil, []error{&errortypes.BadServerResponse{ diff --git a/adapters/ownadx/ownadx_test.go b/adapters/ownadx/ownadx_test.go index 07dc928b9b0..6921e1ba123 100644 --- a/adapters/ownadx/ownadx_test.go +++ b/adapters/ownadx/ownadx_test.go @@ -3,15 +3,15 @@ package ownadx import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) func TestJsonSamples(t *testing.T) { bidder, buildErr := Builder(openrtb_ext.BidderOwnAdx, config.Adapter{ - Endpoint: "https://pbs.prebid-ownadx.com/bidder/bid/{{.AccountID}}/{{.ZoneID}}?token={{.SourceId}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + Endpoint: "https://pbs.prebid-ownadx.com/bidder/bid/{{.SeatID}}/{{.SspID}}?token={{.TokenID}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) assert.NoError(t, buildErr) adapterstest.RunJSONBidderTest(t, "ownadxtest", bidder) diff --git a/adapters/pangle/pangle.go b/adapters/pangle/pangle.go index b46e2c669b7..a86052d649d 100644 --- a/adapters/pangle/pangle.go +++ b/adapters/pangle/pangle.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -81,13 +82,13 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte requestCopy := *request for _, imp := range request.Imp { var impExt wrappedExtImpBidder - if err := json.Unmarshal(imp.Ext, &impExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &impExt); err != nil { errs = append(errs, fmt.Errorf("failed unmarshalling imp ext (err)%s", err.Error())) continue } // get token & networkIDs var bidderImpExt openrtb_ext.ImpExtPangle - if err := json.Unmarshal(impExt.Bidder, &bidderImpExt); err != nil { + if err := jsonutil.Unmarshal(impExt.Bidder, &bidderImpExt); err != nil { errs = append(errs, fmt.Errorf("failed unmarshalling bidder imp ext (err)%s", err.Error())) continue } @@ -147,7 +148,7 @@ func getMediaTypeForBid(bid *openrtb2.Bid) (openrtb_ext.BidType, error) { } var bidExt pangleBidExt - if err := json.Unmarshal(bid.Ext, &bidExt); err != nil { + if err := jsonutil.Unmarshal(bid.Ext, &bidExt); err != nil { return "", fmt.Errorf("invalid bid ext") } else if bidExt.Pangle == nil || bidExt.Pangle.AdType == nil { return "", fmt.Errorf("missing pangleExt/adtype in bid ext") @@ -189,7 +190,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } diff --git a/adapters/pangle/pangle_test.go b/adapters/pangle/pangle_test.go index 243bbadc90a..2143d4f90af 100644 --- a/adapters/pangle/pangle_test.go +++ b/adapters/pangle/pangle_test.go @@ -3,9 +3,9 @@ package pangle import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/pangle/param_test.go b/adapters/pangle/param_test.go index e25b7d740c4..57acfb0609a 100644 --- a/adapters/pangle/param_test.go +++ b/adapters/pangle/param_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/pgamssp/params_test.go b/adapters/pgamssp/params_test.go index d2f06cbcfa8..ec95d47e5fa 100644 --- a/adapters/pgamssp/params_test.go +++ b/adapters/pgamssp/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/pgamssp/pgamssp.go b/adapters/pgamssp/pgamssp.go index 2f8360fb2e8..6ddf21159e0 100644 --- a/adapters/pgamssp/pgamssp.go +++ b/adapters/pgamssp/pgamssp.go @@ -4,11 +4,13 @@ import ( "encoding/json" "fmt" "net/http" + "strings" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -38,15 +40,26 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E reqCopy := *request for _, imp := range request.Imp { + + // Check if imp comes with bid floor amount defined in a foreign currency + if imp.BidFloor > 0 && imp.BidFloorCur != "" && strings.ToUpper(imp.BidFloorCur) != "USD" { + // Convert to US dollars + convertedValue, err := reqInfo.ConvertCurrency(imp.BidFloor, imp.BidFloorCur, "USD") + if err == nil { + imp.BidFloorCur = "USD" + imp.BidFloor = convertedValue + } + } + reqCopy.Imp = []openrtb2.Imp{imp} var bidderExt adapters.ExtImpBidder var pgamExt openrtb_ext.ImpExtPgamSsp - if err = json.Unmarshal(reqCopy.Imp[0].Ext, &bidderExt); err != nil { + if err = jsonutil.Unmarshal(reqCopy.Imp[0].Ext, &bidderExt); err != nil { return nil, []error{err} } - if err = json.Unmarshal(bidderExt.Bidder, &pgamExt); err != nil { + if err = jsonutil.Unmarshal(bidderExt.Bidder, &pgamExt); err != nil { return nil, []error{err} } @@ -107,7 +120,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } diff --git a/adapters/pgamssp/pgamssp_test.go b/adapters/pgamssp/pgamssp_test.go index 10e72f5d093..450eb0f0b5f 100644 --- a/adapters/pgamssp/pgamssp_test.go +++ b/adapters/pgamssp/pgamssp_test.go @@ -3,9 +3,9 @@ package pgamssp import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/pgamssp/pgamssptest/exemplary/convert_currency.json b/adapters/pgamssp/pgamssptest/exemplary/convert_currency.json new file mode 100644 index 00000000000..bdb2027714b --- /dev/null +++ b/adapters/pgamssp/pgamssptest/exemplary/convert_currency.json @@ -0,0 +1,154 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "bidfloor": 1, + "bidfloorcur": "GBP", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "ext": { + "prebid": { + "currency": { + "rates": { + "GBP": { + "USD": 0.05 + } + } + } + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://test.com/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "bidfloor": 0.05, + "bidfloorcur": "USD", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "ext": { + "prebid": { + "currency": { + "rates": { + "GBP": { + "USD": 0.05 + } + } + } + } + } + }, + "impIDs": [ + "test-imp-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "w": 300, + "h": 250, + "mtype": 1 + } + ], + "seat": "pgamssp" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/pgamssp/pgamssptest/supplemental/bad_response.json b/adapters/pgamssp/pgamssptest/supplemental/bad_response.json index 53446fb8ab9..36f5e7ba4d0 100644 --- a/adapters/pgamssp/pgamssptest/supplemental/bad_response.json +++ b/adapters/pgamssp/pgamssptest/supplemental/bad_response.json @@ -78,7 +78,7 @@ }], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/playdigo/params_test.go b/adapters/playdigo/params_test.go index ba18c1fb216..cb0fa0c6815 100644 --- a/adapters/playdigo/params_test.go +++ b/adapters/playdigo/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/playdigo/playdigo.go b/adapters/playdigo/playdigo.go index d8450bdd798..fe0091e2cbd 100644 --- a/adapters/playdigo/playdigo.go +++ b/adapters/playdigo/playdigo.go @@ -7,9 +7,10 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -44,11 +45,11 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E var bidderExt adapters.ExtImpBidder var playdigoExt openrtb_ext.ImpExtPlaydigo - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { errs = append(errs, err) continue } - if err := json.Unmarshal(bidderExt.Bidder, &playdigoExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &playdigoExt); err != nil { errs = append(errs, err) continue } @@ -116,7 +117,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } diff --git a/adapters/playdigo/playdigo_test.go b/adapters/playdigo/playdigo_test.go index f7424ca583d..275924f1936 100644 --- a/adapters/playdigo/playdigo_test.go +++ b/adapters/playdigo/playdigo_test.go @@ -3,9 +3,9 @@ package playdigo import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/playdigo/playdigotest/supplemental/bad_response.json b/adapters/playdigo/playdigotest/supplemental/bad_response.json index afa17aa2e87..4e4b3ef9671 100644 --- a/adapters/playdigo/playdigotest/supplemental/bad_response.json +++ b/adapters/playdigo/playdigotest/supplemental/bad_response.json @@ -78,7 +78,7 @@ }], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/pubmatic/params_test.go b/adapters/pubmatic/params_test.go index d5d1d46842f..531416f1877 100644 --- a/adapters/pubmatic/params_test.go +++ b/adapters/pubmatic/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/pubmatic.json diff --git a/adapters/pubmatic/pubmatic.go b/adapters/pubmatic/pubmatic.go index 9c5799eece7..bcff41d43f1 100644 --- a/adapters/pubmatic/pubmatic.go +++ b/adapters/pubmatic/pubmatic.go @@ -9,11 +9,12 @@ import ( "strconv" "strings" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/ptrutil" "github.com/buger/jsonparser" "github.com/prebid/openrtb/v20/openrtb2" @@ -260,12 +261,12 @@ func parseImpressionObject(imp *openrtb2.Imp, extractWrapperExtFromImp, extractP } var bidderExt ExtImpBidderPubmatic - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return wrapExt, pubID, err } var pubmaticExt openrtb_ext.ExtImpPubmatic - if err := json.Unmarshal(bidderExt.Bidder, &pubmaticExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &pubmaticExt); err != nil { return wrapExt, pubID, err } @@ -275,7 +276,7 @@ func parseImpressionObject(imp *openrtb2.Imp, extractWrapperExtFromImp, extractP // Parse Wrapper Extension only once per request if extractWrapperExtFromImp && len(pubmaticExt.WrapExt) != 0 { - err := json.Unmarshal([]byte(pubmaticExt.WrapExt), &wrapExt) + err := jsonutil.Unmarshal([]byte(pubmaticExt.WrapExt), &wrapExt) if err != nil { return wrapExt, pubID, fmt.Errorf("Error in Wrapper Parameters = %v for ImpID = %v WrapperExt = %v", err.Error(), imp.ID, string(pubmaticExt.WrapExt)) } @@ -346,7 +347,7 @@ func extractPubmaticExtFromRequest(request *openrtb2.BidRequest) (extRequestAdSe } reqExt := &openrtb_ext.ExtRequest{} - err := json.Unmarshal(request.Ext, &reqExt) + err := jsonutil.Unmarshal(request.Ext, &reqExt) if err != nil { return pmReqExt, fmt.Errorf("error decoding Request.ext : %s", err.Error()) } @@ -354,7 +355,7 @@ func extractPubmaticExtFromRequest(request *openrtb2.BidRequest) (extRequestAdSe reqExtBidderParams := make(map[string]json.RawMessage) if reqExt.Prebid.BidderParams != nil { - err = json.Unmarshal(reqExt.Prebid.BidderParams, &reqExtBidderParams) + err = jsonutil.Unmarshal(reqExt.Prebid.BidderParams, &reqExtBidderParams) if err != nil { return pmReqExt, err } @@ -363,7 +364,7 @@ func extractPubmaticExtFromRequest(request *openrtb2.BidRequest) (extRequestAdSe //get request ext bidder params if wrapperObj, present := reqExtBidderParams["wrapper"]; present && len(wrapperObj) != 0 { wrpExt := &pubmaticWrapperExt{} - err = json.Unmarshal(wrapperObj, wrpExt) + err = jsonutil.Unmarshal(wrapperObj, wrpExt) if err != nil { return pmReqExt, err } @@ -372,7 +373,7 @@ func extractPubmaticExtFromRequest(request *openrtb2.BidRequest) (extRequestAdSe if acatBytes, ok := reqExtBidderParams["acat"]; ok { var acat []string - err = json.Unmarshal(acatBytes, &acat) + err = jsonutil.Unmarshal(acatBytes, &acat) if err != nil { return pmReqExt, err } @@ -437,7 +438,7 @@ func (a *PubmaticAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externa } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } @@ -458,7 +459,7 @@ func (a *PubmaticAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externa } var bidExt *pubmaticBidExt - err := json.Unmarshal(bid.Ext, &bidExt) + err := jsonutil.Unmarshal(bid.Ext, &bidExt) if err != nil { errs = append(errs, err) } else if bidExt != nil { @@ -489,7 +490,7 @@ func (a *PubmaticAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externa if bidResp.Ext != nil { var bidRespExt respExt - if err := json.Unmarshal(bidResp.Ext, &bidRespExt); err == nil && bidRespExt.FledgeAuctionConfigs != nil { + if err := jsonutil.Unmarshal(bidResp.Ext, &bidRespExt); err == nil && bidRespExt.FledgeAuctionConfigs != nil { bidResponse.FledgeAuctionConfigs = make([]*openrtb_ext.FledgeAuctionConfig, 0, len(bidRespExt.FledgeAuctionConfigs)) for impId, config := range bidRespExt.FledgeAuctionConfigs { fledgeAuctionConfig := &openrtb_ext.FledgeAuctionConfig{ @@ -506,7 +507,7 @@ func (a *PubmaticAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externa func getNativeAdm(adm string) (string, error) { var err error nativeAdm := make(map[string]interface{}) - err = json.Unmarshal([]byte(adm), &nativeAdm) + err = jsonutil.Unmarshal([]byte(adm), &nativeAdm) if err != nil { return adm, errors.New("unable to unmarshal native adm") } @@ -528,7 +529,7 @@ func getNativeAdm(adm string) (string, error) { func getMapFromJSON(source json.RawMessage) map[string]interface{} { if source != nil { dataMap := make(map[string]interface{}) - err := json.Unmarshal(source, &dataMap) + err := jsonutil.Unmarshal(source, &dataMap) if err == nil { return dataMap } diff --git a/adapters/pubmatic/pubmatic_test.go b/adapters/pubmatic/pubmatic_test.go index 747dd5de0d8..9c6af0cba40 100644 --- a/adapters/pubmatic/pubmatic_test.go +++ b/adapters/pubmatic/pubmatic_test.go @@ -8,10 +8,10 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/pubmatic/pubmatictest/exemplary/video.json b/adapters/pubmatic/pubmatictest/exemplary/video.json index be24d849cca..f8bdaee6e8c 100644 --- a/adapters/pubmatic/pubmatictest/exemplary/video.json +++ b/adapters/pubmatic/pubmatictest/exemplary/video.json @@ -177,7 +177,8 @@ }, "type": "video", "video" :{ - "duration" : 5 + "duration" : 5, + "primary_category": "" } } ] diff --git a/adapters/pubmatic/pubmatictest/supplemental/app.json b/adapters/pubmatic/pubmatictest/supplemental/app.json index abe79bbe31d..67be496c5df 100644 --- a/adapters/pubmatic/pubmatictest/supplemental/app.json +++ b/adapters/pubmatic/pubmatictest/supplemental/app.json @@ -139,8 +139,8 @@ ], "expectedMakeBidsErrors": [ { - "value": "unexpected end of JSON input", - "comparison": "literal" + "value": "expect { or n, but found", + "comparison": "startswith" } ] } \ No newline at end of file diff --git a/adapters/pubnative/pubnative.go b/adapters/pubnative/pubnative.go index 89d8f9e9e77..7c77aeefc90 100644 --- a/adapters/pubnative/pubnative.go +++ b/adapters/pubnative/pubnative.go @@ -8,11 +8,12 @@ import ( "strconv" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/ptrutil" ) type PubnativeAdapter struct { @@ -37,13 +38,13 @@ func (a *PubnativeAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *a for _, imp := range request.Imp { requestCopy := *request var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { errs = append(errs, err) continue } var pubnativeExt openrtb_ext.ExtImpPubnative - if err := json.Unmarshal(bidderExt.Bidder, &pubnativeExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &pubnativeExt); err != nil { errs = append(errs, err) continue } @@ -145,7 +146,7 @@ func (a *PubnativeAdapter) MakeBids(internalRequest *openrtb2.BidRequest, extern } var parsedResponse openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &parsedResponse); err != nil { + if err := jsonutil.Unmarshal(response.Body, &parsedResponse); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: err.Error(), }} diff --git a/adapters/pubnative/pubnative_test.go b/adapters/pubnative/pubnative_test.go index b1b1bf85e05..dfc065b7166 100644 --- a/adapters/pubnative/pubnative_test.go +++ b/adapters/pubnative/pubnative_test.go @@ -3,9 +3,9 @@ package pubnative import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/pubrise/params_test.go b/adapters/pubrise/params_test.go new file mode 100644 index 00000000000..97ee8ebc5c7 --- /dev/null +++ b/adapters/pubrise/params_test.go @@ -0,0 +1,47 @@ +package pubrise + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v3/openrtb_ext" +) + +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json schema. %v", err) + } + + for _, p := range validParams { + if err := validator.Validate(openrtb_ext.BidderPubrise, json.RawMessage(p)); err != nil { + t.Errorf("Schema rejected valid params: %s", p) + } + } +} + +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json schema. %v", err) + } + + for _, p := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderPubrise, json.RawMessage(p)); err == nil { + t.Errorf("Schema allowed invalid params: %s", p) + } + } +} + +var validParams = []string{ + `{"placementId": "test"}`, + `{"placementId": "1"}`, + `{"endpointId": "test"}`, + `{"endpointId": "1"}`, +} + +var invalidParams = []string{ + `{"placementId": 42}`, + `{"endpointId": 42}`, + `{"placementId": "1", "endpointId": "1"}`, +} diff --git a/adapters/pubrise/pubrise.go b/adapters/pubrise/pubrise.go new file mode 100644 index 00000000000..80168f97256 --- /dev/null +++ b/adapters/pubrise/pubrise.go @@ -0,0 +1,160 @@ +package pubrise + +import ( + "encoding/json" + "errors" + "fmt" + "net/http" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" +) + +type adapter struct { + endpoint string +} + +type reqBodyExt struct { + PubriseBidderExt reqBodyExtBidder `json:"bidder"` +} + +type reqBodyExtBidder struct { + Type string `json:"type"` + PlacementID string `json:"placementId,omitempty"` + EndpointID string `json:"endpointId,omitempty"` +} + +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + bidder := &adapter{ + endpoint: config.Endpoint, + } + return bidder, nil +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + var errs []error + var adapterRequests []*adapters.RequestData + + reqCopy := *request + for _, imp := range request.Imp { + reqCopy.Imp = []openrtb2.Imp{imp} + + var bidderExt adapters.ExtImpBidder + var pubriseExt openrtb_ext.ImpExtPubrise + + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { + errs = append(errs, err) + continue + } + if err := jsonutil.Unmarshal(bidderExt.Bidder, &pubriseExt); err != nil { + errs = append(errs, err) + continue + } + + impExt := reqBodyExt{PubriseBidderExt: reqBodyExtBidder{}} + + if pubriseExt.PlacementID != "" { + impExt.PubriseBidderExt.PlacementID = pubriseExt.PlacementID + impExt.PubriseBidderExt.Type = "publisher" + } else if pubriseExt.EndpointID != "" { + impExt.PubriseBidderExt.EndpointID = pubriseExt.EndpointID + impExt.PubriseBidderExt.Type = "network" + } + + finalyImpExt, err := json.Marshal(impExt) + if err != nil { + errs = append(errs, err) + continue + } + + reqCopy.Imp[0].Ext = finalyImpExt + + adapterReq, err := a.makeRequest(&reqCopy) + if err != nil { + errs = append(errs, err) + continue + } + + if adapterReq != nil { + adapterRequests = append(adapterRequests, adapterReq) + } + } + + if len(adapterRequests) == 0 { + errs = append(errs, errors.New("found no valid impressions")) + return nil, errs + } + + return adapterRequests, nil +} + +func (a *adapter) makeRequest(request *openrtb2.BidRequest) (*adapters.RequestData, error) { + reqJSON, err := json.Marshal(request) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + headers.Add("Accept", "application/json") + return &adapters.RequestData{ + Method: "POST", + Uri: a.endpoint, + Body: reqJSON, + Headers: headers, + ImpIDs: openrtb_ext.GetImpIDs(request.Imp), + }, nil +} + +func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if adapters.IsResponseStatusCodeNoContent(responseData) { + return nil, nil + } + + if err := adapters.CheckResponseStatusCodeForErrors(responseData); err != nil { + return nil, []error{err} + } + + var response openrtb2.BidResponse + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { + return nil, []error{err} + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) + if len(response.Cur) != 0 { + bidResponse.Currency = response.Cur + } + + for _, seatBid := range response.SeatBid { + for i := range seatBid.Bid { + bidType, err := getBidType(seatBid.Bid[i]) + if err != nil { + return nil, []error{err} + } + + b := &adapters.TypedBid{ + Bid: &seatBid.Bid[i], + BidType: bidType, + } + bidResponse.Bids = append(bidResponse.Bids, b) + } + } + return bidResponse, nil +} + +func getBidType(bid openrtb2.Bid) (openrtb_ext.BidType, error) { + // determinate media type by bid response field mtype + switch bid.MType { + case openrtb2.MarkupBanner: + return openrtb_ext.BidTypeBanner, nil + case openrtb2.MarkupVideo: + return openrtb_ext.BidTypeVideo, nil + case openrtb2.MarkupNative: + return openrtb_ext.BidTypeNative, nil + } + + return "", fmt.Errorf("could not define media type for impression: %s", bid.ImpID) +} diff --git a/adapters/pubrise/pubrise_test.go b/adapters/pubrise/pubrise_test.go new file mode 100644 index 00000000000..9f4f2124abc --- /dev/null +++ b/adapters/pubrise/pubrise_test.go @@ -0,0 +1,20 @@ +package pubrise + +import ( + "testing" + + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderEmtv, config.Adapter{ + Endpoint: "https://backend.pubrise.ai/pserver"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "pubrisetest", bidder) +} diff --git a/adapters/pubrise/pubrisetest/exemplary/endpointId.json b/adapters/pubrise/pubrisetest/exemplary/endpointId.json new file mode 100644 index 00000000000..3766c7a3ef4 --- /dev/null +++ b/adapters/pubrise/pubrisetest/exemplary/endpointId.json @@ -0,0 +1,136 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "endpointId": "test" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://backend.pubrise.ai/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "endpointId": "test", + "type": "network" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ], + "seat": "pubrise" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/pubrise/pubrisetest/exemplary/multi-format.json b/adapters/pubrise/pubrisetest/exemplary/multi-format.json new file mode 100644 index 00000000000..9e5c2ef2c57 --- /dev/null +++ b/adapters/pubrise/pubrisetest/exemplary/multi-format.json @@ -0,0 +1,105 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "endpointId": "test" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://backend.pubrise.ai/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "endpointId": "test", + "type": "network" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 204 + } + } + ], + "expectedBidResponses": [] +} \ No newline at end of file diff --git a/adapters/pubrise/pubrisetest/exemplary/multi-imp.json b/adapters/pubrise/pubrisetest/exemplary/multi-imp.json new file mode 100644 index 00000000000..d922113a512 --- /dev/null +++ b/adapters/pubrise/pubrisetest/exemplary/multi-imp.json @@ -0,0 +1,253 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "endpointId": "test" + } + } + }, + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "endpointId": "test" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://backend.pubrise.ai/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "endpointId": "test", + "type": "network" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ], + "seat": "pubrise" + } + ], + "cur": "USD" + } + } + }, + { + "expectedRequest": { + "uri": "https://backend.pubrise.ai/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "endpointId": "test", + "type": "network" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ], + "seat": "pubrise" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + }, + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/pubrise/pubrisetest/exemplary/simple-banner.json b/adapters/pubrise/pubrisetest/exemplary/simple-banner.json new file mode 100644 index 00000000000..6669c460ea1 --- /dev/null +++ b/adapters/pubrise/pubrisetest/exemplary/simple-banner.json @@ -0,0 +1,136 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://backend.pubrise.ai/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ], + "seat": "pubrise" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/pubrise/pubrisetest/exemplary/simple-native.json b/adapters/pubrise/pubrisetest/exemplary/simple-native.json new file mode 100644 index 00000000000..e535c9ce5f9 --- /dev/null +++ b/adapters/pubrise/pubrisetest/exemplary/simple-native.json @@ -0,0 +1,120 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "native": { + "request": "{\"ver\":\"1.1\",\"layout\":1,\"adunit\":2,\"plcmtcnt\":6,\"plcmttype\":4,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"wmin\":492,\"hmin\":328,\"type\":3,\"mimes\":[\"image/jpeg\",\"image/jpg\",\"image/png\"]}},{\"id\":4,\"required\":0,\"data\":{\"type\":6}},{\"id\":5,\"required\":0,\"data\":{\"type\":7}},{\"id\":6,\"required\":0,\"data\":{\"type\":1,\"len\":20}}]}", + "ver": "1.1" + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://backend.pubrise.ai/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "native": { + "request": "{\"ver\":\"1.1\",\"layout\":1,\"adunit\":2,\"plcmtcnt\":6,\"plcmttype\":4,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"wmin\":492,\"hmin\":328,\"type\":3,\"mimes\":[\"image/jpeg\",\"image/jpg\",\"image/png\"]}},{\"id\":4,\"required\":0,\"data\":{\"type\":6}},{\"id\":5,\"required\":0,\"data\":{\"type\":7}},{\"id\":6,\"required\":0,\"data\":{\"type\":1,\"len\":20}}]}", + "ver": "1.1" + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 4, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "native" + } + } + } + ], + "seat": "pubrise" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 4, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "native" + } + } + }, + "type": "native" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/pubrise/pubrisetest/exemplary/simple-video.json b/adapters/pubrise/pubrisetest/exemplary/simple-video.json new file mode 100644 index 00000000000..047b2bc7d99 --- /dev/null +++ b/adapters/pubrise/pubrisetest/exemplary/simple-video.json @@ -0,0 +1,131 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://backend.pubrise.ai/pserver", + "body": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ] + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "00:01:00", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 2, + "ext": { + "prebid": { + "type": "video" + } + } + } + ], + "seat": "pubrise" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "00:01:00", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 2, + "ext": { + "prebid": { + "type": "video" + } + } + }, + "type": "video" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/pubrise/pubrisetest/exemplary/simple-web-banner.json b/adapters/pubrise/pubrisetest/exemplary/simple-web-banner.json new file mode 100644 index 00000000000..ef9b8080ae7 --- /dev/null +++ b/adapters/pubrise/pubrisetest/exemplary/simple-web-banner.json @@ -0,0 +1,136 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "site": { + "id": "1", + "domain": "test.com" + }, + "device": { + "ip": "123.123.123.123", + "ua": "Ubuntu" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://backend.pubrise.ai/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "site": { + "id": "1", + "domain": "test.com" + }, + "device": { + "ip": "123.123.123.123", + "ua": "Ubuntu" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 468, + "h": 60, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ], + "seat": "pubrise" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 468, + "h": 60, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/pubrise/pubrisetest/supplemental/bad_media_type.json b/adapters/pubrise/pubrisetest/supplemental/bad_media_type.json new file mode 100644 index 00000000000..2b6165345ac --- /dev/null +++ b/adapters/pubrise/pubrisetest/supplemental/bad_media_type.json @@ -0,0 +1,83 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://backend.pubrise.ai/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "w": 300, + "h": 250, + "ext": {} + } + ], + "seat": "pubrise" + } + ], + "cur": "USD" + } + } + }], + "expectedMakeBidsErrors": [ + { + "value": "could not define media type for impression: test-imp-id", + "comparison": "literal" + } + ] +} diff --git a/adapters/pubrise/pubrisetest/supplemental/bad_response.json b/adapters/pubrise/pubrisetest/supplemental/bad_response.json new file mode 100644 index 00000000000..9bc9c2de35a --- /dev/null +++ b/adapters/pubrise/pubrisetest/supplemental/bad_response.json @@ -0,0 +1,85 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://backend.pubrise.ai/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": "" + } + }], + "expectedMakeBidsErrors": [ + { + "value": "expect { or n, but found \"", + "comparison": "literal" + } + ] +} diff --git a/adapters/pubrise/pubrisetest/supplemental/no-valid-impressions.json b/adapters/pubrise/pubrisetest/supplemental/no-valid-impressions.json new file mode 100644 index 00000000000..cc1edd685f9 --- /dev/null +++ b/adapters/pubrise/pubrisetest/supplemental/no-valid-impressions.json @@ -0,0 +1,20 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "expectedMakeRequestsErrors": [ + { + "value": "found no valid impressions", + "comparison": "literal" + } + ] +} diff --git a/adapters/pubrise/pubrisetest/supplemental/status-204.json b/adapters/pubrise/pubrisetest/supplemental/status-204.json new file mode 100644 index 00000000000..1ed98ff0c72 --- /dev/null +++ b/adapters/pubrise/pubrisetest/supplemental/status-204.json @@ -0,0 +1,80 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://backend.pubrise.ai/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 204, + "body": {} + } + }], + "expectedBidResponses": [] +} diff --git a/adapters/pubrise/pubrisetest/supplemental/status-not-200.json b/adapters/pubrise/pubrisetest/supplemental/status-not-200.json new file mode 100644 index 00000000000..c4b3cdc6f57 --- /dev/null +++ b/adapters/pubrise/pubrisetest/supplemental/status-not-200.json @@ -0,0 +1,85 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://backend.pubrise.ai/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 404, + "body": {} + } + }], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 404. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} diff --git a/adapters/pulsepoint/params_test.go b/adapters/pulsepoint/params_test.go index 4b3c6c017db..4359c4115ad 100644 --- a/adapters/pulsepoint/params_test.go +++ b/adapters/pulsepoint/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { @@ -37,6 +37,9 @@ func TestInvalidParams(t *testing.T) { var validParams = []string{ `{"cp":1000, "ct": 2000}`, `{"cp":1001, "ct": 2001}`, + `{"cp":"1000", "ct": "2000"}`, + `{"cp":"1000", "ct": 2000}`, + `{"cp":1000, "ct": "2000"}`, `{"cp":1001, "ct": 2001, "cf": "1x1"}`, } @@ -52,8 +55,4 @@ var invalidParams = []string{ `{"ct":"1000"}`, `{"cp":1000}`, `{"ct":1000}`, - `{"cp":1000, "ct":"1000"}`, - `{"cp":1000, "ct": "abcd"}`, - `{"cp":"abcd", "ct": 1000}`, - `{"cp":"1000.2", "ct": "1000.1"}`, } diff --git a/adapters/pulsepoint/pulsepoint.go b/adapters/pulsepoint/pulsepoint.go index c351bb7d051..2f750e9f858 100644 --- a/adapters/pulsepoint/pulsepoint.go +++ b/adapters/pulsepoint/pulsepoint.go @@ -2,14 +2,16 @@ package pulsepoint import ( "encoding/json" + "errors" "fmt" "net/http" "strconv" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" "github.com/prebid/openrtb/v20/openrtb2" ) @@ -35,25 +37,39 @@ func (a *PulsePointAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo * for i := 0; i < len(request.Imp); i++ { imp := request.Imp[i] var bidderExt adapters.ExtImpBidder - if err = json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err = jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { errs = append(errs, &errortypes.BadInput{ Message: err.Error(), }) continue } var pulsepointExt openrtb_ext.ExtImpPulsePoint - if err = json.Unmarshal(bidderExt.Bidder, &pulsepointExt); err != nil { + if err = jsonutil.Unmarshal(bidderExt.Bidder, &pulsepointExt); err != nil { errs = append(errs, &errortypes.BadInput{ Message: err.Error(), }) continue } // parse pubid and keep it for reference - if pubID == "" && pulsepointExt.PubID > 0 { - pubID = strconv.Itoa(pulsepointExt.PubID) + if pubID == "" { + pubID, err = parseParam("pubID", pulsepointExt.PubID) + if err != nil { + errs = append(errs, &errortypes.BadInput{ + Message: err.Error(), + }) + continue + } } // tag id to be sent - imp.TagID = strconv.Itoa(pulsepointExt.TagID) + var tagID string + tagID, err = parseParam("tagID", pulsepointExt.TagID) + if err != nil { + errs = append(errs, &errortypes.BadInput{ + Message: err.Error(), + }) + continue + } + imp.TagID = tagID imps = append(imps, imp) } @@ -122,7 +138,7 @@ func (a *PulsePointAdapter) MakeBids(internalRequest *openrtb2.BidRequest, exter } // parse response var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } @@ -163,3 +179,12 @@ func getBidType(imp openrtb2.Imp) openrtb_ext.BidType { } return "" } + +func parseParam(paramName string, paramValue jsonutil.StringInt) (string, error) { + value := int(paramValue) + // verify we got a non-zero value + if value == 0 { + return "", errors.New("param not found - " + paramName) + } + return strconv.Itoa(value), nil +} diff --git a/adapters/pulsepoint/pulsepoint_test.go b/adapters/pulsepoint/pulsepoint_test.go index 20f73c89ecb..be9fff83a69 100644 --- a/adapters/pulsepoint/pulsepoint_test.go +++ b/adapters/pulsepoint/pulsepoint_test.go @@ -3,9 +3,9 @@ package pulsepoint import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/pulsepoint/pulsepointtest/exemplary/banner-string-bidder-params.json b/adapters/pulsepoint/pulsepointtest/exemplary/banner-string-bidder-params.json new file mode 100644 index 00000000000..2a13f4d5b96 --- /dev/null +++ b/adapters/pulsepoint/pulsepointtest/exemplary/banner-string-bidder-params.json @@ -0,0 +1,102 @@ +{ + "mockBidRequest": { + "id": "request-id", + "site": { + "page": "http://publisher.com/index.html", + "publisher": { + "id": "123456789", + "name": "publisher.com" + } + }, + "imp": [{ + "id": "banner-1", + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "cp": "1234", + "ct": "1001" + } + } + }] + }, + "httpCalls": [{ + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ] + }, + "uri": "http://bidder.pulsepoint.com", + "body": { + "id": "request-id", + "site": { + "page": "http://publisher.com/index.html", + "publisher": { + "id": "1234", + "name": "publisher.com" + } + }, + "imp": [{ + "id": "banner-1", + "tagid": "1001", + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "cp": "1234", + "ct": "1001" + } + } + }] + }, + "impIDs":["banner-1"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "response-id", + "seatbid": [{ + "bid": [{ + "id": "banner-1-bid", + "impid": "banner-1", + "price": 3.5, + "adm": "
Creative
", + "adomain": [ + "advertiser.com" + ], + "crid": "20", + "w": 300, + "h": 250 + }], + "seat": "pulsepoint-seat" + }], + "cur": "USD" + } + } + }], + "expectedBidResponses": [{ + "bids": [{ + "bid": { + "id": "banner-1-bid", + "impid": "banner-1", + "price": 3.5, + "adm": "
Creative
", + "adomain": [ + "advertiser.com" + ], + "crid": "20", + "w": 300, + "h": 250 + }, + "type": "banner" + }] + }] +} \ No newline at end of file diff --git a/adapters/pulsepoint/pulsepointtest/supplemental/bad-bid-data.json b/adapters/pulsepoint/pulsepointtest/supplemental/bad-bid-data.json index 182bddc7137..8949960cb29 100644 --- a/adapters/pulsepoint/pulsepointtest/supplemental/bad-bid-data.json +++ b/adapters/pulsepoint/pulsepointtest/supplemental/bad-bid-data.json @@ -84,8 +84,8 @@ }], "expectedBidResponses": [], "expectedMakeBidsErrors": [{ - "value": "json: cannot unmarshal string into Go struct field Bid.seatbid.bid.w of type int64", - "comparison": "literal" + "value": "cannot unmarshal openrtb2.Bid.W: unexpected character", + "comparison": "startswith" } ] } \ No newline at end of file diff --git a/adapters/pulsepoint/pulsepointtest/supplemental/bad-prebid-params-missing-param.json b/adapters/pulsepoint/pulsepointtest/supplemental/bad-prebid-params-missing-param.json new file mode 100644 index 00000000000..1b90f37d1eb --- /dev/null +++ b/adapters/pulsepoint/pulsepointtest/supplemental/bad-prebid-params-missing-param.json @@ -0,0 +1,31 @@ +{ + "mockBidRequest": { + "id": "request-id", + "site": { + "page": "http://publisher.com/index.html", + "publisher": { + "id": "123456789", + "name": "publisher.com" + } + }, + "imp": [{ + "id": "banner-1", + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "cp": "1234" + } + } + }] + }, + "httpCalls": [], + "expectedMakeRequestsErrors": [{ + "value": "param not found - tagID", + "comparison": "literal" + }], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [] +} \ No newline at end of file diff --git a/adapters/pulsepoint/pulsepointtest/supplemental/bad-prebid-params.json b/adapters/pulsepoint/pulsepointtest/supplemental/bad-prebid-params.json index 2d0c74d39d7..aee3d444912 100644 --- a/adapters/pulsepoint/pulsepointtest/supplemental/bad-prebid-params.json +++ b/adapters/pulsepoint/pulsepointtest/supplemental/bad-prebid-params.json @@ -17,14 +17,14 @@ "ext": { "bidder": { "cp": "1234", - "ct": "1001" + "ct": "ab1001" } } }] }, "httpCalls": [], "expectedMakeRequestsErrors": [{ - "value": "json: cannot unmarshal string into Go struct field ExtImpPulsePoint.cp of type int", + "value": "cannot unmarshal openrtb_ext.ExtImpPulsePoint.TagID: Value looks like Number/Boolean/None, but can't find its end: ',' or '}' symbol", "comparison": "literal" }], "expectedBidResponses": [], diff --git a/adapters/pulsepoint/pulsepointtest/supplemental/bad-prebid.ext.json b/adapters/pulsepoint/pulsepointtest/supplemental/bad-prebid.ext.json index 7de9bd3c264..74825c2c018 100644 --- a/adapters/pulsepoint/pulsepointtest/supplemental/bad-prebid.ext.json +++ b/adapters/pulsepoint/pulsepointtest/supplemental/bad-prebid.ext.json @@ -19,7 +19,7 @@ }, "httpCalls": [], "expectedMakeRequestsErrors": [{ - "value": "json: cannot unmarshal string into Go value of type adapters.ExtImpBidder", + "value": "expect { or n, but found \"", "comparison": "literal" }], "expectedBidResponses": [], diff --git a/adapters/pwbid/params_test.go b/adapters/pwbid/params_test.go index 44d36379cca..52f06e02573 100644 --- a/adapters/pwbid/params_test.go +++ b/adapters/pwbid/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/pwbid/pwbid.go b/adapters/pwbid/pwbid.go index 19b182562c6..7e03185f2cd 100644 --- a/adapters/pwbid/pwbid.go +++ b/adapters/pwbid/pwbid.go @@ -5,10 +5,11 @@ import ( "fmt" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -51,7 +52,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } diff --git a/adapters/pwbid/pwbid_test.go b/adapters/pwbid/pwbid_test.go index 9abad59d97c..cb028a19f69 100644 --- a/adapters/pwbid/pwbid_test.go +++ b/adapters/pwbid/pwbid_test.go @@ -3,9 +3,9 @@ package pwbid import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/pwbid/pwbidtest/supplemental/response-200-without-body.json b/adapters/pwbid/pwbidtest/supplemental/response-200-without-body.json index 6b4effd139e..ffb61b548b7 100644 --- a/adapters/pwbid/pwbidtest/supplemental/response-200-without-body.json +++ b/adapters/pwbid/pwbidtest/supplemental/response-200-without-body.json @@ -45,8 +45,8 @@ ], "expectedMakeBidsErrors": [ { - "value": "unexpected end of JSON input", - "comparison": "literal" + "value": "expect { or n, but found", + "comparison": "startswith" } ] } diff --git a/adapters/qt/params_test.go b/adapters/qt/params_test.go new file mode 100644 index 00000000000..5c8d3253bec --- /dev/null +++ b/adapters/qt/params_test.go @@ -0,0 +1,47 @@ +package qt + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v3/openrtb_ext" +) + +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json schema. %v", err) + } + + for _, p := range validParams { + if err := validator.Validate(openrtb_ext.BidderQT, json.RawMessage(p)); err != nil { + t.Errorf("Schema rejected valid params: %s", p) + } + } +} + +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json schema. %v", err) + } + + for _, p := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderQT, json.RawMessage(p)); err == nil { + t.Errorf("Schema allowed invalid params: %s", p) + } + } +} + +var validParams = []string{ + `{"placementId": "test"}`, + `{"placementId": "1"}`, + `{"endpointId": "test"}`, + `{"endpointId": "1"}`, +} + +var invalidParams = []string{ + `{"placementId": 42}`, + `{"endpointId": 42}`, + `{"placementId": "1", "endpointId": "1"}`, +} diff --git a/adapters/qt/qt.go b/adapters/qt/qt.go new file mode 100644 index 00000000000..a7c5d53c5ac --- /dev/null +++ b/adapters/qt/qt.go @@ -0,0 +1,153 @@ +package qt + +import ( + "encoding/json" + "fmt" + "net/http" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" +) + +type adapter struct { + endpoint string +} + +type reqBodyExt struct { + QTBidderExt reqBodyExtBidder `json:"bidder"` +} + +type reqBodyExtBidder struct { + Type string `json:"type"` + PlacementID string `json:"placementId,omitempty"` + EndpointID string `json:"endpointId,omitempty"` +} + +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + bidder := &adapter{ + endpoint: config.Endpoint, + } + return bidder, nil +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + var errs []error + var adapterRequests []*adapters.RequestData + + reqCopy := *request + for _, imp := range request.Imp { + reqCopy.Imp = []openrtb2.Imp{imp} + + var bidderExt adapters.ExtImpBidder + var qtExt openrtb_ext.ImpExtQT + + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { + errs = append(errs, err) + continue + } + if err := jsonutil.Unmarshal(bidderExt.Bidder, &qtExt); err != nil { + errs = append(errs, err) + continue + } + + impExt := reqBodyExt{QTBidderExt: reqBodyExtBidder{}} + + if qtExt.PlacementID != "" { + impExt.QTBidderExt.PlacementID = qtExt.PlacementID + impExt.QTBidderExt.Type = "publisher" + } else if qtExt.EndpointID != "" { + impExt.QTBidderExt.EndpointID = qtExt.EndpointID + impExt.QTBidderExt.Type = "network" + } + + finalyImpExt, err := json.Marshal(impExt) + if err != nil { + errs = append(errs, err) + continue + } + + reqCopy.Imp[0].Ext = finalyImpExt + + adapterReq, err := a.makeRequest(&reqCopy) + if err != nil { + errs = append(errs, err) + continue + } + + adapterRequests = append(adapterRequests, adapterReq) + } + + return adapterRequests, nil +} + +func (a *adapter) makeRequest(request *openrtb2.BidRequest) (*adapters.RequestData, error) { + reqJSON, err := json.Marshal(request) + if err != nil { + return nil, err + } + + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + headers.Add("Accept", "application/json") + return &adapters.RequestData{ + Method: "POST", + Uri: a.endpoint, + Body: reqJSON, + Headers: headers, + ImpIDs: openrtb_ext.GetImpIDs(request.Imp), + }, nil +} + +func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if adapters.IsResponseStatusCodeNoContent(responseData) { + return nil, nil + } + + if err := adapters.CheckResponseStatusCodeForErrors(responseData); err != nil { + return nil, []error{err} + } + + var response openrtb2.BidResponse + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { + return nil, []error{err} + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) + if len(response.Cur) != 0 { + bidResponse.Currency = response.Cur + } + + for _, seatBid := range response.SeatBid { + for i := range seatBid.Bid { + bid := seatBid.Bid[i] + bidType, err := getBidType(bid) + if err != nil { + return nil, []error{err} + } + + b := &adapters.TypedBid{ + Bid: &seatBid.Bid[i], + BidType: bidType, + } + bidResponse.Bids = append(bidResponse.Bids, b) + } + } + return bidResponse, nil +} + +func getBidType(bid openrtb2.Bid) (openrtb_ext.BidType, error) { + // determinate media type by bid response field mtype + switch bid.MType { + case openrtb2.MarkupBanner: + return openrtb_ext.BidTypeBanner, nil + case openrtb2.MarkupVideo: + return openrtb_ext.BidTypeVideo, nil + case openrtb2.MarkupNative: + return openrtb_ext.BidTypeNative, nil + } + + return "", fmt.Errorf("could not define media type for impression: %s", bid.ImpID) +} diff --git a/adapters/qt/qt_test.go b/adapters/qt/qt_test.go new file mode 100644 index 00000000000..f85adbaf18c --- /dev/null +++ b/adapters/qt/qt_test.go @@ -0,0 +1,20 @@ +package qt + +import ( + "testing" + + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderQT, config.Adapter{ + Endpoint: "https://fake.test.io/pserver"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "qttest", bidder) +} diff --git a/adapters/qt/qttest/exemplary/endpointId.json b/adapters/qt/qttest/exemplary/endpointId.json new file mode 100644 index 00000000000..1716aaa25e8 --- /dev/null +++ b/adapters/qt/qttest/exemplary/endpointId.json @@ -0,0 +1,136 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "endpointId": "test" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://fake.test.io/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "endpointId": "test", + "type": "network" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ], + "seat": "qt" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/qt/qttest/exemplary/multi-format.json b/adapters/qt/qttest/exemplary/multi-format.json new file mode 100644 index 00000000000..cb1c6ffd9c6 --- /dev/null +++ b/adapters/qt/qttest/exemplary/multi-format.json @@ -0,0 +1,105 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "endpointId": "test" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://fake.test.io/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "endpointId": "test", + "type": "network" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 204 + } + } + ], + "expectedBidResponses": [] +} \ No newline at end of file diff --git a/adapters/qt/qttest/exemplary/multi-imp.json b/adapters/qt/qttest/exemplary/multi-imp.json new file mode 100644 index 00000000000..1613863e2d9 --- /dev/null +++ b/adapters/qt/qttest/exemplary/multi-imp.json @@ -0,0 +1,253 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id1", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "endpointId": "test" + } + } + }, + { + "id": "test-imp-id2", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "endpointId": "test" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://fake.test.io/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id1", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "endpointId": "test", + "type": "network" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + } + }, + "impIDs":["test-imp-id1"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id1", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ], + "seat": "qt" + } + ], + "cur": "USD" + } + } + }, + { + "expectedRequest": { + "uri": "https://fake.test.io/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id2", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "endpointId": "test", + "type": "network" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + } + }, + "impIDs":["test-imp-id2"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id2", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ], + "seat": "qt" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id1", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + }, + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id2", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/qt/qttest/exemplary/simple-banner.json b/adapters/qt/qttest/exemplary/simple-banner.json new file mode 100644 index 00000000000..8bb08c22f74 --- /dev/null +++ b/adapters/qt/qttest/exemplary/simple-banner.json @@ -0,0 +1,136 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://fake.test.io/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ], + "seat": "qt" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/qt/qttest/exemplary/simple-native.json b/adapters/qt/qttest/exemplary/simple-native.json new file mode 100644 index 00000000000..91d53898a62 --- /dev/null +++ b/adapters/qt/qttest/exemplary/simple-native.json @@ -0,0 +1,120 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "native": { + "request": "{\"ver\":\"1.1\",\"layout\":1,\"adunit\":2,\"plcmtcnt\":6,\"plcmttype\":4,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"wmin\":492,\"hmin\":328,\"type\":3,\"mimes\":[\"image/jpeg\",\"image/jpg\",\"image/png\"]}},{\"id\":4,\"required\":0,\"data\":{\"type\":6}},{\"id\":5,\"required\":0,\"data\":{\"type\":7}},{\"id\":6,\"required\":0,\"data\":{\"type\":1,\"len\":20}}]}", + "ver": "1.1" + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://fake.test.io/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "native": { + "request": "{\"ver\":\"1.1\",\"layout\":1,\"adunit\":2,\"plcmtcnt\":6,\"plcmttype\":4,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"wmin\":492,\"hmin\":328,\"type\":3,\"mimes\":[\"image/jpeg\",\"image/jpg\",\"image/png\"]}},{\"id\":4,\"required\":0,\"data\":{\"type\":6}},{\"id\":5,\"required\":0,\"data\":{\"type\":7}},{\"id\":6,\"required\":0,\"data\":{\"type\":1,\"len\":20}}]}", + "ver": "1.1" + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 4, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "native" + } + } + } + ], + "seat": "qt" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 4, + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "native" + } + } + }, + "type": "native" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/qt/qttest/exemplary/simple-video.json b/adapters/qt/qttest/exemplary/simple-video.json new file mode 100644 index 00000000000..31906856960 --- /dev/null +++ b/adapters/qt/qttest/exemplary/simple-video.json @@ -0,0 +1,131 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://fake.test.io/pserver", + "body": { + "id": "test-request-id", + "device": { + "ip": "123.123.123.123", + "ua": "iPad" + }, + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 2, + 5 + ], + "w": 1024, + "h": 576 + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ] + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "00:01:00", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 2, + "ext": { + "prebid": { + "type": "video" + } + } + } + ], + "seat": "qt" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "00:01:00", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 2, + "ext": { + "prebid": { + "type": "video" + } + } + }, + "type": "video" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/qt/qttest/exemplary/simple-web-banner.json b/adapters/qt/qttest/exemplary/simple-web-banner.json new file mode 100644 index 00000000000..170ccccab59 --- /dev/null +++ b/adapters/qt/qttest/exemplary/simple-web-banner.json @@ -0,0 +1,136 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "site": { + "id": "1", + "domain": "test.com" + }, + "device": { + "ip": "123.123.123.123", + "ua": "Ubuntu" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://fake.test.io/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "tagid": "test", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "site": { + "id": "1", + "domain": "test.com" + }, + "device": { + "ip": "123.123.123.123", + "ua": "Ubuntu" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 468, + "h": 60, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ], + "seat": "qt" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "mtype": 1, + "w": 468, + "h": 60, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/qt/qttest/supplemental/bad_media_type.json b/adapters/qt/qttest/supplemental/bad_media_type.json new file mode 100644 index 00000000000..41953fdcfb1 --- /dev/null +++ b/adapters/qt/qttest/supplemental/bad_media_type.json @@ -0,0 +1,83 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://fake.test.io/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "test_bid_id", + "impid": "test-imp-id", + "price": 0.27543, + "adm": "", + "cid": "test_cid", + "crid": "test_crid", + "dealid": "test_dealid", + "w": 300, + "h": 250, + "ext": {} + } + ], + "seat": "qt" + } + ], + "cur": "USD" + } + } + }], + "expectedMakeBidsErrors": [ + { + "value": "could not define media type for impression: test-imp-id", + "comparison": "literal" + } + ] +} diff --git a/adapters/qt/qttest/supplemental/bad_response.json b/adapters/qt/qttest/supplemental/bad_response.json new file mode 100644 index 00000000000..4fe8d572c46 --- /dev/null +++ b/adapters/qt/qttest/supplemental/bad_response.json @@ -0,0 +1,85 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://fake.test.io/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": "" + } + }], + "expectedMakeBidsErrors": [ + { + "value": "expect { or n, but found \"", + "comparison": "literal" + } + ] +} diff --git a/adapters/qt/qttest/supplemental/status-204.json b/adapters/qt/qttest/supplemental/status-204.json new file mode 100644 index 00000000000..f72a2eb0607 --- /dev/null +++ b/adapters/qt/qttest/supplemental/status-204.json @@ -0,0 +1,80 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://fake.test.io/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 204, + "body": {} + } + }], + "expectedBidResponses": [] +} diff --git a/adapters/qt/qttest/supplemental/status-not-200.json b/adapters/qt/qttest/supplemental/status-not-200.json new file mode 100644 index 00000000000..218aa632618 --- /dev/null +++ b/adapters/qt/qttest/supplemental/status-not-200.json @@ -0,0 +1,85 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://fake.test.io/pserver", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": "test", + "type": "publisher" + } + } + } + ], + "app": { + "id": "1", + "bundle": "com.wls.testwlsapplication" + }, + "device": { + "ip": "123.123.123.123", + "ifa": "sdjfksdf-dfsds-dsdg-dsgg" + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 404, + "body": {} + } + }], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 404. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} diff --git a/adapters/readpeak/params_test.go b/adapters/readpeak/params_test.go index 494cff3db6e..772855e425d 100644 --- a/adapters/readpeak/params_test.go +++ b/adapters/readpeak/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/readpeak/readpeak.go b/adapters/readpeak/readpeak.go index dd7e30ccb81..7049dace489 100644 --- a/adapters/readpeak/readpeak.go +++ b/adapters/readpeak/readpeak.go @@ -8,10 +8,11 @@ import ( "strings" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -33,11 +34,11 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte var imps []openrtb2.Imp for i := 0; i < len(requestCopy.Imp); i++ { var impExt adapters.ExtImpBidder - if err := json.Unmarshal(requestCopy.Imp[i].Ext, &impExt); err != nil { + if err := jsonutil.Unmarshal(requestCopy.Imp[i].Ext, &impExt); err != nil { errors = append(errors, err) continue } - if err := json.Unmarshal(impExt.Bidder, &rpExt); err != nil { + if err := jsonutil.Unmarshal(impExt.Bidder, &rpExt); err != nil { errors = append(errors, err) continue } @@ -108,7 +109,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } diff --git a/adapters/readpeak/readpeak_test.go b/adapters/readpeak/readpeak_test.go index aab6b554cb0..8c8e8e27bea 100644 --- a/adapters/readpeak/readpeak_test.go +++ b/adapters/readpeak/readpeak_test.go @@ -3,9 +3,9 @@ package readpeak import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/relevantdigital/params_test.go b/adapters/relevantdigital/params_test.go index cd889a5eaa8..987dfd6e589 100644 --- a/adapters/relevantdigital/params_test.go +++ b/adapters/relevantdigital/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/relevantdigital/relevantdigital.go b/adapters/relevantdigital/relevantdigital.go index 134bdf5e4d5..35789f3b841 100644 --- a/adapters/relevantdigital/relevantdigital.go +++ b/adapters/relevantdigital/relevantdigital.go @@ -10,11 +10,12 @@ import ( "github.com/buger/jsonparser" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" jsonpatch "gopkg.in/evanphx/json-patch.v4" ) @@ -56,7 +57,7 @@ func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server co func patchBidRequestExt(prebidBidRequest *openrtb2.BidRequest, id string) error { var bidRequestExt relevantExt if len(prebidBidRequest.Ext) != 0 { - if err := json.Unmarshal(prebidBidRequest.Ext, &bidRequestExt); err != nil { + if err := jsonutil.Unmarshal(prebidBidRequest.Ext, &bidRequestExt); err != nil { return &errortypes.FailedToRequestBids{ Message: fmt.Sprintf("failed to unmarshal ext, %s", prebidBidRequest.Ext), } @@ -158,13 +159,13 @@ func createJSONRequest(bidRequest *openrtb2.BidRequest) ([]byte, error) { func getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtRelevantDigital, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: "imp.ext not provided", } } relevantExt := openrtb_ext.ExtRelevantDigital{PbsBufferMs: default_bufffer_ms} - if err := json.Unmarshal(bidderExt.Bidder, &relevantExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &relevantExt); err != nil { return nil, &errortypes.BadInput{ Message: "ext.bidder not provided", } @@ -254,7 +255,7 @@ func getHeaders(request *openrtb2.BidRequest) http.Header { func getMediaTypeForBidFromExt(bid openrtb2.Bid) (openrtb_ext.BidType, error) { if bid.Ext != nil { var bidExt openrtb_ext.ExtBid - err := json.Unmarshal(bid.Ext, &bidExt) + err := jsonutil.Unmarshal(bid.Ext, &bidExt) if err == nil && bidExt.Prebid != nil { return openrtb_ext.ParseBidType(string(bidExt.Prebid.Type)) } @@ -301,7 +302,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } diff --git a/adapters/relevantdigital/relevantdigital_test.go b/adapters/relevantdigital/relevantdigital_test.go index 5c627ca7c65..31e6b370d86 100644 --- a/adapters/relevantdigital/relevantdigital_test.go +++ b/adapters/relevantdigital/relevantdigital_test.go @@ -3,9 +3,9 @@ package relevantdigital import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/resetdigital/resetdigital.go b/adapters/resetdigital/resetdigital.go new file mode 100644 index 00000000000..3aace820035 --- /dev/null +++ b/adapters/resetdigital/resetdigital.go @@ -0,0 +1,322 @@ +package resetdigital + +import ( + "encoding/json" + "fmt" + "net/http" + "strconv" + "text/template" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" +) + +type adapter struct { + endpoint *template.Template + endpointUri string +} + +type resetDigitalRequest struct { + Site resetDigitalSite `json:"site"` + Imps []resetDigitalImp `json:"imps"` +} +type resetDigitalSite struct { + Domain string `json:"domain"` + Referrer string `json:"referrer"` +} +type resetDigitalImp struct { + ZoneID resetDigitalImpZone `json:"zone_id"` + BidID string `json:"bid_id"` + ImpID string `json:"imp_id"` + Ext resetDigitalImpExt `json:"ext"` + MediaTypes resetDigitalMediaTypes `json:"media_types"` +} +type resetDigitalImpZone struct { + PlacementID string `json:"placementId"` +} +type resetDigitalImpExt struct { + Gpid string `json:"gpid"` +} +type resetDigitalMediaTypes struct { + Banner resetDigitalMediaType `json:"banner"` + Video resetDigitalMediaType `json:"video"` + Audio resetDigitalMediaType `json:"audio"` +} +type resetDigitalMediaType struct { + Sizes [][]int64 `json:"sizes"` + Mimes []string `json:"mimes"` +} +type resetDigitalBidResponse struct { + Bids []resetDigitalBid `json:"bids"` +} +type resetDigitalBid struct { + BidID string `json:"bid_id"` + ImpID string `json:"imp_id"` + CPM float64 `json:"cpm"` + CID string `json:"cid,omitempty"` + CrID string `json:"crid,omitempty"` + AdID string `json:"adid"` + W string `json:"w,omitempty"` + H string `json:"h,omitempty"` + Seat string `json:"seat"` + HTML string `json:"html"` +} + +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + template, err := template.New("endpointTemplate").Parse(config.Endpoint) + if err != nil { + return nil, fmt.Errorf("unable to parse endpoint url template: %v", err) + } + bidder := &adapter{ + endpoint: template, + } + return bidder, nil +} + +func getHeaders(request *openrtb2.BidRequest) http.Header { + headers := http.Header{} + + addNonEmptyHeaders(&headers, map[string]string{ + "Content-Type": "application/json;charset=utf-8", + "Accept": "application/json", + }) + + if request != nil && request.Device != nil { + addNonEmptyHeaders(&headers, map[string]string{ + "Accept-Language": request.Device.Language, + "User-Agent": request.Device.UA, + "X-Forwarded-For": request.Device.IP, + "X-Real-Ip": request.Device.IP, + }) + } + if request != nil && request.Site != nil { + addNonEmptyHeaders(&headers, map[string]string{ + "Referer": request.Site.Page, + }) + } + + return headers +} + +func addNonEmptyHeaders(headers *http.Header, headerValues map[string]string) { + for key, value := range headerValues { + if len(value) > 0 { + headers.Add(key, value) + } + } +} + +func (a *adapter) MakeRequests(requestData *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + var ( + requests []*adapters.RequestData + errors []error + ) + + for _, imp := range requestData.Imp { + bidType, err := getBidType(imp) + if err != nil { + errors = append(errors, err) + continue + } + + splittedRequestData, err := processDataFromRequest(requestData, imp, bidType) + if err != nil { + errors = append(errors, err) + continue + } + + requestBody, err := json.Marshal(splittedRequestData) + if err != nil { + errors = append(errors, err) + continue + } + + requests = append(requests, &adapters.RequestData{ + Method: "POST", + Uri: a.endpointUri, + Body: requestBody, + Headers: getHeaders(requestData), + ImpIDs: []string{imp.ID}, + }) + } + + return requests, errors +} + +func processDataFromRequest(requestData *openrtb2.BidRequest, imp openrtb2.Imp, bidType openrtb_ext.BidType) (resetDigitalRequest, error) { + var reqData resetDigitalRequest + + if requestData.Site != nil { + reqData.Site.Domain = requestData.Site.Domain + reqData.Site.Referrer = requestData.Site.Page + } + + reqData.Imps = append(reqData.Imps, resetDigitalImp{ + BidID: requestData.ID, + ImpID: imp.ID, + }) + + if bidType == openrtb_ext.BidTypeBanner && imp.Banner != nil { + var tempH, tempW int64 + if imp.Banner.H != nil { + tempH = *imp.Banner.H + } + if imp.Banner.W != nil { + tempW = *imp.Banner.W + } + if tempH > 0 && tempW > 0 { + reqData.Imps[0].MediaTypes.Banner.Sizes = append( + reqData.Imps[0].MediaTypes.Banner.Sizes, + []int64{tempW, tempH}, + ) + } + } + if bidType == openrtb_ext.BidTypeVideo && imp.Video != nil { + var tempH, tempW int64 + if imp.Video.H != nil { + tempH = *imp.Video.H + } + if imp.Video.W != nil { + tempW = *imp.Video.W + } + if tempH > 0 && tempW > 0 { + reqData.Imps[0].MediaTypes.Video.Sizes = append( + reqData.Imps[0].MediaTypes.Video.Sizes, + []int64{tempW, tempH}, + ) + } + if imp.Video.MIMEs != nil { + // reqData.Imps[0].MediaTypes.Video.Mimes = imp.Video.MIMEs + reqData.Imps[0].MediaTypes.Video.Mimes = append( + reqData.Imps[0].MediaTypes.Video.Mimes, + imp.Video.MIMEs..., + ) + } + } + if bidType == openrtb_ext.BidTypeAudio && imp.Audio != nil && imp.Audio.MIMEs != nil { + reqData.Imps[0].MediaTypes.Audio.Mimes = append( + reqData.Imps[0].MediaTypes.Audio.Mimes, + imp.Audio.MIMEs..., + ) + } + + var bidderExt adapters.ExtImpBidder + var resetDigitalExt openrtb_ext.ImpExtResetDigital + + if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + return resetDigitalRequest{}, err + } + if err := json.Unmarshal(bidderExt.Bidder, &resetDigitalExt); err != nil { + return resetDigitalRequest{}, err + } + reqData.Imps[0].ZoneID.PlacementID = resetDigitalExt.PlacementID + + return reqData, nil +} + +func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if adapters.IsResponseStatusCodeNoContent(responseData) { + return nil, nil + } + + if err := adapters.CheckResponseStatusCodeForErrors(responseData); err != nil { + return nil, []error{err} + } + + var response resetDigitalBidResponse + if err := json.Unmarshal(responseData.Body, &response); err != nil { + return nil, []error{err} + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) + + var errs []error + requestImps := make(map[string]openrtb2.Imp) + for _, imp := range request.Imp { + requestImps[imp.ID] = imp + } + + for i := range response.Bids { + resetDigitalBid := &response.Bids[i] + + bid, err := getBidFromResponse(resetDigitalBid) + // handle the error + if bid == nil { + // it would be better to return an error here + errs = append(errs, err) + continue + } + + bidType, err := GetMediaTypeForImp(requestImps, bid.ImpID) + if err != nil { + errs = append(errs, err) + continue + } + + b := &adapters.TypedBid{ + Bid: bid, + BidType: bidType, + Seat: openrtb_ext.BidderName(resetDigitalBid.Seat), + } + bidResponse.Bids = append(bidResponse.Bids, b) + } + + if len(request.Cur) == 0 { + bidResponse.Currency = "USD" + } + + return bidResponse, errs +} + +func getBidFromResponse(bidResponse *resetDigitalBid) (*openrtb2.Bid, error) { + + bid := &openrtb2.Bid{ + ID: bidResponse.BidID, + Price: bidResponse.CPM, + ImpID: bidResponse.ImpID, + CID: bidResponse.CID, + CrID: bidResponse.CrID, + AdM: bidResponse.HTML, + } + + w, err := strconv.ParseInt(bidResponse.W, 10, 64) + if err != nil { + return nil, err + } + bid.W = w + + h, err := strconv.ParseInt(bidResponse.H, 10, 64) + if err != nil { + return nil, err + } + bid.H = h + return bid, nil +} + +func getBidType(imp openrtb2.Imp) (openrtb_ext.BidType, error) { + if imp.Banner != nil { + return openrtb_ext.BidTypeBanner, nil + } else if imp.Video != nil { + return openrtb_ext.BidTypeVideo, nil + } else if imp.Audio != nil { + return openrtb_ext.BidTypeAudio, nil + } + + return "", fmt.Errorf("failed to find matching imp for bid %s", imp.ID) +} + +func GetMediaTypeForImp(reqImps map[string]openrtb2.Imp, bidImpID string) (openrtb_ext.BidType, error) { + mediaType := openrtb_ext.BidTypeBanner + + if reqImp, ok := reqImps[bidImpID]; ok { + if reqImp.Banner == nil && reqImp.Video != nil { + mediaType = openrtb_ext.BidTypeVideo + } else if reqImp.Audio != nil { + mediaType = openrtb_ext.BidTypeAudio + } + return mediaType, nil + } + return "", fmt.Errorf("unknown media type for bid imp ID %s", bidImpID) +} diff --git a/adapters/resetdigital/resetdigital_test.go b/adapters/resetdigital/resetdigital_test.go new file mode 100644 index 00000000000..9efba33f301 --- /dev/null +++ b/adapters/resetdigital/resetdigital_test.go @@ -0,0 +1,21 @@ +package resetdigital + +import ( + "testing" + + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" +) + +func TestJsonSamples(t *testing.T) { + + bidder, buildErr := Builder(openrtb_ext.BidderResetDigital, config.Adapter{ + Endpoint: "https://test.com"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "resetdigitaltest", bidder) +} diff --git a/adapters/resetdigital/resetdigitaltest/exemplary/simple-audio.json b/adapters/resetdigital/resetdigitaltest/exemplary/simple-audio.json new file mode 100644 index 00000000000..80ae00517f6 --- /dev/null +++ b/adapters/resetdigital/resetdigitaltest/exemplary/simple-audio.json @@ -0,0 +1,183 @@ +{ + "mockBidRequest": { + "id": "12345", + "at": 1, + "bcat": [ + "IAB24", + "IAB25", + "IAB26" + ], + "cur": [ + "USD" + ], + "source": { + "fd": 0, + "tid": "00000FBCE10DE8FA", + "schain": { + "complete": 1, + "ver": "1.0", + "nodes": [ + { + "asi": "resetdigital.co", + "sid": "176", + "hp": 1 + } + ] + } + }, + "device": { + "ip": "35.146.176.97", + "js": 1, + "language": "en", + "ua": "PostmanRuntime/7.42.0" + }, + "user": { + "id": "000011200BA1065C", + "buyeruid": "000011200BA1065C" + }, + "app": { + "id": "test.com", + "bundle": "test.com", + "name": "test.com", + "content": { + "livestream": 1, + "genre": "F%C3%BAtbol", + "cat": [ + "" + ], + "language": "es" + }, + "publisher": { + "id": "176" + }, + "keywords": "" + }, + "imp": [ + { + "id": "001", + "bidfloor": 1.429, + "tagid": "667", + "secure": 1, + "audio": { + "protocols": [ + 2, + 3, + 5, + 6 + ], + "mimes": [ + "audio/mp4", + "audio/mp3" + ], + "api": [], + "minduration": 15, + "maxduration": 60, + "startdelay": -1 + }, + "ext": { + "bidder": { + "placement_id": "placement-id-1" + } + } + } + ], + "site": { + "domain": "https://test.com", + "page": "https://test.com/2016/06/12" + }, + "cur": [ + "USD" + ], + "device": { + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36", + "ip": "127.0.0.1", + "language": "EN" + }, + "tmax": 400 + }, + "httpCalls": [ + { + "expectedRequest": { + "method": "POST", + "body": { + "imps": [ + { + "bid_id": "12345", + "ext": { + "gpid": "" + }, + "imp_id": "001", + "media_types": { + "banner": { + "sizes": null, + "mimes": null + }, + "video": { + "sizes": null, + "mimes": null + }, + "audio": { + "sizes": null, + "mimes": [ + "audio/mp4", + "audio/mp3" + ] + } + }, + "zone_id": { + "placementId": "placement-id-1" + } + } + ], + "site": { + "domain": "https://test.com", + "referrer": "https://test.com/2016/06/12" + } + }, + "impIDs": [ + "001" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "bids": [ + { + "bid_id": "01", + "imp_id": "001", + "cpm": 9.11, + "dealid": "RD-1000164", + "cid": "1000048-1002918", + "crid": "1003893", + "adid": "1003893", + "language": "en", + "w": "0", + "h": "0", + "seat": "resetdigital", + "html": "" + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "adm": "", + "cid": "1000048-1002918", + "crid": "1003893", + "id": "01", + "impid": "001", + "price": 9.11 + }, + "type": "audio", + "seat": "resetdigital" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/resetdigital/resetdigitaltest/exemplary/simple-banner.json b/adapters/resetdigital/resetdigitaltest/exemplary/simple-banner.json new file mode 100644 index 00000000000..2e4a54c8a57 --- /dev/null +++ b/adapters/resetdigital/resetdigitaltest/exemplary/simple-banner.json @@ -0,0 +1,108 @@ +{ + "mockBidRequest": { + "id": "12345", + "imp": [{ + "id": "001", + "banner": { + "h": 300, + "w": 250 + }, + "ext": { + "bidder": { + "placement_id": "placement-id-1" + } + } + }], + "site": { + "domain": "https://test.com", + "page": "https://test.com/2016/06/12" + }, + "cur": [ + "USD" + ], + "device": { + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36", + "ip": "127.0.0.1", + "language": "EN" + }, + "tmax": 500 + }, + "httpCalls": [{ + "expectedRequest": { + "method": "POST", + "body": { + "imps": [{ + "bid_id": "12345", + "ext": { + "gpid": "" + }, + "imp_id": "001", + "media_types": { + "banner": { + "mimes": null, + "sizes": [ + [ + 250, + 300 + ] + ] + }, + "video": { + "mimes": null, + "sizes": null + }, + "audio": { + "mimes": null, + "sizes": null + } + }, + "zone_id": { + "placementId": "placement-id-1" + } + }], + "site": { + "domain": "https://test.com", + "referrer": "https://test.com/2016/06/12" + } + }, + "impIDs": [ + "001" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "bids": [{ + "bid_id": "01", + "imp_id": "001", + "cpm": 1.00, + "cid": "1002088", + "crid": "1000763-1002088", + "adid": "1002088", + "w": "300", + "h": "250", + "seat": "resetdigital", + "html": "" + }] + } + } + }], + + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "bid": { + "adm": "", + "cid": "1002088", + "crid": "1000763-1002088", + "id": "01", + "impid": "001", + "price": 1.00, + "w": 300, + "h": 250 + }, + "type": "banner", + "seat": "resetdigital" + }] + }] +} diff --git a/adapters/resetdigital/resetdigitaltest/exemplary/simple-video.json b/adapters/resetdigital/resetdigitaltest/exemplary/simple-video.json new file mode 100644 index 00000000000..0310ed18c46 --- /dev/null +++ b/adapters/resetdigital/resetdigitaltest/exemplary/simple-video.json @@ -0,0 +1,126 @@ +{ + "mockBidRequest": { + "id": "12345", + "imp": [ + { + "id": "001", + "video": { + "w": 900, + "h": 250, + "mimes": [ + "video/x-flv", + "video/mp4" + ] + }, + "ext": { + "bidder": { + "placement_id": "placement-id-1" + } + } + } + ], + "site": { + "domain": "https://test.com", + "page": "https://test.com/2016/06/12" + }, + "cur": [ + "USD" + ], + "device": { + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36", + "ip": "127.0.0.1", + "language": "EN" + }, + "tmax": 500 + }, + "httpCalls": [ + { + "expectedRequest": { + "method": "POST", + "body": { + "imps": [ + { + "bid_id": "12345", + "ext": { + "gpid": "" + }, + "imp_id": "001", + "media_types": { + "banner": { + "mimes": null, + "sizes": null + }, + "video": { + "sizes": [ + [ + 900, + 250 + ] + ], + "mimes": [ + "video/x-flv", + "video/mp4" + ] + }, + "audio": { + "mimes": null, + "sizes": null + } + }, + "zone_id": { + "placementId": "placement-id-1" + } + } + ], + "site": { + "domain": "https://test.com", + "referrer": "https://test.com/2016/06/12" + } + }, + "impIDs": [ + "001" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "bids": [ + { + "bid_id": "01", + "imp_id": "001", + "cpm": 1.00, + "cid": "1002088", + "crid": "1000763-1002088", + "adid": "1002088", + "w": "900", + "h": "250", + "seat": "resetdigital", + "html": "" + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "adm": "", + "cid": "1002088", + "crid": "1000763-1002088", + "id": "01", + "impid": "001", + "price": 1.00, + "w": 900, + "h": 250 + }, + "type": "video", + "seat": "resetdigital" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/resetdigital/resetdigitaltest/supplemental/invalid-device.json b/adapters/resetdigital/resetdigitaltest/supplemental/invalid-device.json new file mode 100644 index 00000000000..fca85c84d4a --- /dev/null +++ b/adapters/resetdigital/resetdigitaltest/supplemental/invalid-device.json @@ -0,0 +1,80 @@ +{ + "mockBidRequest": { + "id": "test-invalid-device", + "imp": [{ + "id": "001", + "banner": { + "h": 300, + "w": 250 + }, + "ext": { + "bidder": { + "placement_id": "placement-id-1" + } + } + }], + "site": { + "domain": "https://test.com", + "page": "https://test.com/2016/06/12" + }, + "cur": [ + "USD" + ] + }, + "httpCalls": [{ + "expectedRequest": { + "method": "POST", + "body": { + "imps": [{ + "bid_id": "test-invalid-device", + "ext": { + "gpid": "" + }, + "imp_id": "001", + "media_types": { + "banner": { + "mimes": null, + "sizes": [ + [ + 250, + 300 + ] + ] + }, + "video": { + "mimes": null, + "sizes": null + }, + "audio": { + "mimes": null, + "sizes": null + } + }, + "zone_id": { + "placementId": "placement-id-1" + } + }], + "site": { + "domain": "https://test.com", + "referrer": "https://test.com/2016/06/12" + } + }, + "impIDs": [ + "001" + ] + }, + "mockResponse": { + "status": 400, + "body": { + "error": "Unexpected status code: 400. Run with request.debug = 1 for more info" + } + } + }], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] + } + \ No newline at end of file diff --git a/adapters/resetdigital/resetdigitaltest/supplemental/invalid_cur.json b/adapters/resetdigital/resetdigitaltest/supplemental/invalid_cur.json new file mode 100644 index 00000000000..878d9c07289 --- /dev/null +++ b/adapters/resetdigital/resetdigitaltest/supplemental/invalid_cur.json @@ -0,0 +1,82 @@ +{ + "mockBidRequest": { + "id": "test-invalid-cur", + "imp": [{ + "id": "001", + "banner": { + "h": 300, + "w": 250 + }, + "ext": { + "bidder": { + "placement_id": "placement-id-1" + } + } + }], + "site": { + "domain": "https://test.com", + "page": "https://test.com/2016/06/12" + }, + "device": { + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36", + "ip": "127.0.0.1", + "language": "EN" + } + }, + "httpCalls": [{ + "expectedRequest": { + "method": "POST", + "body": { + "imps": [{ + "bid_id": "test-invalid-cur", + "ext": { + "gpid": "" + }, + "imp_id": "001", + "media_types": { + "banner": { + "mimes": null, + "sizes": [ + [ + 250, + 300 + ] + ] + }, + "video": { + "mimes": null, + "sizes": null + }, + "audio": { + "mimes": null, + "sizes": null + } + }, + "zone_id": { + "placementId": "placement-id-1" + } + }], + "site": { + "domain": "https://test.com", + "referrer": "https://test.com/2016/06/12" + } + }, + "impIDs": [ + "001" + ] + }, + "mockResponse": { + "status": 400, + "body": { + "error": "Unexpected status code: 400. Run with request.debug = 1 for more info" + } + } + }], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] + } + \ No newline at end of file diff --git a/adapters/resetdigital/resetdigitaltest/supplemental/invalid_media_def.json b/adapters/resetdigital/resetdigitaltest/supplemental/invalid_media_def.json new file mode 100644 index 00000000000..0c24e666b9f --- /dev/null +++ b/adapters/resetdigital/resetdigitaltest/supplemental/invalid_media_def.json @@ -0,0 +1,35 @@ +{ + "mockBidRequest": { + "id": "12345", + "imp": [{ + "id": "001", + "ext": { + "bidder": { + "placement_id": "placement-id-1" + } + } + }], + "site": { + "domain": "https://test.com", + "page": "https://test.com/2016/06/12" + }, + "cur": [ + "USD" + ], + "device": { + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36", + "ip": "127.0.0.1", + "language": "EN" + }, + "tmax": 500, + "debug": 1 + }, + "httpCalls": [], + "expectedMakeRequestsErrors": [ + { + "value": "failed to find matching imp for bid 001", + "comparison": "literal" + } + ], + "expectedBidResponses": [] + } \ No newline at end of file diff --git a/adapters/resetdigital/resetdigitaltest/supplemental/invalid_placement_id.json b/adapters/resetdigital/resetdigitaltest/supplemental/invalid_placement_id.json new file mode 100644 index 00000000000..14959b36d14 --- /dev/null +++ b/adapters/resetdigital/resetdigitaltest/supplemental/invalid_placement_id.json @@ -0,0 +1,43 @@ +{ + "mockBidRequest": { + "id": "12345", + "imp": [{ + "id": "001", + "video": { + "w": 900, + "h": 250, + "mimes": [ + "video/x-flv", + "video/mp4" + ] + }, + "ext": { + "bidder": { + "placement_id": 1 + } + } + }], + "site": { + "domain": "https://test.com", + "page": "https://test.com/2016/06/12" + }, + "cur": [ + "USD" + ], + "device": { + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36", + "ip": "127.0.0.1", + "language": "EN" + }, + "tmax": 500, + "debug": 1 + }, + "httpCalls": [], + "expectedMakeRequestsErrors": [ + { + "value": "json: cannot unmarshal number into Go struct field ImpExtResetDigital.placement_id of type string", + "comparison": "literal" + } + ], + "expectedBidResponses": [] + } diff --git a/adapters/resetdigital/resetdigitaltest/supplemental/invalid_video_dim.json b/adapters/resetdigital/resetdigitaltest/supplemental/invalid_video_dim.json new file mode 100644 index 00000000000..9a955ccb6a2 --- /dev/null +++ b/adapters/resetdigital/resetdigitaltest/supplemental/invalid_video_dim.json @@ -0,0 +1,83 @@ +{ + "mockBidRequest": { + "id": "12345", + "imp": [{ + "id": "001", + "video": { + "w": 0, + "h": 480, + "mimes": [ + "video/x-flv", + "video/mp4" + ] + }, + "ext": { + "bidder": { + "placement_id": "placement-id-1" + } + } + }], + "site": { + "domain": "https://test.com", + "page": "https://test.com/2016/06/12" + }, + "cur": [ + "USD" + ], + "device": { + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36", + "ip": "127.0.0.1", + "language": "EN" + }, + "tmax": 500, + "debug": 1 + }, + "httpCalls": [{ + "expectedRequest": { + "method": "POST", + "body": { + "imps": [{ + "bid_id": "12345", + "ext": { + "gpid": "" + }, + "imp_id": "001", + "media_types": { + "banner": { + "mimes": null, + "sizes": null + }, + "video": { + "sizes": null, + "mimes": [ + "video/x-flv", + "video/mp4" + ] + }, + "audio": { + "mimes": null, + "sizes": null + } + }, + "zone_id": { + "placementId": "placement-id-1" + } + }], + "site": { + "domain": "https://test.com", + "referrer": "https://test.com/2016/06/12" + } + }, + "impIDs": [ + "001" + ] + }, + "mockResponse": { + "status": 204, + "body": { + "error": "Unexpected status code: 204. Run with request.debug = 1 for more info" + } + } + }], + "expectedBidResponses": [] + } diff --git a/adapters/resetdigital/resetdigitaltest/supplemental/missing-currency.json b/adapters/resetdigital/resetdigitaltest/supplemental/missing-currency.json new file mode 100644 index 00000000000..35bf5f7165e --- /dev/null +++ b/adapters/resetdigital/resetdigitaltest/supplemental/missing-currency.json @@ -0,0 +1,105 @@ +{ + "mockBidRequest": { + "id": "12345", + "imp": [{ + "id": "001", + "banner": { + "h": 300, + "w": 250 + }, + "ext": { + "bidder": { + "placement_id": "placement-id-1" + } + } + }], + "site": { + "domain": "https://test.com", + "page": "https://test.com/2016/06/12" + }, + "device": { + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36", + "ip": "127.0.0.1", + "language": "EN" + }, + "tmax": 500 + }, + "httpCalls": [{ + "expectedRequest": { + "method": "POST", + "body": { + "imps": [{ + "bid_id": "12345", + "ext": { + "gpid": "" + }, + "imp_id": "001", + "media_types": { + "banner": { + "mimes": null, + "sizes": [ + [ + 250, + 300 + ] + ] + }, + "video": { + "mimes": null, + "sizes": null + }, + "audio": { + "mimes": null, + "sizes": null + } + }, + "zone_id": { + "placementId": "placement-id-1" + } + }], + "site": { + "domain": "https://test.com", + "referrer": "https://test.com/2016/06/12" + } + }, + "impIDs": [ + "001" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "bids": [{ + "bid_id": "01", + "imp_id": "001", + "cpm": 1.00, + "cid": "1002088", + "crid": "1000763-1002088", + "adid": "1002088", + "w": "300", + "h": "250", + "seat": "resetdigital", + "html": "" + }] + } + } + }], + + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "bid": { + "adm": "", + "cid": "1002088", + "crid": "1000763-1002088", + "id": "01", + "impid": "001", + "price": 1.00, + "w": 300, + "h": 250 + }, + "type": "banner", + "seat": "resetdigital" + }] + }] +} diff --git a/adapters/resetdigital/resetdigitaltest/supplemental/multi_format.json b/adapters/resetdigital/resetdigitaltest/supplemental/multi_format.json new file mode 100644 index 00000000000..66a441f6506 --- /dev/null +++ b/adapters/resetdigital/resetdigitaltest/supplemental/multi_format.json @@ -0,0 +1,114 @@ +{ + "mockBidRequest": { + "id": "test-multi-format", + "imp": [{ + "id": "001", + "banner": { + "w": 300, + "h": 600 + }, + "video": { + "w": 900, + "h": 250, + "mimes": ["video/mp4"] + }, + "ext": { + "bidder": { + "placement_id": "placement-id-1" + } + } + }], + "site": { + "domain": "https://test.com", + "page": "https://test.com/2016/06/12" + }, + "cur": [ + "USD" + ], + "device": { + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36", + "ip": "127.0.0.1", + "language": "EN" + }, + "tmax": 500 + }, + "httpCalls": [{ + "expectedRequest": { + "method": "POST", + "body": { + "imps": [{ + "bid_id": "test-multi-format", + "ext": { + "gpid": "" + }, + "imp_id": "001", + "media_types": { + "banner": { + "mimes": null, + "sizes": [ + [ + 300, + 600 + ] + ] + }, + "video": { + "sizes": null, + "mimes": null + }, + "audio": { + "mimes": null, + "sizes": null + } + }, + "zone_id": { + "placementId": "placement-id-1" + } + }], + "site": { + "domain": "https://test.com", + "referrer": "https://test.com/2016/06/12" + } + }, + "impIDs": [ + "001" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "bids": [{ + "bid_id": "01", + "imp_id": "001", + "cpm": 1.00, + "cid": "1002088", + "crid": "1000763-1002088", + "adid": "1002088", + "w": "300", + "h": "250", + "seat": "resetdigital", + "html": "" + }] + } + } + }], + + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "bid": { + "adm": "", + "cid": "1002088", + "crid": "1000763-1002088", + "id": "01", + "impid": "001", + "price": 1.00, + "w": 300, + "h": 250 + }, + "type": "banner", + "seat": "resetdigital" + }] + }] + } + \ No newline at end of file diff --git a/adapters/resetdigital/resetdigitaltest/supplemental/unknown_media.json b/adapters/resetdigital/resetdigitaltest/supplemental/unknown_media.json new file mode 100644 index 00000000000..2d42bf5ddd4 --- /dev/null +++ b/adapters/resetdigital/resetdigitaltest/supplemental/unknown_media.json @@ -0,0 +1,74 @@ +{ + "mockBidRequest": { + "id": "test-unknown-media-type", + "imp": [{ + "id": "001", + "audio": { + "mimes": ["audio/mpeg"] + }, + "ext": { + "bidder": { + "placement_id": "placement-id-1" + } + } + }], + "site": { + "domain": "https://test.com", + "page": "https://test.com/2016/06/12" + }, + "cur": [ + "USD" + ] + }, + "httpCalls": [{ + "expectedRequest": { + "method": "POST", + "body": { + "imps": [{ + "bid_id": "test-unknown-media-type", + "ext": { + "gpid": "" + }, + "imp_id": "001", + "media_types": { + "banner": { + "mimes": null, + "sizes": null + }, + "video": { + "mimes": null, + "sizes": null + }, + "audio": { + "sizes": null, + "mimes": ["audio/mpeg"] + } + }, + "zone_id": { + "placementId": "placement-id-1" + } + }], + "site": { + "domain": "https://test.com", + "referrer": "https://test.com/2016/06/12" + } + }, + "impIDs": [ + "001" + ] + }, + "mockResponse": { + "status": 400, + "body": { + "error": "unknown media type for bid imp ID 003" + } + } + }], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] + } + \ No newline at end of file diff --git a/adapters/response.go b/adapters/response.go index 747b6ddf9c0..ec02513ca6a 100644 --- a/adapters/response.go +++ b/adapters/response.go @@ -4,7 +4,7 @@ import ( "fmt" "net/http" - "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v3/errortypes" ) func CheckResponseStatusCodeForErrors(response *ResponseData) error { diff --git a/adapters/response_test.go b/adapters/response_test.go index 11ef1abcc5a..28fbefdf525 100644 --- a/adapters/response_test.go +++ b/adapters/response_test.go @@ -3,7 +3,7 @@ package adapters import ( "testing" - "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v3/errortypes" "github.com/stretchr/testify/assert" ) diff --git a/adapters/revcontent/revcontent.go b/adapters/revcontent/revcontent.go index e2a74c9311c..881b1d4916d 100644 --- a/adapters/revcontent/revcontent.go +++ b/adapters/revcontent/revcontent.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -78,7 +79,7 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } diff --git a/adapters/revcontent/revcontent_test.go b/adapters/revcontent/revcontent_test.go index a39a78a81dd..35e6970c7f1 100644 --- a/adapters/revcontent/revcontent_test.go +++ b/adapters/revcontent/revcontent_test.go @@ -3,9 +3,9 @@ package revcontent import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/revcontent/revcontenttest/supplemental/bad_response.json b/adapters/revcontent/revcontenttest/supplemental/bad_response.json index cf9450c533d..b9922f7d38b 100644 --- a/adapters/revcontent/revcontenttest/supplemental/bad_response.json +++ b/adapters/revcontent/revcontenttest/supplemental/bad_response.json @@ -44,7 +44,7 @@ "expectedMakeBidsErrors": [ { "comparison": "literal", - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse" + "value": "expect { or n, but found \"" } ] } diff --git a/adapters/richaudience/params_test.go b/adapters/richaudience/params_test.go index 4f7ede9bd55..8f5b2e244b3 100644 --- a/adapters/richaudience/params_test.go +++ b/adapters/richaudience/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/richaudience/richaudience.go b/adapters/richaudience/richaudience.go index 7955e3577c8..969fd312c91 100644 --- a/adapters/richaudience/richaudience.go +++ b/adapters/richaudience/richaudience.go @@ -7,10 +7,11 @@ import ( "net/url" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -157,14 +158,14 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var bidReq openrtb2.BidRequest - if err := json.Unmarshal(requestData.Body, &bidReq); err != nil { + if err := jsonutil.Unmarshal(requestData.Body, &bidReq); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: err.Error(), }} } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &bidResp); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: err.Error(), }} @@ -230,7 +231,7 @@ func validateDevice(request *openrtb2.BidRequest) (err error) { func parseImpExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpRichaudience, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { err = &errortypes.BadInput{ Message: fmt.Sprintf("not found parameters ext in ImpID : %s", imp.ID), } @@ -238,7 +239,7 @@ func parseImpExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpRichaudience, error) { } var richaudienceExt openrtb_ext.ExtImpRichaudience - if err := json.Unmarshal(bidderExt.Bidder, &richaudienceExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &richaudienceExt); err != nil { err = &errortypes.BadInput{ Message: fmt.Sprintf("invalid parameters ext in ImpID: %s", imp.ID), } diff --git a/adapters/richaudience/richaudience_test.go b/adapters/richaudience/richaudience_test.go index 6150e45e1a0..fde825ef6a3 100644 --- a/adapters/richaudience/richaudience_test.go +++ b/adapters/richaudience/richaudience_test.go @@ -5,10 +5,10 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/rise/rise.go b/adapters/rise/rise.go index 3742f768ee4..6ba15b8e1b5 100644 --- a/adapters/rise/rise.go +++ b/adapters/rise/rise.go @@ -9,9 +9,10 @@ import ( "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) // adapter is a Rise implementation of the adapters.Bidder interface. @@ -62,7 +63,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, _ *adapters.RequestData } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } @@ -93,12 +94,12 @@ func extractOrg(openRTBRequest *openrtb2.BidRequest) (string, error) { var err error for _, imp := range openRTBRequest.Imp { var bidderExt adapters.ExtImpBidder - if err = json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err = jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return "", fmt.Errorf("unmarshal bidderExt: %w", err) } var impExt openrtb_ext.ImpExtRise - if err = json.Unmarshal(bidderExt.Bidder, &impExt); err != nil { + if err = jsonutil.Unmarshal(bidderExt.Bidder, &impExt); err != nil { return "", fmt.Errorf("unmarshal ImpExtRise: %w", err) } diff --git a/adapters/rise/rise_test.go b/adapters/rise/rise_test.go index 79d34bde64f..d7235a7f3f5 100644 --- a/adapters/rise/rise_test.go +++ b/adapters/rise/rise_test.go @@ -3,9 +3,9 @@ package rise import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) const testsDir = "risetest" diff --git a/adapters/rise/risetest/supplemental/missing-bidder.json b/adapters/rise/risetest/supplemental/missing-bidder.json index 0a7cc67ca08..5cde70f5719 100644 --- a/adapters/rise/risetest/supplemental/missing-bidder.json +++ b/adapters/rise/risetest/supplemental/missing-bidder.json @@ -28,8 +28,8 @@ }, "expectedMakeRequestsErrors": [ { - "value": "extractOrg: unmarshal ImpExtRise: unexpected end of JSON input", - "comparison": "literal" + "value": "extractOrg: unmarshal ImpExtRise: expect { or n, but found", + "comparison": "startswith" } ] } diff --git a/adapters/rise/risetest/supplemental/missing-extension.json b/adapters/rise/risetest/supplemental/missing-extension.json index 74e94f45c79..6bb8594d152 100644 --- a/adapters/rise/risetest/supplemental/missing-extension.json +++ b/adapters/rise/risetest/supplemental/missing-extension.json @@ -27,8 +27,8 @@ }, "expectedMakeRequestsErrors": [ { - "value": "extractOrg: unmarshal bidderExt: unexpected end of JSON input", - "comparison": "literal" + "value": "extractOrg: unmarshal bidderExt: expect { or n, but found", + "comparison": "startswith" } ] } diff --git a/adapters/roulax/roulax.go b/adapters/roulax/roulax.go index 959aa57eca9..99238369081 100644 --- a/adapters/roulax/roulax.go +++ b/adapters/roulax/roulax.go @@ -7,10 +7,11 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -33,11 +34,11 @@ func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server co // getImpAdotExt parses and return first imp ext or nil func getImpRoulaxExt(imp *openrtb2.Imp) (openrtb_ext.ExtImpRoulax, error) { var extBidder adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &extBidder); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &extBidder); err != nil { return openrtb_ext.ExtImpRoulax{}, err } var extImpRoulax openrtb_ext.ExtImpRoulax - if err := json.Unmarshal(extBidder.Bidder, &extImpRoulax); err != nil { + if err := jsonutil.Unmarshal(extBidder.Bidder, &extImpRoulax); err != nil { return openrtb_ext.ExtImpRoulax{}, err } return extImpRoulax, nil @@ -80,7 +81,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, _ *adapters.RequestData return nil, []error{err} } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) diff --git a/adapters/roulax/roulax_test.go b/adapters/roulax/roulax_test.go index 0b13b9874c4..3bd03bbbf38 100644 --- a/adapters/roulax/roulax_test.go +++ b/adapters/roulax/roulax_test.go @@ -3,9 +3,9 @@ package roulax import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) const testsDir = "roulaxtest" diff --git a/adapters/rtbhouse/rtbhouse.go b/adapters/rtbhouse/rtbhouse.go index bd0d892b996..f499022aa16 100644 --- a/adapters/rtbhouse/rtbhouse.go +++ b/adapters/rtbhouse/rtbhouse.go @@ -5,14 +5,16 @@ import ( "errors" "fmt" "net/http" + "strconv" "strings" "github.com/buger/jsonparser" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) const ( @@ -106,14 +108,14 @@ func (adapter *RTBHouseAdapter) MakeRequests( func getImpressionExt(imp openrtb2.Imp) (*openrtb_ext.ExtImpRTBHouse, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: "Bidder extension not provided or can't be unmarshalled", } } var rtbhouseExt openrtb_ext.ExtImpRTBHouse - if err := json.Unmarshal(bidderExt.Bidder, &rtbhouseExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &rtbhouseExt); err != nil { return nil, &errortypes.BadInput{ Message: "Error while unmarshaling bidder extension", } @@ -152,7 +154,7 @@ func (adapter *RTBHouseAdapter) MakeBids( } var openRTBBidderResponse openrtb2.BidResponse - if err := json.Unmarshal(bidderRawResponse.Body, &openRTBBidderResponse); err != nil { + if err := jsonutil.Unmarshal(bidderRawResponse.Body, &openRTBBidderResponse); err != nil { return nil, []error{err} } @@ -161,8 +163,9 @@ func (adapter *RTBHouseAdapter) MakeBids( var typedBid *adapters.TypedBid for _, seatBid := range openRTBBidderResponse.SeatBid { for _, bid := range seatBid.Bid { - bid := bid // pin! -> https://github.com/kyoh86/scopelint#whats-this + bid := bid bidType, err := getMediaTypeForBid(bid) + resolveMacros(&bid) if err != nil { errs = append(errs, err) continue @@ -205,7 +208,7 @@ func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) { func getNativeAdm(adm string) (string, error) { nativeAdm := make(map[string]interface{}) - err := json.Unmarshal([]byte(adm), &nativeAdm) + err := jsonutil.Unmarshal([]byte(adm), &nativeAdm) if err != nil { return adm, errors.New("unable to unmarshal native adm") } @@ -222,3 +225,11 @@ func getNativeAdm(adm string) (string, error) { return adm, nil } + +func resolveMacros(bid *openrtb2.Bid) { + if bid != nil { + price := strconv.FormatFloat(bid.Price, 'f', -1, 64) + bid.NURL = strings.Replace(bid.NURL, "${AUCTION_PRICE}", price, -1) + bid.AdM = strings.Replace(bid.AdM, "${AUCTION_PRICE}", price, -1) + } +} diff --git a/adapters/rtbhouse/rtbhouse_test.go b/adapters/rtbhouse/rtbhouse_test.go index 7bccfa36266..c7189cffc9b 100644 --- a/adapters/rtbhouse/rtbhouse_test.go +++ b/adapters/rtbhouse/rtbhouse_test.go @@ -3,9 +3,9 @@ package rtbhouse import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) const testsDir = "rtbhousetest" diff --git a/adapters/rtbhouse/rtbhousetest/exemplary/banner-resolve-macros.json b/adapters/rtbhouse/rtbhousetest/exemplary/banner-resolve-macros.json new file mode 100644 index 00000000000..eaa3965040e --- /dev/null +++ b/adapters/rtbhouse/rtbhousetest/exemplary/banner-resolve-macros.json @@ -0,0 +1,87 @@ +{ + "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": {} + } + }] + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [{ + "seat": "rtbhouse", + "bid": [{ + "id": "randomid", + "impid": "test-imp-id", + "price": 0.500000, + "adid": "12345678", + "adm": "", + "cid": "987", + "crid": "12345678", + "h": 250, + "w": 300, + "mtype": 1 + }] + }], + "cur": "USD" + } + } + }], + + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "bid": { + "id": "randomid", + "impid": "test-imp-id", + "price": 0.5, + "adm": "", + "adid": "12345678", + "cid": "987", + "crid": "12345678", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner" + }] + }] +} diff --git a/adapters/rtbhouse/rtbhousetest/supplemental/bad_response.json b/adapters/rtbhouse/rtbhousetest/supplemental/bad_response.json index 6eb776e48aa..a2d0c8da3d4 100644 --- a/adapters/rtbhouse/rtbhousetest/supplemental/bad_response.json +++ b/adapters/rtbhouse/rtbhousetest/supplemental/bad_response.json @@ -56,7 +56,7 @@ "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/rubicon/rubicon.go b/adapters/rubicon/rubicon.go index 000850752de..baf4b3e191b 100644 --- a/adapters/rubicon/rubicon.go +++ b/adapters/rubicon/rubicon.go @@ -8,11 +8,14 @@ import ( "strconv" "strings" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/maputil" + "github.com/prebid/prebid-server/v3/version" + + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/maputil" "github.com/buger/jsonparser" "github.com/prebid/openrtb/v20/adcom1" @@ -25,6 +28,7 @@ var bannerExtContent = []byte(`{"rp":{"mime":"text/html"}}`) type RubiconAdapter struct { URI string + externalURI string XAPIUsername string XAPIPassword string } @@ -219,6 +223,7 @@ func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server co bidder := &RubiconAdapter{ URI: uri, + externalURI: server.ExternalUrl, XAPIUsername: config.XAPI.Username, XAPIPassword: config.XAPI.Password, } @@ -271,7 +276,7 @@ func (a *RubiconAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *ada rubiconRequest := *request for imp, bidderExt := range impsToExtMap { rubiconExt := bidderExt.Bidder - target, err := updateImpRpTargetWithFpdAttributes(bidderExt, rubiconExt, *imp, request.Site, request.App) + target, err := a.updateImpRpTarget(bidderExt, rubiconExt, *imp, request.Site, request.App) if err != nil { errs = append(errs, err) continue @@ -317,9 +322,11 @@ func (a *RubiconAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *ada continue } - if resolvedBidFloor > 0 { - imp.BidFloorCur = "USD" + if resolvedBidFloor >= 0 { imp.BidFloor = resolvedBidFloor + if imp.BidFloorCur != "" { + imp.BidFloorCur = "USD" + } } if request.User != nil { @@ -474,7 +481,7 @@ func (a *RubiconAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *ada if sourceCopy.SChain != nil { var sourceCopyExt openrtb_ext.ExtSource if sourceCopy.Ext != nil { - if err = json.Unmarshal(sourceCopy.Ext, &sourceCopyExt); err != nil { + if err = jsonutil.Unmarshal(sourceCopy.Ext, &sourceCopyExt); err != nil { errs = append(errs, &errortypes.BadInput{Message: err.Error()}) continue } @@ -504,7 +511,7 @@ func (a *RubiconAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *ada var regsCopyExt openrtb_ext.ExtRegs if regsCopy.Ext != nil { - if err = json.Unmarshal(regsCopy.Ext, ®sCopyExt); err != nil { + if err = jsonutil.Unmarshal(regsCopy.Ext, ®sCopyExt); err != nil { errs = append(errs, &errortypes.BadInput{Message: err.Error()}) continue } @@ -572,7 +579,7 @@ func createImpsToExtMap(imps []openrtb2.Imp) (map[*openrtb2.Imp]rubiconExtImpBid for _, imp := range imps { impCopy := imp var bidderExt rubiconExtImpBidder - if err = json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err = jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { errs = append(errs, &errortypes.BadInput{ Message: err.Error(), }) @@ -648,7 +655,7 @@ func resolveBidFloor(bidFloor float64, bidFloorCur string, reqInfo *adapters.Ext return bidFloor, nil } -func updateImpRpTargetWithFpdAttributes(extImp rubiconExtImpBidder, extImpRubicon openrtb_ext.ExtImpRubicon, +func (a *RubiconAdapter) updateImpRpTarget(extImp rubiconExtImpBidder, extImpRubicon openrtb_ext.ExtImpRubicon, imp openrtb2.Imp, site *openrtb2.Site, app *openrtb2.App) (json.RawMessage, error) { existingTarget, _, _, err := jsonparser.Get(imp.Ext, "rp", "target") @@ -716,14 +723,14 @@ func updateImpRpTargetWithFpdAttributes(extImp rubiconExtImpBidder, extImpRubico var data rubiconData if len(extImp.Data) > 0 { - err := json.Unmarshal(extImp.Data, &data) + err := jsonutil.Unmarshal(extImp.Data, &data) if err != nil { return nil, err } } var contextData rubiconData if len(extImp.Context.Data) > 0 { - err := json.Unmarshal(extImp.Context.Data, &contextData) + err := jsonutil.Unmarshal(extImp.Context.Data, &contextData) if err != nil { return nil, err } @@ -741,6 +748,11 @@ func updateImpRpTargetWithFpdAttributes(extImp rubiconExtImpBidder, extImpRubico if len(extImpRubicon.Keywords) > 0 { addStringArrayAttribute(extImpRubicon.Keywords, target, "keywords") } + + target["pbs_login"] = a.XAPIUsername + target["pbs_version"] = version.Ver + target["pbs_url"] = a.externalURI + updatedTarget, err := json.Marshal(target) if err != nil { return nil, err @@ -878,7 +890,7 @@ func rawJSONToMap(message json.RawMessage) (map[string]interface{}, error) { func mapFromRawJSON(message json.RawMessage) (map[string]interface{}, error) { targetAsMap := make(map[string]interface{}) - err := json.Unmarshal(message, &targetAsMap) + err := jsonutil.Unmarshal(message, &targetAsMap) if err != nil { return nil, err } @@ -891,7 +903,7 @@ func getSegmentIdsToCopy(data []openrtb2.Data, segTaxValues []int) []string { for _, dataRecord := range data { if dataRecord.Ext != nil { var dataExtObject rubiconDataExt - err := json.Unmarshal(dataRecord.Ext, &dataExtObject) + err := jsonutil.Unmarshal(dataRecord.Ext, &dataExtObject) if err != nil { continue } @@ -937,7 +949,7 @@ func resolveNativeObject(native *openrtb2.Native, target map[string]interface{}) return native, nil } - err := json.Unmarshal([]byte(native.Request), &target) + err := jsonutil.Unmarshal([]byte(native.Request), &target) if err != nil { return nil, err } @@ -962,7 +974,7 @@ func resolveNativeObject(native *openrtb2.Native, target map[string]interface{}) func setImpNative(jsonData []byte, requestNative map[string]interface{}) ([]byte, error) { var jsonMap map[string]interface{} - if err := json.Unmarshal(jsonData, &jsonMap); err != nil { + if err := jsonutil.Unmarshal(jsonData, &jsonMap); err != nil { return jsonData, err } @@ -1007,14 +1019,14 @@ func (a *RubiconAdapter) MakeBids(internalRequest *openrtb2.BidRequest, external } var bidResp rubiconBidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: err.Error(), }} } var bidReq openrtb2.BidRequest - if err := json.Unmarshal(externalRequest.Body, &bidReq); err != nil { + if err := jsonutil.Unmarshal(externalRequest.Body, &bidReq); err != nil { return nil, []error{err} } @@ -1069,7 +1081,7 @@ func (a *RubiconAdapter) MakeBids(internalRequest *openrtb2.BidRequest, external rubiconBidAsBytes, _ := json.Marshal(bid) if len(rubiconBidAsBytes) > 0 { - err = json.Unmarshal(rubiconBidAsBytes, &ortbBid) + err = jsonutil.Unmarshal(rubiconBidAsBytes, &ortbBid) if err != nil { return nil, []error{err} } @@ -1093,12 +1105,12 @@ func mapImpIdToCpmOverride(imps []openrtb2.Imp) map[string]float64 { impIdToCmpOverride := make(map[string]float64) for _, imp := range imps { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { continue } var rubiconExt openrtb_ext.ExtImpRubicon - if err := json.Unmarshal(bidderExt.Bidder, &rubiconExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &rubiconExt); err != nil { continue } @@ -1124,7 +1136,7 @@ func resolveAdm(bid rubiconBid) string { func cmpOverrideFromBidRequest(bidRequest *openrtb2.BidRequest) float64 { var bidRequestExt bidRequestExt - if err := json.Unmarshal(bidRequest.Ext, &bidRequestExt); err != nil { + if err := jsonutil.Unmarshal(bidRequest.Ext, &bidRequestExt); err != nil { return 0 } @@ -1137,7 +1149,7 @@ func updateBidExtWithMetaNetworkId(bid rubiconBid, buyer int) json.RawMessage { } var bidExt *extPrebid if bid.Ext != nil { - if err := json.Unmarshal(bid.Ext, &bidExt); err != nil { + if err := jsonutil.Unmarshal(bid.Ext, &bidExt); err != nil { return nil } } diff --git a/adapters/rubicon/rubicon_test.go b/adapters/rubicon/rubicon_test.go index 7a420a10eca..168c1d15343 100644 --- a/adapters/rubicon/rubicon_test.go +++ b/adapters/rubicon/rubicon_test.go @@ -8,12 +8,12 @@ import ( "strconv" "testing" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/ptrutil" "github.com/buger/jsonparser" "github.com/prebid/openrtb/v20/adcom1" @@ -232,6 +232,14 @@ func TestOpenRTBRequestWithDifferentBidFloorAttributes(t *testing.T) { expectedBidCur: "", expectedErrors: nil, }, + { + bidFloor: 0, + bidFloorCur: "EUR", + setMock: func(m *mock.Mock) {}, + expectedBidFloor: 0, + expectedBidCur: "USD", + expectedErrors: nil, + }, { bidFloor: -1, bidFloorCur: "CZK", @@ -600,6 +608,73 @@ func TestOpenRTBFirstPartyDataPopulating(t *testing.T) { } } +func TestPbsHostInfoPopulating(t *testing.T) { + bidder := RubiconAdapter{ + URI: "url", + externalURI: "externalUrl", + XAPIUsername: "username", + XAPIPassword: "password", + } + + request := &openrtb2.BidRequest{ + ID: "test-request-id", + Imp: []openrtb2.Imp{{ + ID: "test-imp-id", + Banner: &openrtb2.Banner{ + Format: []openrtb2.Format{ + {W: 300, H: 250}, + }, + }, + Ext: json.RawMessage(`{ + "bidder": { + "zoneId": 8394, + "siteId": 283282, + "accountId": 7891, + "inventory": {"key1" : "val1"}, + "visitor": {"key2" : "val2"} + } + }`), + }}, + App: &openrtb2.App{ + ID: "com.test", + Name: "testApp", + }, + } + + reqs, _ := bidder.MakeRequests(request, &adapters.ExtraRequestInfo{}) + + rubiconReq := &openrtb2.BidRequest{} + if err := json.Unmarshal(reqs[0].Body, rubiconReq); err != nil { + t.Fatalf("Unexpected error while decoding request: %s", err) + } + + var rpImpExt rubiconImpExt + if err := json.Unmarshal(rubiconReq.Imp[0].Ext, &rpImpExt); err != nil { + t.Fatalf("Error unmarshalling imp.ext: %s", err) + } + + var pbsLogin string + pbsLogin, err := jsonparser.GetString(rpImpExt.RP.Target, "pbs_login") + if err != nil { + t.Fatal("Error extracting pbs_login") + } + assert.Equal(t, pbsLogin, "username", "Unexpected pbs_login value") + + var pbsVersion string + pbsVersion, err = jsonparser.GetString(rpImpExt.RP.Target, "pbs_version") + if err != nil { + t.Fatal("Error extracting pbs_version") + } + assert.Equal(t, pbsVersion, "", "Unexpected pbs_version value") + + var pbsUrl string + pbsUrl, err = jsonparser.GetString(rpImpExt.RP.Target, "pbs_url") + if err != nil { + t.Fatal("Error extracting pbs_url") + } + assert.Equal(t, pbsUrl, "externalUrl", "Unexpected pbs_url value") +} + func TestOpenRTBRequestWithBadvOverflowed(t *testing.T) { bidder := new(RubiconAdapter) @@ -982,7 +1057,7 @@ func TestOpenRTBResponseOverridePriceFromCorrespondingImp(t *testing.T) { "siteId": 68780, "zoneId": 327642, "debug": { - "cpmoverride" : 20 + "cpmoverride" : 20 } }}`), }}, diff --git a/adapters/rubicon/rubicontest/exemplary/25-26-transition-period.json b/adapters/rubicon/rubicontest/exemplary/25-26-transition-period.json index d64f2361521..0196c93049a 100644 --- a/adapters/rubicon/rubicontest/exemplary/25-26-transition-period.json +++ b/adapters/rubicon/rubicontest/exemplary/25-26-transition-period.json @@ -364,7 +364,10 @@ "pagecat": [ "val1", "val2" - ] + ], + "pbs_login": "xuser", + "pbs_url": "http://hosturl.com", + "pbs_version": "" }, "track": { "mint": "", diff --git a/adapters/rubicon/rubicontest/exemplary/app-imp-fpd.json b/adapters/rubicon/rubicontest/exemplary/app-imp-fpd.json index 914cfce03de..4e7c2a92148 100644 --- a/adapters/rubicon/rubicontest/exemplary/app-imp-fpd.json +++ b/adapters/rubicon/rubicontest/exemplary/app-imp-fpd.json @@ -349,7 +349,10 @@ "sectioncat": [ "sectionCat1", "sectionCat2" - ] + ], + "pbs_login": "xuser", + "pbs_url": "http://hosturl.com", + "pbs_version": "" }, "track": { "mint": "", diff --git a/adapters/rubicon/rubicontest/exemplary/bidonmultiformat.json b/adapters/rubicon/rubicontest/exemplary/bidonmultiformat.json index 33757cd889d..c47cd3f9c36 100644 --- a/adapters/rubicon/rubicontest/exemplary/bidonmultiformat.json +++ b/adapters/rubicon/rubicontest/exemplary/bidonmultiformat.json @@ -106,7 +106,10 @@ ], "search": [ "someSearch" - ] + ], + "pbs_login": "xuser", + "pbs_url": "http://hosturl.com", + "pbs_version": "" }, "track": { "mint": "", @@ -213,7 +216,10 @@ ], "search": [ "someSearch" - ] + ], + "pbs_login": "xuser", + "pbs_url": "http://hosturl.com", + "pbs_version": "" }, "track": { "mint": "", diff --git a/adapters/rubicon/rubicontest/exemplary/flexible-schema.json b/adapters/rubicon/rubicontest/exemplary/flexible-schema.json index 0434f6bab83..f4dcebc2280 100644 --- a/adapters/rubicon/rubicontest/exemplary/flexible-schema.json +++ b/adapters/rubicon/rubicontest/exemplary/flexible-schema.json @@ -349,7 +349,10 @@ "sectioncat": [ "sectionCat1", "sectionCat2" - ] + ], + "pbs_login": "xuser", + "pbs_url": "http://hosturl.com", + "pbs_version": "" }, "track": { "mint": "", diff --git a/adapters/rubicon/rubicontest/exemplary/hardcode-secure.json b/adapters/rubicon/rubicontest/exemplary/hardcode-secure.json index c349b86da91..9df133385c6 100644 --- a/adapters/rubicon/rubicontest/exemplary/hardcode-secure.json +++ b/adapters/rubicon/rubicontest/exemplary/hardcode-secure.json @@ -323,7 +323,10 @@ "pagecat": [ "val1", "val2" - ] + ], + "pbs_login": "xuser", + "pbs_url": "http://hosturl.com", + "pbs_version": "" }, "track": { "mint": "", diff --git a/adapters/rubicon/rubicontest/exemplary/non-bidonmultiformat.json b/adapters/rubicon/rubicontest/exemplary/non-bidonmultiformat.json index 1e1485861fd..dae54aca730 100644 --- a/adapters/rubicon/rubicontest/exemplary/non-bidonmultiformat.json +++ b/adapters/rubicon/rubicontest/exemplary/non-bidonmultiformat.json @@ -105,7 +105,10 @@ ], "search": [ "someSearch" - ] + ], + "pbs_login": "xuser", + "pbs_url": "http://hosturl.com", + "pbs_version": "" }, "track": { "mint": "", diff --git a/adapters/rubicon/rubicontest/exemplary/simple-banner.json b/adapters/rubicon/rubicontest/exemplary/simple-banner.json index d2da4ce8a8d..21ec12990da 100644 --- a/adapters/rubicon/rubicontest/exemplary/simple-banner.json +++ b/adapters/rubicon/rubicontest/exemplary/simple-banner.json @@ -323,7 +323,10 @@ "pagecat": [ "val1", "val2" - ] + ], + "pbs_login": "xuser", + "pbs_url": "http://hosturl.com", + "pbs_version": "" }, "track": { "mint": "", diff --git a/adapters/rubicon/rubicontest/exemplary/simple-native.json b/adapters/rubicon/rubicontest/exemplary/simple-native.json index f5e43ff9211..98bfdb4f845 100644 --- a/adapters/rubicon/rubicontest/exemplary/simple-native.json +++ b/adapters/rubicon/rubicontest/exemplary/simple-native.json @@ -307,7 +307,10 @@ "pagecat": [ "val1", "val2" - ] + ], + "pbs_login": "xuser", + "pbs_url": "http://hosturl.com", + "pbs_version": "" }, "track": { "mint": "", diff --git a/adapters/rubicon/rubicontest/exemplary/simple-video.json b/adapters/rubicon/rubicontest/exemplary/simple-video.json index 5552dd71816..3bceef2cf38 100644 --- a/adapters/rubicon/rubicontest/exemplary/simple-video.json +++ b/adapters/rubicon/rubicontest/exemplary/simple-video.json @@ -322,7 +322,10 @@ "pagecat": [ "val1", "val2" - ] + ], + "pbs_login": "xuser", + "pbs_url": "http://hosturl.com", + "pbs_version": "" }, "track": { "mint": "", diff --git a/adapters/rubicon/rubicontest/exemplary/site-imp-fpd.json b/adapters/rubicon/rubicontest/exemplary/site-imp-fpd.json index 87c20e227b1..b8519dabdb3 100644 --- a/adapters/rubicon/rubicontest/exemplary/site-imp-fpd.json +++ b/adapters/rubicon/rubicontest/exemplary/site-imp-fpd.json @@ -473,7 +473,10 @@ "sectionCat1", "sectionCat2" ], - "dfp_ad_unit_code": "adSlotFromData" + "dfp_ad_unit_code": "adSlotFromData", + "pbs_login": "xuser", + "pbs_url": "http://hosturl.com", + "pbs_version": "" }, "track": { "mint": "", diff --git a/adapters/rubicon/rubicontest/exemplary/user-fpd.json b/adapters/rubicon/rubicontest/exemplary/user-fpd.json index 42ab0f0babe..c989c6a1e19 100644 --- a/adapters/rubicon/rubicontest/exemplary/user-fpd.json +++ b/adapters/rubicon/rubicontest/exemplary/user-fpd.json @@ -275,7 +275,10 @@ "search": [ "someSearch" ], - "dfp_ad_unit_code": "someAdSlot" + "dfp_ad_unit_code": "someAdSlot", + "pbs_login": "xuser", + "pbs_url": "http://hosturl.com", + "pbs_version": "" }, "track": { "mint": "", diff --git a/adapters/rubicon/rubicontest/supplemental/invalid-bidder-ext.json b/adapters/rubicon/rubicontest/supplemental/invalid-bidder-ext.json index c9114d1d4d4..08141bf6065 100644 --- a/adapters/rubicon/rubicontest/supplemental/invalid-bidder-ext.json +++ b/adapters/rubicon/rubicontest/supplemental/invalid-bidder-ext.json @@ -25,7 +25,7 @@ "expectedMakeRequestsErrors": [ { - "value": "json: cannot unmarshal array into Go struct field rubiconExtImpBidder.bidder of type openrtb_ext.ExtImpRubicon", + "value": "cannot unmarshal rubicon.rubiconExtImpBidder.Bidder: expect { or n, but found [", "comparison": "literal" } ] diff --git a/adapters/rubicon/rubicontest/supplemental/no-site-content-data.json b/adapters/rubicon/rubicontest/supplemental/no-site-content-data.json index b2f463a95dc..b121d75a0f6 100644 --- a/adapters/rubicon/rubicontest/supplemental/no-site-content-data.json +++ b/adapters/rubicon/rubicontest/supplemental/no-site-content-data.json @@ -234,7 +234,10 @@ "pagecat": [ "val1", "val2" - ] + ], + "pbs_login": "xuser", + "pbs_url": "http://hosturl.com", + "pbs_version": "" }, "track": { "mint": "", diff --git a/adapters/rubicon/rubicontest/supplemental/no-site-content.json b/adapters/rubicon/rubicontest/supplemental/no-site-content.json index 5744b2c9e47..65c3cacd858 100644 --- a/adapters/rubicon/rubicontest/supplemental/no-site-content.json +++ b/adapters/rubicon/rubicontest/supplemental/no-site-content.json @@ -230,7 +230,10 @@ "pagecat": [ "val1", "val2" - ] + ], + "pbs_login": "xuser", + "pbs_url": "http://hosturl.com", + "pbs_version": "" }, "track": { "mint": "", diff --git a/adapters/sa_lunamedia/params_test.go b/adapters/sa_lunamedia/params_test.go index 568ac83d9cf..640af6ceb3a 100644 --- a/adapters/sa_lunamedia/params_test.go +++ b/adapters/sa_lunamedia/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/sa_lunamedia/salunamedia.go b/adapters/sa_lunamedia/salunamedia.go index 89d5d9f691a..b75ccd9f8a4 100644 --- a/adapters/sa_lunamedia/salunamedia.go +++ b/adapters/sa_lunamedia/salunamedia.go @@ -7,10 +7,11 @@ import ( "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -86,7 +87,7 @@ func (a *adapter) MakeBids( responseBody := bidderRawResponse.Body var bidResp openrtb2.BidResponse - if err := json.Unmarshal(responseBody, &bidResp); err != nil { + if err := jsonutil.Unmarshal(responseBody, &bidResp); err != nil { return nil, []error{err} } @@ -111,7 +112,7 @@ func (a *adapter) MakeBids( var bidExt bidExt var bidType openrtb_ext.BidType - if err := json.Unmarshal(bid.Ext, &bidExt); err != nil { + if err := jsonutil.Unmarshal(bid.Ext, &bidExt); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: "Missing BidExt", }} diff --git a/adapters/sa_lunamedia/salunamedia_test.go b/adapters/sa_lunamedia/salunamedia_test.go index 4bcfb96f28e..3247bb0a57c 100644 --- a/adapters/sa_lunamedia/salunamedia_test.go +++ b/adapters/sa_lunamedia/salunamedia_test.go @@ -3,9 +3,9 @@ package salunamedia import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/sa_lunamedia/salunamediatest/supplemental/bad-response.json b/adapters/sa_lunamedia/salunamediatest/supplemental/bad-response.json index 72262b5d533..33020bc6d3c 100644 --- a/adapters/sa_lunamedia/salunamediatest/supplemental/bad-response.json +++ b/adapters/sa_lunamedia/salunamediatest/supplemental/bad-response.json @@ -90,7 +90,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ], diff --git a/adapters/screencore/params_test.go b/adapters/screencore/params_test.go index 7220f9945cf..508731fbdee 100644 --- a/adapters/screencore/params_test.go +++ b/adapters/screencore/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/screencore/screencore.go b/adapters/screencore/screencore.go index 6011b9bbd80..17dab9084bd 100644 --- a/adapters/screencore/screencore.go +++ b/adapters/screencore/screencore.go @@ -7,11 +7,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -88,13 +89,13 @@ func (a *adapter) MakeRequests(openRTBRequest *openrtb2.BidRequest, reqInfo *ada func getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtScreencore, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: "Error parsing screencoreExt - " + err.Error(), } } var screencoreExt openrtb_ext.ExtScreencore - if err := json.Unmarshal(bidderExt.Bidder, &screencoreExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &screencoreExt); err != nil { return nil, &errortypes.BadInput{ Message: "Error parsing bidderExt - " + err.Error(), } @@ -130,7 +131,7 @@ func (a *adapter) MakeBids(openRTBRequest *openrtb2.BidRequest, requestToBidder responseBody := bidderRawResponse.Body var bidResp openrtb2.BidResponse - if err := json.Unmarshal(responseBody, &bidResp); err != nil { + if err := jsonutil.Unmarshal(responseBody, &bidResp); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: "Bad Server Response", }} diff --git a/adapters/screencore/screencore_test.go b/adapters/screencore/screencore_test.go index 4dc22b3cd6a..2451231fe5f 100644 --- a/adapters/screencore/screencore_test.go +++ b/adapters/screencore/screencore_test.go @@ -3,9 +3,9 @@ package screencore import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/screencore/screencoretest/supplemental/invalid-bidder-ext-object.json b/adapters/screencore/screencoretest/supplemental/invalid-bidder-ext-object.json index 4dc5c5a62bc..016fbd43490 100644 --- a/adapters/screencore/screencoretest/supplemental/invalid-bidder-ext-object.json +++ b/adapters/screencore/screencoretest/supplemental/invalid-bidder-ext-object.json @@ -1,7 +1,7 @@ { "expectedMakeRequestsErrors": [ { - "value": "Error parsing bidderExt - json: cannot unmarshal string into Go value of type openrtb_ext.ExtScreencore", + "value": "Error parsing bidderExt - expect { or n, but found \"", "comparison": "literal" } ], diff --git a/adapters/screencore/screencoretest/supplemental/invalid-screencore-ext-object.json b/adapters/screencore/screencoretest/supplemental/invalid-screencore-ext-object.json index b52e18fab50..4c3c9d95055 100644 --- a/adapters/screencore/screencoretest/supplemental/invalid-screencore-ext-object.json +++ b/adapters/screencore/screencoretest/supplemental/invalid-screencore-ext-object.json @@ -1,7 +1,7 @@ { "expectedMakeRequestsErrors": [ { - "value": "Error parsing screencoreExt - json: cannot unmarshal string into Go value of type adapters.ExtImpBidder", + "value": "Error parsing screencoreExt - expect { or n, but found \"", "comparison": "literal" } ], diff --git a/adapters/seedingAlliance/params_test.go b/adapters/seedingAlliance/params_test.go index deb964a3743..56433b003ce 100644 --- a/adapters/seedingAlliance/params_test.go +++ b/adapters/seedingAlliance/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/seedingAlliance/seedingAlliance.go b/adapters/seedingAlliance/seedingAlliance.go index 1d6e9a8fb12..1e23d4e25ab 100644 --- a/adapters/seedingAlliance/seedingAlliance.go +++ b/adapters/seedingAlliance/seedingAlliance.go @@ -9,11 +9,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -86,7 +87,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } @@ -123,7 +124,7 @@ func resolvePriceMacro(bid *openrtb2.Bid) { func getMediaTypeForBid(ext json.RawMessage) (openrtb_ext.BidType, error) { var bidExt openrtb_ext.ExtBid - if err := json.Unmarshal(ext, &bidExt); err != nil { + if err := jsonutil.Unmarshal(ext, &bidExt); err != nil { return "", fmt.Errorf("could not unmarshal openrtb_ext.ExtBid: %w", err) } @@ -149,11 +150,11 @@ func getExtInfo(imp *openrtb2.Imp) (string, error) { accountId := "pbs" - if err := json.Unmarshal(imp.Ext, &ext); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &ext); err != nil { return "", fmt.Errorf("could not unmarshal adapters.ExtImpBidder: %w", err) } - if err := json.Unmarshal(ext.Bidder, &extSA); err != nil { + if err := jsonutil.Unmarshal(ext.Bidder, &extSA); err != nil { return "", fmt.Errorf("could not unmarshal openrtb_ext.ImpExtSeedingAlliance: %w", err) } diff --git a/adapters/seedingAlliance/seedingAlliance_test.go b/adapters/seedingAlliance/seedingAlliance_test.go index ae9b888e4b1..b432d0577f4 100644 --- a/adapters/seedingAlliance/seedingAlliance_test.go +++ b/adapters/seedingAlliance/seedingAlliance_test.go @@ -5,10 +5,10 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/seedingAlliance/seedingAlliancetest/supplemental/invalid_tag_id.json b/adapters/seedingAlliance/seedingAlliancetest/supplemental/invalid_tag_id.json index c79795e48e2..7d4c212d611 100644 --- a/adapters/seedingAlliance/seedingAlliancetest/supplemental/invalid_tag_id.json +++ b/adapters/seedingAlliance/seedingAlliancetest/supplemental/invalid_tag_id.json @@ -1,7 +1,7 @@ { "expectedMakeRequestsErrors": [ { - "value": "could not unmarshal openrtb_ext.ImpExtSeedingAlliance: json: cannot unmarshal number into Go struct field ImpExtSeedingAlliance.adUnitId of type string", + "value": "could not unmarshal openrtb_ext.ImpExtSeedingAlliance: cannot unmarshal openrtb_ext.ImpExtSeedingAlliance.AdUnitID: expects \" or n, but found 1", "comparison": "literal" } ], diff --git a/adapters/sharethrough/params_test.go b/adapters/sharethrough/params_test.go index 3c2d80dfa8b..a7011ab3767 100644 --- a/adapters/sharethrough/params_test.go +++ b/adapters/sharethrough/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/sharethrough/sharethrough.go b/adapters/sharethrough/sharethrough.go index fd303c6feff..cf5c65a7364 100644 --- a/adapters/sharethrough/sharethrough.go +++ b/adapters/sharethrough/sharethrough.go @@ -7,11 +7,12 @@ import ( "strings" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/version" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/version" ) var adapterVersion = "10.0" @@ -41,7 +42,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E modifiableSource = *request.Source } var sourceExt map[string]interface{} - if err := json.Unmarshal(modifiableSource.Ext, &sourceExt); err == nil { + if err := jsonutil.Unmarshal(modifiableSource.Ext, &sourceExt); err == nil { sourceExt["str"] = adapterVersion sourceExt["version"] = version.Ver } else { @@ -58,12 +59,12 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E for _, imp := range request.Imp { // Extract Sharethrough Params var strImpExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &strImpExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &strImpExt); err != nil { errors = append(errors, err) continue } var strImpParams openrtb_ext.ExtImpSharethrough - if err := json.Unmarshal(strImpExt.Bidder, &strImpParams); err != nil { + if err := jsonutil.Unmarshal(strImpExt.Bidder, &strImpParams); err != nil { errors = append(errors, err) continue } @@ -128,12 +129,12 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var bidReq openrtb2.BidRequest - if err := json.Unmarshal(requestData.Body, &bidReq); err != nil { + if err := jsonutil.Unmarshal(requestData.Body, &bidReq); err != nil { return nil, []error{err} } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } @@ -197,7 +198,7 @@ func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) { if bid.Ext != nil { var bidExt openrtb_ext.ExtBid - err := json.Unmarshal(bid.Ext, &bidExt) + err := jsonutil.Unmarshal(bid.Ext, &bidExt) if err == nil && bidExt.Prebid != nil { return openrtb_ext.ParseBidType(string(bidExt.Prebid.Type)) } diff --git a/adapters/sharethrough/sharethrough_test.go b/adapters/sharethrough/sharethrough_test.go index 2983487ac40..6ca7d9c7ef4 100644 --- a/adapters/sharethrough/sharethrough_test.go +++ b/adapters/sharethrough/sharethrough_test.go @@ -3,9 +3,9 @@ package sharethrough import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/silvermob/params_test.go b/adapters/silvermob/params_test.go index d69171ed78d..9dc9a34eb60 100644 --- a/adapters/silvermob/params_test.go +++ b/adapters/silvermob/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // TestValidParams makes sure that the silvermob schema accepts all imp.ext fields which we intend to support. diff --git a/adapters/silvermob/silvermob.go b/adapters/silvermob/silvermob.go index 636f126147a..5c80240e722 100644 --- a/adapters/silvermob/silvermob.go +++ b/adapters/silvermob/silvermob.go @@ -7,11 +7,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type SilverMobAdapter struct { @@ -111,13 +112,13 @@ func (a *SilverMobAdapter) MakeRequests( func (a *SilverMobAdapter) getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtSilverMob, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: fmt.Sprintf("error unmarshaling imp.ext: %s", err.Error()), } } var silvermobExt openrtb_ext.ExtSilverMob - if err := json.Unmarshal(bidderExt.Bidder, &silvermobExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &silvermobExt); err != nil { return nil, &errortypes.BadInput{ Message: fmt.Sprintf("error unmarshaling imp.ext.bidder: %s", err.Error()), } @@ -161,7 +162,7 @@ func (a *SilverMobAdapter) MakeBids( responseBody := bidderRawResponse.Body var bidResp openrtb2.BidResponse - if err := json.Unmarshal(responseBody, &bidResp); err != nil { + if err := jsonutil.Unmarshal(responseBody, &bidResp); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: fmt.Sprintf("Error unmarshaling server Response: %s", err), }} diff --git a/adapters/silvermob/silvermob_test.go b/adapters/silvermob/silvermob_test.go index ce08651ff59..991a758b4ef 100644 --- a/adapters/silvermob/silvermob_test.go +++ b/adapters/silvermob/silvermob_test.go @@ -3,9 +3,9 @@ package silvermob import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/silvermob/silvermobtest/supplemental/invalid-response.json b/adapters/silvermob/silvermobtest/supplemental/invalid-response.json index f78979db334..353adb84f85 100644 --- a/adapters/silvermob/silvermobtest/supplemental/invalid-response.json +++ b/adapters/silvermob/silvermobtest/supplemental/invalid-response.json @@ -112,7 +112,7 @@ }], "expectedMakeBidsErrors": [ { - "value": "Error unmarshaling server Response: json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "Error unmarshaling server Response: expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/silvermob/silvermobtest/supplemental/invalid-silvermob-ext-object.json b/adapters/silvermob/silvermobtest/supplemental/invalid-silvermob-ext-object.json index 090d7aff5b6..1f452e8d289 100644 --- a/adapters/silvermob/silvermobtest/supplemental/invalid-silvermob-ext-object.json +++ b/adapters/silvermob/silvermobtest/supplemental/invalid-silvermob-ext-object.json @@ -21,7 +21,7 @@ }, "expectedMakeRequestsErrors": [ { - "value": "error unmarshaling imp.ext: json: cannot unmarshal string into Go value of type adapters.ExtImpBidder", + "value": "error unmarshaling imp.ext: expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/silverpush/params_test.go b/adapters/silverpush/params_test.go index 2a20aa2ff71..d98f413a711 100644 --- a/adapters/silverpush/params_test.go +++ b/adapters/silverpush/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file intends to test static/bidder-params/silverpush.json diff --git a/adapters/silverpush/silverpush.go b/adapters/silverpush/silverpush.go index 2ed554a2594..049b0d5a93f 100644 --- a/adapters/silverpush/silverpush.go +++ b/adapters/silverpush/silverpush.go @@ -6,11 +6,12 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/ptrutil" ) const ( @@ -118,11 +119,11 @@ func setUser(req *openrtb2.BidRequest) error { var userExtRaw map[string]json.RawMessage if req.User != nil && req.User.Ext != nil { - if err := json.Unmarshal(req.User.Ext, &userExtRaw); err != nil { + if err := jsonutil.Unmarshal(req.User.Ext, &userExtRaw); err != nil { return &errortypes.BadInput{Message: "Invalid user.ext."} } if userExtDataRaw, ok := userExtRaw["data"]; ok { - if err := json.Unmarshal(userExtDataRaw, &extUser); err != nil { + if err := jsonutil.Unmarshal(userExtDataRaw, &extUser); err != nil { return &errortypes.BadInput{Message: "Invalid user.ext.data."} } var userCopy = *req.User @@ -217,13 +218,13 @@ func setBannerDimension(banner *openrtb2.Banner) (*openrtb2.Banner, error) { func setPublisherId(req *openrtb2.BidRequest, imp *openrtb2.Imp, impExt *openrtb_ext.ImpExtSilverpush) error { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return &errortypes.BadInput{ Message: err.Error(), } } - if err := json.Unmarshal(bidderExt.Bidder, impExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, impExt); err != nil { return &errortypes.BadInput{ Message: err.Error(), } @@ -283,7 +284,7 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } diff --git a/adapters/silverpush/silverpush_test.go b/adapters/silverpush/silverpush_test.go index 7d515bf242c..f953584f0b3 100644 --- a/adapters/silverpush/silverpush_test.go +++ b/adapters/silverpush/silverpush_test.go @@ -5,10 +5,10 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/silverpush/silverpushtest/supplemental/bad-imp-ext-bidder.json b/adapters/silverpush/silverpushtest/supplemental/bad-imp-ext-bidder.json index 5bedcfe34c6..5621dfbe2d4 100644 --- a/adapters/silverpush/silverpushtest/supplemental/bad-imp-ext-bidder.json +++ b/adapters/silverpush/silverpushtest/supplemental/bad-imp-ext-bidder.json @@ -77,7 +77,7 @@ }, "expectedMakeRequestsErrors": [ { - "value": "json: cannot unmarshal number into Go value of type openrtb_ext.ImpExtSilverpush", + "value": "expect { or n, but found 9", "comparison": "literal" } ] diff --git a/adapters/silverpush/silverpushtest/supplemental/bad-imp-ext.json b/adapters/silverpush/silverpushtest/supplemental/bad-imp-ext.json index 7c5b7af90e2..16d7aaf7159 100644 --- a/adapters/silverpush/silverpushtest/supplemental/bad-imp-ext.json +++ b/adapters/silverpush/silverpushtest/supplemental/bad-imp-ext.json @@ -75,7 +75,7 @@ }, "expectedMakeRequestsErrors": [ { - "value": "json: cannot unmarshal number into Go value of type adapters.ExtImpBidder", + "value": "expect { or n, but found 9", "comparison": "literal" } ] diff --git a/adapters/silverpush/silverpushtest/supplemental/bad-response-unmarshal.json b/adapters/silverpush/silverpushtest/supplemental/bad-response-unmarshal.json index d6cad0fc5f7..dba093b2dc3 100644 --- a/adapters/silverpush/silverpushtest/supplemental/bad-response-unmarshal.json +++ b/adapters/silverpush/silverpushtest/supplemental/bad-response-unmarshal.json @@ -178,7 +178,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/smaato/banner.go b/adapters/smaato/banner.go new file mode 100644 index 00000000000..643405facf3 --- /dev/null +++ b/adapters/smaato/banner.go @@ -0,0 +1,22 @@ +package smaato + +import ( + "fmt" + "net/url" + "strings" +) + +func extractAdmBanner(adMarkup string, curls []string) string { + if len(curls) > 0 { + var clickEvent string + var clicks strings.Builder + for _, clicktracker := range curls { + clicks.WriteString("fetch(decodeURIComponent('" + url.QueryEscape(clicktracker) + "'.replace(/\\+/g, ' ')), " + + "{cache: 'no-cache'});") + } + clickEvent = fmt.Sprintf(`onclick="%s"`, clicks.String()) + return fmt.Sprintf(`
%s
`, clickEvent, adMarkup) + } + + return adMarkup +} diff --git a/adapters/smaato/banner_test.go b/adapters/smaato/banner_test.go new file mode 100644 index 00000000000..bf3e877ae18 --- /dev/null +++ b/adapters/smaato/banner_test.go @@ -0,0 +1,42 @@ +package smaato + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func TestExtractAdmBanner(t *testing.T) { + tests := []struct { + testName string + adMarkup string + curls []string + expectedAdMarkup string + }{ + { + testName: "extract_banner_without_curls", + adMarkup: ``, + expectedAdMarkup: ``, + curls: []string{}, + }, + { + testName: "extract_banner_with_nil_curls", + adMarkup: ``, + expectedAdMarkup: ``, + curls: nil, + }, + { + testName: "extract_banner_with_curls", + adMarkup: ``, + expectedAdMarkup: `
`, + curls: []string{"curls.net"}, + }, + } + + for _, tt := range tests { + t.Run(tt.testName, func(t *testing.T) { + adMarkup := extractAdmBanner(tt.adMarkup, tt.curls) + + assert.Equal(t, tt.expectedAdMarkup, adMarkup) + }) + } +} diff --git a/adapters/smaato/image.go b/adapters/smaato/image.go deleted file mode 100644 index 8e601187ccd..00000000000 --- a/adapters/smaato/image.go +++ /dev/null @@ -1,50 +0,0 @@ -package smaato - -import ( - "encoding/json" - "fmt" - "net/url" - "strings" - - "github.com/prebid/prebid-server/v2/errortypes" -) - -type imageAd struct { - Image image `json:"image"` -} -type image struct { - Img img `json:"img"` - Impressiontrackers []string `json:"impressiontrackers"` - Clicktrackers []string `json:"clicktrackers"` -} -type img struct { - URL string `json:"url"` - W int `json:"w"` - H int `json:"h"` - Ctaurl string `json:"ctaurl"` -} - -func extractAdmImage(adMarkup string) (string, error) { - var imageAd imageAd - if err := json.Unmarshal([]byte(adMarkup), &imageAd); err != nil { - return "", &errortypes.BadServerResponse{ - Message: fmt.Sprintf("Invalid ad markup %s.", adMarkup), - } - } - - var clickEvent strings.Builder - for _, clicktracker := range imageAd.Image.Clicktrackers { - clickEvent.WriteString("fetch(decodeURIComponent('" + url.QueryEscape(clicktracker) + "'.replace(/\\+/g, ' ')), " + - "{cache: 'no-cache'});") - } - - var impressionTracker strings.Builder - for _, impression := range imageAd.Image.Impressiontrackers { - impressionTracker.WriteString(fmt.Sprintf(``, impression)) - } - - imageAdMarkup := fmt.Sprintf(`
%s
`, - &clickEvent, url.QueryEscape(imageAd.Image.Img.Ctaurl), imageAd.Image.Img.URL, imageAd.Image.Img.W, imageAd.Image.Img.H, &impressionTracker) - - return imageAdMarkup, nil -} diff --git a/adapters/smaato/image_test.go b/adapters/smaato/image_test.go deleted file mode 100644 index 1ba99ddd7c5..00000000000 --- a/adapters/smaato/image_test.go +++ /dev/null @@ -1,51 +0,0 @@ -package smaato - -import ( - "github.com/stretchr/testify/assert" - "testing" -) - -func TestExtractAdmImage(t *testing.T) { - tests := []struct { - testName string - adMarkup string - expectedAdMarkup string - expectedError string - }{ - { - testName: "extract image", - adMarkup: "{\"image\":{\"img\":{\"url\":\"//prebid-test.smaatolabs.net/img/320x50.jpg\"," + - "\"w\":350,\"h\":50,\"ctaurl\":\"//prebid-test.smaatolabs.net/track/ctaurl/1\"}," + - "\"impressiontrackers\":[\"//prebid-test.smaatolabs.net/track/imp/1\",\"//prebid-test.smaatolabs.net/track/imp/2\"]," + - "\"clicktrackers\":[\"//prebid-test.smaatolabs.net/track/click/1\",\"//prebid-test.smaatolabs.net/track/click/2\"]}}", - expectedAdMarkup: `
` + - `` + - `` + - `
`, - expectedError: "", - }, - { - testName: "invalid adMarkup", - adMarkup: "{", - expectedAdMarkup: "", - expectedError: "Invalid ad markup {.", - }, - } - - for _, tt := range tests { - t.Run(tt.testName, func(t *testing.T) { - adMarkup, err := extractAdmImage(tt.adMarkup) - - if tt.expectedError != "" { - assert.EqualError(t, err, tt.expectedError) - } else { - assert.NoError(t, err) - } - - assert.Equal(t, tt.expectedAdMarkup, adMarkup) - }) - } -} diff --git a/adapters/smaato/native.go b/adapters/smaato/native.go index b18a5fc4490..2cbcae471c2 100644 --- a/adapters/smaato/native.go +++ b/adapters/smaato/native.go @@ -4,7 +4,8 @@ import ( "encoding/json" "fmt" - "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type nativeAd struct { @@ -13,7 +14,7 @@ type nativeAd struct { func extractAdmNative(adMarkup string) (string, error) { var nativeAd nativeAd - if err := json.Unmarshal([]byte(adMarkup), &nativeAd); err != nil { + if err := jsonutil.Unmarshal([]byte(adMarkup), &nativeAd); err != nil { return "", &errortypes.BadServerResponse{ Message: fmt.Sprintf("Invalid ad markup %s.", adMarkup), } diff --git a/adapters/smaato/params_test.go b/adapters/smaato/params_test.go index d1c334acbfa..7acb42c6960 100644 --- a/adapters/smaato/params_test.go +++ b/adapters/smaato/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file intends to test static/bidder-params/smaato.json diff --git a/adapters/smaato/richmedia.go b/adapters/smaato/richmedia.go deleted file mode 100644 index 09e1f2bf3d6..00000000000 --- a/adapters/smaato/richmedia.go +++ /dev/null @@ -1,50 +0,0 @@ -package smaato - -import ( - "encoding/json" - "fmt" - "net/url" - "strings" - - "github.com/prebid/prebid-server/v2/errortypes" -) - -type richMediaAd struct { - RichMedia richmedia `json:"richmedia"` -} -type mediadata struct { - Content string `json:"content"` - W int `json:"w"` - H int `json:"h"` -} - -type richmedia struct { - MediaData mediadata `json:"mediadata"` - Impressiontrackers []string `json:"impressiontrackers"` - Clicktrackers []string `json:"clicktrackers"` -} - -func extractAdmRichMedia(adMarkup string) (string, error) { - var richMediaAd richMediaAd - if err := json.Unmarshal([]byte(adMarkup), &richMediaAd); err != nil { - return "", &errortypes.BadServerResponse{ - Message: fmt.Sprintf("Invalid ad markup %s.", adMarkup), - } - } - - var clickEvent strings.Builder - var impressionTracker strings.Builder - - for _, clicktracker := range richMediaAd.RichMedia.Clicktrackers { - clickEvent.WriteString("fetch(decodeURIComponent('" + url.QueryEscape(clicktracker) + "'), " + - "{cache: 'no-cache'});") - } - for _, impression := range richMediaAd.RichMedia.Impressiontrackers { - impressionTracker.WriteString(fmt.Sprintf(``, impression)) - } - - richmediaAdMarkup := fmt.Sprintf(`
%s%s
`, - &clickEvent, richMediaAd.RichMedia.MediaData.Content, &impressionTracker) - - return richmediaAdMarkup, nil -} diff --git a/adapters/smaato/richmedia_test.go b/adapters/smaato/richmedia_test.go deleted file mode 100644 index eff559852be..00000000000 --- a/adapters/smaato/richmedia_test.go +++ /dev/null @@ -1,48 +0,0 @@ -package smaato - -import ( - "github.com/stretchr/testify/assert" - "testing" -) - -func TestExtractAdmRichMedia(t *testing.T) { - tests := []struct { - testName string - adMarkup string - expectedAdMarkup string - expectedError string - }{ - { - testName: "extract richmedia", - adMarkup: "{\"richmedia\":{\"mediadata\":{\"content\":\"
hello
\"," + - "" + "\"w\":350," + - "\"h\":50},\"impressiontrackers\":[\"//prebid-test.smaatolabs.net/track/imp/1\",\"//prebid-test.smaatolabs.net/track/imp/2\"]," + - "\"clicktrackers\":[\"//prebid-test.smaatolabs.net/track/click/1\",\"//prebid-test.smaatolabs.net/track/click/2\"]}}", - expectedAdMarkup: `
hello
` + - `
`, - expectedError: "", - }, - { - testName: "invalid adMarkup", - adMarkup: "{", - expectedAdMarkup: "", - expectedError: "Invalid ad markup {.", - }, - } - - for _, tt := range tests { - t.Run(tt.testName, func(t *testing.T) { - adMarkup, err := extractAdmRichMedia(tt.adMarkup) - - if tt.expectedError != "" { - assert.EqualError(t, err, tt.expectedError) - } else { - assert.NoError(t, err) - } - - assert.Equal(t, tt.expectedAdMarkup, adMarkup) - }) - } -} diff --git a/adapters/smaato/smaato.go b/adapters/smaato/smaato.go index 7dcf4446702..3a349204004 100644 --- a/adapters/smaato/smaato.go +++ b/adapters/smaato/smaato.go @@ -9,15 +9,16 @@ import ( "github.com/buger/jsonparser" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/metrics" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/timeutil" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/metrics" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/timeutil" ) -const clientVersion = "prebid_server_0.7" +const clientVersion = "prebid_server_1.1" type adMarkupType string @@ -57,7 +58,8 @@ type bidRequestExt struct { // bidExt defines Bid.Ext object for Smaato type bidExt struct { - Duration int `json:"duration"` + Duration int `json:"duration"` + Curls []string `json:"curls"` } // videoExt defines Video.Ext object for Smaato @@ -107,24 +109,29 @@ func (adapter *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalR } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } bidResponse := adapters.NewBidderResponseWithBidsCapacity(5) + adMarkupType, err := getAdMarkupType(response) + if err != nil { + return nil, []error{err} + } + var errors []error for _, seatBid := range bidResp.SeatBid { for i := 0; i < len(seatBid.Bid); i++ { bid := seatBid.Bid[i] - adMarkupType, err := getAdMarkupType(response, bid.AdM) + bidExt, err := extractBidExt(&bid) if err != nil { errors = append(errors, err) continue } - bid.AdM, err = renderAdMarkup(adMarkupType, bid.AdM) + bid.AdM, err = renderAdMarkup(adMarkupType, &bidExt, bid) if err != nil { errors = append(errors, err) continue @@ -136,7 +143,7 @@ func (adapter *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalR continue } - bidVideo, err := buildBidVideo(&bid, bidType) + bidVideo, err := buildBidVideo(&bid, &bidExt, bidType) if err != nil { errors = append(errors, err) continue @@ -260,20 +267,12 @@ func (adapter *adapter) makeRequest(request *openrtb2.BidRequest) (*adapters.Req }, nil } -func getAdMarkupType(response *adapters.ResponseData, adMarkup string) (adMarkupType, error) { +func getAdMarkupType(response *adapters.ResponseData) (adMarkupType, error) { if admType := adMarkupType(response.Headers.Get("X-Smt-Adtype")); admType != "" { return admType, nil - } else if strings.HasPrefix(adMarkup, `{"image":`) { - return smtAdTypeImg, nil - } else if strings.HasPrefix(adMarkup, `{"richmedia":`) { - return smtAdTypeRichmedia, nil - } else if strings.HasPrefix(adMarkup, `\"\"", "adomain": [ "smaato.com" ], @@ -347,13 +350,16 @@ "keywords": "power tools" }, "ext": { - "client": "prebid_server_0.7" + "client": "prebid_server_1.1" } }, "impIDs":["postbid_iframe"] }, "mockResponse": { "status": 200, + "headers": { + "X-Smt-Adtype": ["Video"] + }, "body": { "id": "5ebea288-f13a-4754-be6d-4ade66c68877", "seatbid": [ @@ -415,7 +421,7 @@ "bids": [ { "bid": { - "adm": "
\"\"\"\"
", + "adm": "\"\"", "adomain": [ "smaato.com" ], diff --git a/adapters/smaato/smaatotest/exemplary/multiple-impressions.json b/adapters/smaato/smaatotest/exemplary/multiple-impressions.json index e0055602be9..3fee0d654c3 100644 --- a/adapters/smaato/smaatotest/exemplary/multiple-impressions.json +++ b/adapters/smaato/smaatotest/exemplary/multiple-impressions.json @@ -160,13 +160,16 @@ "keywords": "power tools" }, "ext": { - "client": "prebid_server_0.7" + "client": "prebid_server_1.1" } }, "impIDs":["1C86242D-9535-47D6-9576-7B1FE87F282C"] }, "mockResponse": { "status": 200, + "headers": { + "X-Smt-Adtype": ["Img"] + }, "body": { "id": "5ebea288-f13a-4754-be6d-4ade66c68877", "seatbid": [ @@ -174,7 +177,7 @@ "seat": "CM6523", "bid": [ { - "adm": "{\"image\":{\"img\":{\"url\":\"//prebid-test.smaatolabs.net/img/320x50.jpg\",\"w\":350,\"h\":50,\"ctaurl\":\"//prebid-test.smaatolabs.net/track/ctaurl/1\"},\"impressiontrackers\":[\"//prebid-test.smaatolabs.net/track/imp/1\",\"//prebid-test.smaatolabs.net/track/imp/2\"],\"clicktrackers\":[\"//prebid-test.smaatolabs.net/track/click/1\",\"//prebid-test.smaatolabs.net/track/click/2\"]}}", + "adm": "\"\"", "adomain": [ "smaato.com" ], @@ -267,13 +270,16 @@ "keywords": "power tools" }, "ext": { - "client": "prebid_server_0.7" + "client": "prebid_server_1.1" } }, "impIDs":["postbid_iframe"] }, "mockResponse": { "status": 200, + "headers": { + "X-Smt-Adtype": ["Video"] + }, "body": { "id": "5ebea288-f13a-4754-be6d-4ade66c68877", "seatbid": [ @@ -311,7 +317,7 @@ "bids": [ { "bid": { - "adm": "
\"\"\"\"
", + "adm": "\"\"", "adomain": [ "smaato.com" ], diff --git a/adapters/smaato/smaatotest/exemplary/multiple-media-types-skadn.json b/adapters/smaato/smaatotest/exemplary/multiple-media-types-skadn.json index 61de48ea4a8..c2b7bf97869 100644 --- a/adapters/smaato/smaatotest/exemplary/multiple-media-types-skadn.json +++ b/adapters/smaato/smaatotest/exemplary/multiple-media-types-skadn.json @@ -178,13 +178,16 @@ "keywords": "power tools" }, "ext": { - "client": "prebid_server_0.7" + "client": "prebid_server_1.1" } }, "impIDs":["1C86242D-9535-47D6-9576-7B1FE87F282C"] }, "mockResponse": { "status": 200, + "headers": { + "X-Smt-Adtype": ["Img"] + }, "body": { "id": "5ebea288-f13a-4754-be6d-4ade66c68877", "seatbid": [ @@ -192,7 +195,7 @@ "seat": "CM6523", "bid": [ { - "adm": "{\"image\":{\"img\":{\"url\":\"//prebid-test.smaatolabs.net/img/320x50.jpg\",\"w\":350,\"h\":50,\"ctaurl\":\"//prebid-test.smaatolabs.net/track/ctaurl/1\"},\"impressiontrackers\":[\"//prebid-test.smaatolabs.net/track/imp/1\",\"//prebid-test.smaatolabs.net/track/imp/2\"],\"clicktrackers\":[\"//prebid-test.smaatolabs.net/track/click/1\",\"//prebid-test.smaatolabs.net/track/click/2\"]}}", + "adm": "\"\"", "adomain": [ "smaato.com" ], @@ -324,13 +327,16 @@ "keywords": "power tools" }, "ext": { - "client": "prebid_server_0.7" + "client": "prebid_server_1.1" } }, "impIDs":["1C86242D-9535-47D6-9576-7B1FE87F282C"] }, "mockResponse": { "status": 200, + "headers": { + "X-Smt-Adtype": ["Video"] + }, "body": { "id": "5ebea288-f13a-4754-be6d-4ade66c68877", "seatbid": [ @@ -392,7 +398,7 @@ "bids": [ { "bid": { - "adm": "
\"\"\"\"
", + "adm": "\"\"", "adomain": [ "smaato.com" ], diff --git a/adapters/smaato/smaatotest/exemplary/multiple-media-types.json b/adapters/smaato/smaatotest/exemplary/multiple-media-types.json index 3d579060f90..4c6f031016a 100644 --- a/adapters/smaato/smaatotest/exemplary/multiple-media-types.json +++ b/adapters/smaato/smaatotest/exemplary/multiple-media-types.json @@ -150,13 +150,16 @@ "keywords": "power tools" }, "ext": { - "client": "prebid_server_0.7" + "client": "prebid_server_1.1" } }, "impIDs":["1C86242D-9535-47D6-9576-7B1FE87F282C"] }, "mockResponse": { "status": 200, + "headers": { + "X-Smt-Adtype": ["Img"] + }, "body": { "id": "5ebea288-f13a-4754-be6d-4ade66c68877", "seatbid": [ @@ -164,7 +167,7 @@ "seat": "CM6523", "bid": [ { - "adm": "{\"image\":{\"img\":{\"url\":\"//prebid-test.smaatolabs.net/img/320x50.jpg\",\"w\":350,\"h\":50,\"ctaurl\":\"//prebid-test.smaatolabs.net/track/ctaurl/1\"},\"impressiontrackers\":[\"//prebid-test.smaatolabs.net/track/imp/1\",\"//prebid-test.smaatolabs.net/track/imp/2\"],\"clicktrackers\":[\"//prebid-test.smaatolabs.net/track/click/1\",\"//prebid-test.smaatolabs.net/track/click/2\"]}}", + "adm": "\"\"", "adomain": [ "smaato.com" ], @@ -257,13 +260,16 @@ "keywords": "power tools" }, "ext": { - "client": "prebid_server_0.7" + "client": "prebid_server_1.1" } }, "impIDs":["1C86242D-9535-47D6-9576-7B1FE87F282C"] }, "mockResponse": { "status": 200, + "headers": { + "X-Smt-Adtype": ["Video"] + }, "body": { "id": "5ebea288-f13a-4754-be6d-4ade66c68877", "seatbid": [ @@ -301,7 +307,7 @@ "bids": [ { "bid": { - "adm": "
\"\"\"\"
", + "adm": "\"\"", "adomain": [ "smaato.com" ], diff --git a/adapters/smaato/smaatotest/exemplary/native.json b/adapters/smaato/smaatotest/exemplary/native.json index 46d2af28cf8..f229220180e 100644 --- a/adapters/smaato/smaatotest/exemplary/native.json +++ b/adapters/smaato/smaatotest/exemplary/native.json @@ -41,7 +41,18 @@ "gdpr": 1, "us_privacy": "uspConsentString", "gpp": "gppString", - "gpp_sid": [7] + "gpp_sid": [7], + "dsa": { + "dsarequired": 1, + "pubrender": 1, + "datatopub": 1, + "transparency": [ + { + "domain": "testdomain.com", + "dsaparams": [1,3] + } + ] + } } }, "ext": { @@ -98,17 +109,31 @@ "gdpr": 1, "us_privacy": "uspConsentString", "gpp": "gppString", - "gpp_sid": [7] + "gpp_sid": [7], + "dsa": { + "dsarequired": 1, + "pubrender": 1, + "datatopub": 1, + "transparency": [ + { + "domain": "testdomain.com", + "dsaparams": [1,3] + } + ] + } } }, "ext": { - "client": "prebid_server_0.7" + "client": "prebid_server_1.1" } }, "impIDs":["postbid_iframe"] }, "mockResponse": { "status": 200, + "headers": { + "X-Smt-Adtype": ["Native"] + }, "body": { "id": "5ebea288-f13a-4754-be6d-4ade66c68877", "seatbid": [ @@ -129,7 +154,20 @@ "nurl": "https://nurl", "price": 0.01, "w": 480, - "h": 320 + "h": 320, + "ext": { + "dsa": { + "behalf": "Advertiser", + "paid": "Advertiser", + "adrender": 1, + "transparency": [ + { + "domain": "dsp1domain.com", + "dsaparams": [1,3] + } + ] + } + } } ] } @@ -159,7 +197,20 @@ "price": 0.01, "w": 480, "h": 320, - "exp": 300 + "exp": 300, + "ext": { + "dsa": { + "behalf": "Advertiser", + "paid": "Advertiser", + "adrender": 1, + "transparency": [ + { + "domain": "dsp1domain.com", + "dsaparams": [1,3] + } + ] + } + } }, "type": "native" } diff --git a/adapters/smaato/smaatotest/exemplary/simple-banner-app.json b/adapters/smaato/smaatotest/exemplary/simple-banner-app.json index 4f24bb00a9f..d2c5f5453ed 100644 --- a/adapters/smaato/smaatotest/exemplary/simple-banner-app.json +++ b/adapters/smaato/smaatotest/exemplary/simple-banner-app.json @@ -158,13 +158,16 @@ "keywords": "keywords" }, "ext": { - "client": "prebid_server_0.7" + "client": "prebid_server_1.1" } }, "impIDs":["1C86242D-9535-47D6-9576-7B1FE87F282C"] }, "mockResponse": { "status": 200, + "headers": { + "X-Smt-Adtype": ["Img"] + }, "body": { "id": "5ebea288-f13a-4754-be6d-4ade66c68877", "seatbid": [ @@ -172,7 +175,7 @@ "seat": "CM6523", "bid": [ { - "adm": "{\"image\":{\"img\":{\"url\":\"//prebid-test.smaatolabs.net/img/320x50.jpg\",\"w\":350,\"h\":50,\"ctaurl\":\"//prebid-test.smaatolabs.net/track/ctaurl/1\"},\"impressiontrackers\":[\"//prebid-test.smaatolabs.net/track/imp/1\",\"//prebid-test.smaatolabs.net/track/imp/2\"],\"clicktrackers\":[\"//prebid-test.smaatolabs.net/track/click/1\",\"//prebid-test.smaatolabs.net/track/click/2\"]}}", + "adm": "\"\"", "adomain": [ "smaato.com" ], @@ -202,7 +205,7 @@ "bids": [ { "bid": { - "adm": "
\"\"\"\"
", + "adm": "\"\"", "adomain": [ "smaato.com" ], diff --git a/adapters/smaato/smaatotest/exemplary/simple-banner-richMedia-app.json b/adapters/smaato/smaatotest/exemplary/simple-banner-dooh.json similarity index 79% rename from adapters/smaato/smaatotest/exemplary/simple-banner-richMedia-app.json rename to adapters/smaato/smaatotest/exemplary/simple-banner-dooh.json index 30594685c14..d5fd7ef1f05 100644 --- a/adapters/smaato/smaatotest/exemplary/simple-banner-richMedia-app.json +++ b/adapters/smaato/smaatotest/exemplary/simple-banner-dooh.json @@ -1,16 +1,11 @@ { "mockBidRequest": { "id": "1C86242D-9535-47D6-9576-7B1FE87F282C", - "app": { - "id": "app-id", - "name": "app-name", - "bundle": "app-bundle", - "storeurl": "app-storeurl", - "cat": [ - "IAB3-1" - ], - "ver": "app-version", - "paid": 1, + "dooh": { + "id": "id", + "name": "name", + "domain": "domain", + "venuetypetax": 1, "content": { "id": "content-id", "title": "content-title", @@ -21,8 +16,8 @@ "name": "producer-name" }, "cat": [ - "IAB8-6" - ], + "IAB8-6" + ], "livestream": 1, "language": "en" }, @@ -82,12 +77,8 @@ { "expectedRequest": { "headers": { - "Content-Type": [ - "application/json;charset=utf-8" - ], - "Accept": [ - "application/json" - ] + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"] }, "uri": "https://prebid/bidder", "body": { @@ -111,12 +102,12 @@ } ], "user": { - "gender": "M", - "keywords": "a,b", - "yob": 1984, "ext": { "consent": "gdprConsentString" - } + }, + "gender": "M", + "keywords": "a,b", + "yob": 1984 }, "device": { "ua": "test-user-agent", @@ -131,19 +122,14 @@ "us_privacy": "uspConsentString" } }, - "app": { + "dooh": { "publisher": { "id": "1100042525" }, - "id": "app-id", - "name": "app-name", - "bundle": "app-bundle", - "storeurl": "app-storeurl", - "cat": [ - "IAB3-1" - ], - "ver": "app-version", - "paid": 1, + "id": "id", + "name": "name", + "domain": "domain", + "venuetypetax": 1, "content": { "id": "content-id", "title": "content-title", @@ -162,13 +148,16 @@ "keywords": "keywords" }, "ext": { - "client": "prebid_server_0.7" + "client": "prebid_server_1.1" } }, "impIDs":["1C86242D-9535-47D6-9576-7B1FE87F282C"] }, "mockResponse": { "status": 200, + "headers": { + "X-Smt-Adtype": ["Img"] + }, "body": { "id": "5ebea288-f13a-4754-be6d-4ade66c68877", "seatbid": [ @@ -176,7 +165,7 @@ "seat": "CM6523", "bid": [ { - "adm": "{\"richmedia\":{\"mediadata\":{\"content\":\"
hello
\", \"w\":350,\"h\":50},\"impressiontrackers\":[\"//prebid-test.smaatolabs.net/track/imp/1\",\"//prebid-test.smaatolabs.net/track/imp/2\"],\"clicktrackers\":[\"//prebid-test.smaatolabs.net/track/click/1\",\"//prebid-test.smaatolabs.net/track/click/2\"]}}", + "adm": "\"\"", "adomain": [ "smaato.com" ], @@ -206,7 +195,7 @@ "bids": [ { "bid": { - "adm": "
hello
\"\"\"\"
", + "adm": "\"\"", "adomain": [ "smaato.com" ], diff --git a/adapters/smaato/smaatotest/exemplary/simple-banner-eids.json b/adapters/smaato/smaatotest/exemplary/simple-banner-eids.json index b9316341a65..ed0b61dcefa 100644 --- a/adapters/smaato/smaatotest/exemplary/simple-banner-eids.json +++ b/adapters/smaato/smaatotest/exemplary/simple-banner-eids.json @@ -153,13 +153,16 @@ "keywords": "power tools" }, "ext": { - "client": "prebid_server_0.7" + "client": "prebid_server_1.1" } }, "impIDs":["1C86242D-9535-47D6-9576-7B1FE87F282C"] }, "mockResponse": { "status": 200, + "headers": { + "X-Smt-Adtype": ["Img"] + }, "body": { "id": "5ebea288-f13a-4754-be6d-4ade66c68877", "seatbid": [ @@ -167,7 +170,7 @@ "seat": "CM6523", "bid": [ { - "adm": "{\"image\":{\"img\":{\"url\":\"//prebid-test.smaatolabs.net/img/320x50.jpg\",\"w\":350,\"h\":50,\"ctaurl\":\"//prebid-test.smaatolabs.net/track/ctaurl/1\"},\"impressiontrackers\":[\"//prebid-test.smaatolabs.net/track/imp/1\",\"//prebid-test.smaatolabs.net/track/imp/2\"],\"clicktrackers\":[\"//prebid-test.smaatolabs.net/track/click/1\",\"//prebid-test.smaatolabs.net/track/click/2\"]}}", + "adm": "\"\"", "adomain": [ "smaato.com" ], @@ -197,7 +200,7 @@ "bids": [ { "bid": { - "adm": "
\"\"\"\"
", + "adm": "\"\"", "adomain": [ "smaato.com" ], diff --git a/adapters/smaato/smaatotest/exemplary/simple-banner-skadn.json b/adapters/smaato/smaatotest/exemplary/simple-banner-skadn.json index 2b0e8e2fe48..cab205f7334 100644 --- a/adapters/smaato/smaatotest/exemplary/simple-banner-skadn.json +++ b/adapters/smaato/smaatotest/exemplary/simple-banner-skadn.json @@ -167,13 +167,16 @@ "keywords": "power tools" }, "ext": { - "client": "prebid_server_0.7" + "client": "prebid_server_1.1" } }, "impIDs":["1C86242D-9535-47D6-9576-7B1FE87F282C"] }, "mockResponse": { "status": 200, + "headers": { + "X-Smt-Adtype": ["Img"] + }, "body": { "id": "5ebea288-f13a-4754-be6d-4ade66c68877", "seatbid": [ @@ -181,7 +184,7 @@ "seat": "CM6523", "bid": [ { - "adm": "{\"image\":{\"img\":{\"url\":\"//prebid-test.smaatolabs.net/img/320x50.jpg\",\"w\":350,\"h\":50,\"ctaurl\":\"//prebid-test.smaatolabs.net/track/ctaurl/1\"},\"impressiontrackers\":[\"//prebid-test.smaatolabs.net/track/imp/1\",\"//prebid-test.smaatolabs.net/track/imp/2\"],\"clicktrackers\":[\"//prebid-test.smaatolabs.net/track/click/1\",\"//prebid-test.smaatolabs.net/track/click/2\"]}}", + "adm": "\"\"", "adomain": [ "smaato.com" ], @@ -235,7 +238,7 @@ "bids": [ { "bid": { - "adm": "
\"\"\"\"
", + "adm": "\"\"", "adomain": [ "smaato.com" ], diff --git a/adapters/smaato/smaatotest/exemplary/simple-banner.json b/adapters/smaato/smaatotest/exemplary/simple-banner.json index 00dce8f3b17..48ee26ebddc 100644 --- a/adapters/smaato/smaatotest/exemplary/simple-banner.json +++ b/adapters/smaato/smaatotest/exemplary/simple-banner.json @@ -66,7 +66,18 @@ "gdpr": 1, "us_privacy": "uspConsentString", "gpp": "gppString", - "gpp_sid": [7] + "gpp_sid": [7], + "dsa": { + "dsarequired": 1, + "pubrender": 1, + "datatopub": 1, + "transparency": [ + { + "domain": "testdomain.com", + "dsaparams": [1,3] + } + ] + } } } }, @@ -120,7 +131,18 @@ "gdpr": 1, "us_privacy": "uspConsentString", "gpp": "gppString", - "gpp_sid": [7] + "gpp_sid": [7], + "dsa": { + "dsarequired": 1, + "pubrender": 1, + "datatopub": 1, + "transparency": [ + { + "domain": "testdomain.com", + "dsaparams": [1,3] + } + ] + } } }, "site": { @@ -131,13 +153,16 @@ "keywords": "power tools" }, "ext": { - "client": "prebid_server_0.7" + "client": "prebid_server_1.1" } }, "impIDs":["1C86242D-9535-47D6-9576-7B1FE87F282C"] }, "mockResponse": { "status": 200, + "headers": { + "X-Smt-Adtype": ["Img"] + }, "body": { "id": "5ebea288-f13a-4754-be6d-4ade66c68877", "seatbid": [ @@ -145,7 +170,7 @@ "seat": "CM6523", "bid": [ { - "adm": "{\"image\":{\"img\":{\"url\":\"//prebid-test.smaatolabs.net/img/320x50.jpg\",\"w\":350,\"h\":50,\"ctaurl\":\"//prebid-test.smaatolabs.net/track/ctaurl/1\"},\"impressiontrackers\":[\"//prebid-test.smaatolabs.net/track/imp/1\",\"//prebid-test.smaatolabs.net/track/imp/2\"],\"clicktrackers\":[\"//prebid-test.smaatolabs.net/track/click/1\",\"//prebid-test.smaatolabs.net/track/click/2\"]}}", + "adm": "\"\"", "adomain": [ "smaato.com" ], @@ -158,7 +183,23 @@ "nurl": "https://ets-eu-west-1.track.smaato.net/v1/view?sessionId=e4e17adb-9599-42b1-bb5f-a1f1b3bee572&adSourceId=6906aae8-7f74-4edd-9a4f-f49379a3cadd&originalRequestTime=1552310449698&expires=1552311350698&winurl=ama8JbpJVpFWxvEja5viE3cLXFu58qRI8dGUh23xtsOn3N2-5UU0IwkgNEmR82pI37fcMXejL5IWTNAoW6Cnsjf-Dxl_vx2dUqMrVEevX-Vdx2VVnf-D5f73gZhvi4t36iPL8Dsw4aACekoLvVOV7-eXDjz7GHy60QFqcwKf5g2AlKPOInyZ6vJg_fn4qA9argvCRgwVybXE9Ndm2W0v8La4uFYWpJBOUveDDUrSQfzal7RsYvLb_OyaMlPHdrd_bwA9qqZWuyJXd-L9lxr7RQ%3D%3D%7CMw3kt91KJR0Uy5L-oNztAg%3D%3D&dpid=4XVofb_lH-__hr2JNGhKfg%3D%3D%7Cr9ciCU1cx3zmHXihItKO0g%3D%3D", "price": 0.01, "w": 350, - "h": 50 + "h": 50, + "ext": { + "curls": [ + "https://track.net/v1/click" + ], + "dsa": { + "behalf": "Advertiser", + "paid": "Advertiser", + "adrender": 1, + "transparency": [ + { + "domain": "dsp1domain.com", + "dsaparams": [1,3] + } + ] + } + } } ] } @@ -175,7 +216,7 @@ "bids": [ { "bid": { - "adm": "
\"\"\"\"
", + "adm": "
\"\"
", "adomain": [ "smaato.com" ], @@ -188,7 +229,23 @@ "price": 0.01, "w": 350, "h": 50, - "exp": 300 + "exp": 300, + "ext": { + "curls": [ + "https://track.net/v1/click" + ], + "dsa": { + "behalf": "Advertiser", + "paid": "Advertiser", + "adrender": 1, + "transparency": [ + { + "domain": "dsp1domain.com", + "dsaparams": [1,3] + } + ] + } + } }, "type": "banner" } diff --git a/adapters/smaato/smaatotest/exemplary/video-app.json b/adapters/smaato/smaatotest/exemplary/video-app.json index e2ffafae2bb..cd074530838 100644 --- a/adapters/smaato/smaatotest/exemplary/video-app.json +++ b/adapters/smaato/smaatotest/exemplary/video-app.json @@ -165,13 +165,16 @@ "keywords": "keywords" }, "ext": { - "client": "prebid_server_0.7" + "client": "prebid_server_1.1" } }, "impIDs":["postbid_iframe"] }, "mockResponse": { "status": 200, + "headers": { + "X-Smt-Adtype": ["Video"] + }, "body": { "id": "5ebea288-f13a-4754-be6d-4ade66c68877", "seatbid": [ diff --git a/adapters/smaato/smaatotest/exemplary/video-dooh.json b/adapters/smaato/smaatotest/exemplary/video-dooh.json new file mode 100644 index 00000000000..98d30df7774 --- /dev/null +++ b/adapters/smaato/smaatotest/exemplary/video-dooh.json @@ -0,0 +1,225 @@ +{ + "mockBidRequest": { + "id": "447a0a1d-389d-4730-a418-3777e95de7bd", + "imp": [ + { + "id": "postbid_iframe", + "video": { + "mimes": [ + "video/mp4", + "video/quicktime", + "video/3gpp", + "video/x-m4v" + ], + "minduration": 5, + "maxduration": 30, + "protocols": [ + 7 + ], + "w": 1024, + "h": 768, + "startdelay": 0, + "linearity": 1, + "skip": 1, + "skipmin": 5, + "api": [ + 7 + ], + "ext": { + "rewarded": 0 + } + }, + "ext": { + "bidder": { + "publisherId": "1100042525", + "adspaceId": "130563103" + } + } + } + ], + "dooh": { + "id": "id", + "name": "name", + "domain": "domain", + "venuetypetax": 1, + "content": { + "id": "content-id", + "title": "content-title", + "series": "content-series", + "genre": "content-genre", + "producer": { + "id": "producer-id", + "name": "producer-name" + }, + "cat": [ + "IAB8-6" + ], + "livestream": 1, + "language": "en" + }, + "keywords": "keywords" + }, + "device": { + "ua": "test-user-agent" + }, + "user": { + "ext": { + "data": {} + } + }, + "ext": { + "prebid": { + "auctiontimestamp": 1598262728811, + "targeting": { + "includewinners": true, + "includebidderkeys": false + } + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ] + }, + "uri": "https://prebid/bidder", + "body": { + "id": "447a0a1d-389d-4730-a418-3777e95de7bd", + "imp": [ + { + "id": "postbid_iframe", + "tagid": "130563103", + "video": { + "w": 1024, + "h": 768, + "ext": { + "rewarded": 0 + }, + "mimes": [ + "video/mp4", + "video/quicktime", + "video/3gpp", + "video/x-m4v" + ], + "minduration": 5, + "startdelay": 0, + "linearity": 1, + "maxduration": 30, + "skip": 1, + "protocols": [ + 7 + ], + "skipmin": 5, + "api": [ + 7 + ] + } + } + ], + "user": { + "ext": { + } + }, + "device": { + "ua": "test-user-agent" + }, + "dooh": { + "publisher": { + "id": "1100042525" + }, + "id": "id", + "name": "name", + "domain": "domain", + "venuetypetax": 1, + "content": { + "id": "content-id", + "title": "content-title", + "series": "content-series", + "genre": "content-genre", + "producer": { + "id": "producer-id", + "name": "producer-name" + }, + "cat": [ + "IAB8-6" + ], + "livestream": 1, + "language": "en" + }, + "keywords": "keywords" + }, + "ext": { + "client": "prebid_server_1.1" + } + }, + "impIDs":["postbid_iframe"] + }, + "mockResponse": { + "status": 200, + "headers": { + "X-Smt-Adtype": ["Video"] + }, + "body": { + "id": "5ebea288-f13a-4754-be6d-4ade66c68877", + "seatbid": [ + { + "seat": "CM6523", + "bid": [ + { + "adm": "", + "adomain": [ + "smaato.com" + ], + "bidderName": "smaato", + "cid": "CM6523", + "crid": "CR69381", + "id": "6906aae8-7f74-4edd-9a4f-f49379a3cadd", + "impid": "1C86242D-9535-47D6-9576-7B1FE87F282C", + "iurl": "https://iurl", + "nurl": "https://nurl", + "price": 0.01, + "w": 1024, + "h": 768 + } + ] + } + ], + "bidid": "04db8629-179d-4bcd-acce-e54722969006", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "adm": "", + "adomain": [ + "smaato.com" + ], + "cid": "CM6523", + "crid": "CR69381", + "id": "6906aae8-7f74-4edd-9a4f-f49379a3cadd", + "impid": "1C86242D-9535-47D6-9576-7B1FE87F282C", + "iurl": "https://iurl", + "nurl": "https://nurl", + "price": 0.01, + "w": 1024, + "h": 768, + "exp": 300 + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/smaato/smaatotest/exemplary/video.json b/adapters/smaato/smaatotest/exemplary/video.json index 54ef43bf12a..2207c53cf53 100644 --- a/adapters/smaato/smaatotest/exemplary/video.json +++ b/adapters/smaato/smaatotest/exemplary/video.json @@ -69,7 +69,18 @@ "gdpr": 1, "us_privacy": "uspConsentString", "gpp": "gppString", - "gpp_sid": [7] + "gpp_sid": [7], + "dsa": { + "dsarequired": 1, + "pubrender": 1, + "datatopub": 1, + "transparency": [ + { + "domain": "testdomain.com", + "dsaparams": [1,3] + } + ] + } } }, "ext": { @@ -146,7 +157,18 @@ "gdpr": 1, "us_privacy": "uspConsentString", "gpp": "gppString", - "gpp_sid": [7] + "gpp_sid": [7], + "dsa": { + "dsarequired": 1, + "pubrender": 1, + "datatopub": 1, + "transparency": [ + { + "domain": "testdomain.com", + "dsaparams": [1,3] + } + ] + } } }, "device": { @@ -158,13 +180,16 @@ } }, "ext": { - "client": "prebid_server_0.7" + "client": "prebid_server_1.1" } }, "impIDs":["postbid_iframe"] }, "mockResponse": { "status": 200, + "headers": { + "X-Smt-Adtype": ["Video"] + }, "body": { "id": "5ebea288-f13a-4754-be6d-4ade66c68877", "seatbid": [ @@ -185,7 +210,20 @@ "nurl": "https://nurl", "price": 0.01, "w": 1024, - "h": 768 + "h": 768, + "ext": { + "dsa": { + "behalf": "Advertiser", + "paid": "Advertiser", + "adrender": 1, + "transparency": [ + { + "domain": "dsp1domain.com", + "dsaparams": [1,3] + } + ] + } + } } ] } @@ -215,7 +253,20 @@ "price": 0.01, "w": 1024, "h": 768, - "exp": 300 + "exp": 300, + "ext": { + "dsa": { + "behalf": "Advertiser", + "paid": "Advertiser", + "adrender": 1, + "transparency": [ + { + "domain": "dsp1domain.com", + "dsaparams": [1,3] + } + ] + } + } }, "type": "video" } diff --git a/adapters/smaato/smaatotest/supplemental/adtype-header-response.json b/adapters/smaato/smaatotest/supplemental/adtype-header-response.json deleted file mode 100644 index bf33878e911..00000000000 --- a/adapters/smaato/smaatotest/supplemental/adtype-header-response.json +++ /dev/null @@ -1,193 +0,0 @@ -{ - "mockBidRequest": { - "id": "1C86242D-9535-47D6-9576-7B1FE87F282C", - "site": { - "publisher": { - "id": "1100042525" - }, - "page": "http://localhost:3000/server.html?pbjs_debug=true&endpoint=http://localhost:3000/bidder", - "ext": { - "data": { - "keywords": "power tools", - "search": "drill", - "content": { - "userrating": 4 - } - } - } - }, - "imp": [ - { - "id": "1C86242D-9535-47D6-9576-7B1FE87F282C", - "banner": { - "format": [ - { - "w": 320, - "h": 50 - }, - { - "w": 320, - "h": 250 - } - ] - }, - "ext": { - "bidder": { - "publisherId": "1100042525", - "adspaceId": "130563103" - } - } - } - ], - "device": { - "ua": "test-user-agent", - "ip": "123.123.123.123", - "language": "en", - "dnt": 0 - }, - "user": { - "ext": { - "consent": "gdprConsentString", - "data": { - "keywords": "a,b", - "gender": "M", - "yob": 1984, - "geo": { - "country": "ca" - } - } - } - }, - "regs": { - "coppa": 1, - "ext": { - "gdpr": 1, - "us_privacy": "uspConsentString" - } - } - }, - "httpCalls": [ - { - "expectedRequest": { - "headers": { - "Content-Type": ["application/json;charset=utf-8"], - "Accept": ["application/json"] - }, - "uri": "https://prebid/bidder", - "body": { - "id": "1C86242D-9535-47D6-9576-7B1FE87F282C", - "imp": [ - { - "id": "1C86242D-9535-47D6-9576-7B1FE87F282C", - "tagid": "130563103", - "banner": { - "format": [ - { - "w": 320, - "h": 50 - }, - { - "w": 320, - "h": 250 - } - ] - } - } - ], - "user": { - "ext": { - "consent": "gdprConsentString" - }, - "gender": "M", - "keywords": "a,b", - "yob": 1984 - }, - "device": { - "ua": "test-user-agent", - "ip": "123.123.123.123", - "language": "en", - "dnt": 0 - }, - "regs": { - "coppa": 1, - "ext": { - "gdpr": 1, - "us_privacy": "uspConsentString" - } - }, - "site": { - "publisher": { - "id": "1100042525" - }, - "page": "http://localhost:3000/server.html?pbjs_debug=true&endpoint=http://localhost:3000/bidder", - "keywords": "power tools" - }, - "ext": { - "client": "prebid_server_0.7" - } - }, - "impIDs":["1C86242D-9535-47D6-9576-7B1FE87F282C"] - }, - "mockResponse": { - "status": 200, - "headers": { - "X-Smt-Adtype": ["Img"] - }, - "body": { - "id": "5ebea288-f13a-4754-be6d-4ade66c68877", - "seatbid": [ - { - "seat": "CM6523", - "bid": [ - { - "adm": "{\"image\":{\"img\":{\"url\":\"//prebid-test.smaatolabs.net/img/320x50.jpg\",\"w\":350,\"h\":50,\"ctaurl\":\"//prebid-test.smaatolabs.net/track/ctaurl/1\"},\"impressiontrackers\":[\"//prebid-test.smaatolabs.net/track/imp/1\",\"//prebid-test.smaatolabs.net/track/imp/2\"],\"clicktrackers\":[\"//prebid-test.smaatolabs.net/track/click/1\",\"//prebid-test.smaatolabs.net/track/click/2\"]}}", - "adomain": [ - "smaato.com" - ], - "bidderName": "smaato", - "cid": "CM6523", - "crid": "CR69381", - "id": "6906aae8-7f74-4edd-9a4f-f49379a3cadd", - "impid": "1C86242D-9535-47D6-9576-7B1FE87F282C", - "iurl": "https://bidstalkcreatives.s3.amazonaws.com/1x1.png", - "nurl": "https://ets-eu-west-1.track.smaato.net/v1/view?sessionId=e4e17adb-9599-42b1-bb5f-a1f1b3bee572&adSourceId=6906aae8-7f74-4edd-9a4f-f49379a3cadd&originalRequestTime=1552310449698&expires=1552311350698&winurl=ama8JbpJVpFWxvEja5viE3cLXFu58qRI8dGUh23xtsOn3N2-5UU0IwkgNEmR82pI37fcMXejL5IWTNAoW6Cnsjf-Dxl_vx2dUqMrVEevX-Vdx2VVnf-D5f73gZhvi4t36iPL8Dsw4aACekoLvVOV7-eXDjz7GHy60QFqcwKf5g2AlKPOInyZ6vJg_fn4qA9argvCRgwVybXE9Ndm2W0v8La4uFYWpJBOUveDDUrSQfzal7RsYvLb_OyaMlPHdrd_bwA9qqZWuyJXd-L9lxr7RQ%3D%3D%7CMw3kt91KJR0Uy5L-oNztAg%3D%3D&dpid=4XVofb_lH-__hr2JNGhKfg%3D%3D%7Cr9ciCU1cx3zmHXihItKO0g%3D%3D", - "price": 0.01, - "w": 350, - "h": 50 - } - ] - } - ], - "bidid": "04db8629-179d-4bcd-acce-e54722969006", - "cur": "USD" - } - } - } - ], - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "adm": "
\"\"\"\"
", - "adomain": [ - "smaato.com" - ], - "cid": "CM6523", - "crid": "CR69381", - "id": "6906aae8-7f74-4edd-9a4f-f49379a3cadd", - "impid": "1C86242D-9535-47D6-9576-7B1FE87F282C", - "iurl": "https://bidstalkcreatives.s3.amazonaws.com/1x1.png", - "nurl": "https://ets-eu-west-1.track.smaato.net/v1/view?sessionId=e4e17adb-9599-42b1-bb5f-a1f1b3bee572&adSourceId=6906aae8-7f74-4edd-9a4f-f49379a3cadd&originalRequestTime=1552310449698&expires=1552311350698&winurl=ama8JbpJVpFWxvEja5viE3cLXFu58qRI8dGUh23xtsOn3N2-5UU0IwkgNEmR82pI37fcMXejL5IWTNAoW6Cnsjf-Dxl_vx2dUqMrVEevX-Vdx2VVnf-D5f73gZhvi4t36iPL8Dsw4aACekoLvVOV7-eXDjz7GHy60QFqcwKf5g2AlKPOInyZ6vJg_fn4qA9argvCRgwVybXE9Ndm2W0v8La4uFYWpJBOUveDDUrSQfzal7RsYvLb_OyaMlPHdrd_bwA9qqZWuyJXd-L9lxr7RQ%3D%3D%7CMw3kt91KJR0Uy5L-oNztAg%3D%3D&dpid=4XVofb_lH-__hr2JNGhKfg%3D%3D%7Cr9ciCU1cx3zmHXihItKO0g%3D%3D", - "price": 0.01, - "w": 350, - "h": 50, - "exp": 300 - }, - "type": "banner" - } - ] - } - ] -} diff --git a/adapters/smaato/smaatotest/supplemental/bad-adm-response.json b/adapters/smaato/smaatotest/supplemental/bad-adm-response.json deleted file mode 100644 index c86c6f179c4..00000000000 --- a/adapters/smaato/smaatotest/supplemental/bad-adm-response.json +++ /dev/null @@ -1,171 +0,0 @@ -{ - "mockBidRequest": { - "id": "1C86242D-9535-47D6-9576-7B1FE87F282C", - "site": { - "publisher": { - "id": "1100042525" - }, - "page": "http://localhost:3000/server.html?pbjs_debug=true&endpoint=http://localhost:3000/bidder", - "ext": { - "data": { - "keywords": "power tools", - "search": "drill", - "content": { - "userrating": 4 - } - } - } - }, - "imp": [ - { - "id": "1C86242D-9535-47D6-9576-7B1FE87F282C", - "banner": { - "format": [ - { - "w": 320, - "h": 50 - }, - { - "w": 320, - "h": 250 - } - ] - }, - "ext": { - "bidder": { - "publisherId": "1100042525", - "adspaceId": "130563103" - } - } - } - ], - "device": { - "ua": "test-user-agent", - "ip": "123.123.123.123", - "language": "en", - "dnt": 0 - }, - "user": { - "ext": { - "consent": "gdprConsentString", - "data": { - "keywords": "a,b", - "gender": "M", - "yob": 1984, - "geo": { - "country": "ca" - } - } - } - }, - "regs": { - "coppa": 1, - "ext": { - "gdpr": 1, - "us_privacy": "uspConsentString" - } - } - }, - "httpCalls": [ - { - "expectedRequest": { - "headers": { - "Content-Type": ["application/json;charset=utf-8"], - "Accept": ["application/json"] - }, - "uri": "https://prebid/bidder", - "body": { - "id": "1C86242D-9535-47D6-9576-7B1FE87F282C", - "imp": [ - { - "id": "1C86242D-9535-47D6-9576-7B1FE87F282C", - "tagid": "130563103", - "banner": { - "format": [ - { - "w": 320, - "h": 50 - }, - { - "w": 320, - "h": 250 - } - ] - } - } - ], - "user": { - "ext": { - "consent": "gdprConsentString" - }, - "gender": "M", - "keywords": "a,b", - "yob": 1984 - }, - "device": { - "ua": "test-user-agent", - "ip": "123.123.123.123", - "language": "en", - "dnt": 0 - }, - "regs": { - "coppa": 1, - "ext": { - "gdpr": 1, - "us_privacy": "uspConsentString" - } - }, - "site": { - "publisher": { - "id": "1100042525" - }, - "page": "http://localhost:3000/server.html?pbjs_debug=true&endpoint=http://localhost:3000/bidder", - "keywords": "power tools" - }, - "ext": { - "client": "prebid_server_0.7" - } - }, - "impIDs":["1C86242D-9535-47D6-9576-7B1FE87F282C"] - }, - "mockResponse": { - "status": 200, - "body": { - "id": "5ebea288-f13a-4754-be6d-4ade66c68877", - "seatbid": [ - { - "seat": "CM6523", - "bid": [ - { - "adm": "{\"badmedia\":{\"mediadata\":{\"content\":\"
hello
\", \"w\":350,\"h\":50},\"impressiontrackers\":[\"//prebid-test.smaatolabs.net/track/imp/1\",\"//prebid-test.smaatolabs.net/track/imp/2\"],\"clicktrackers\":[\"//prebid-test.smaatolabs.net/track/click/1\",\"//prebid-test.smaatolabs.net/track/click/2\"]}}", - "adomain": [ - "smaato.com" - ], - "bidderName": "smaato", - "cid": "CM6523", - "crid": "CR69381", - "id": "6906aae8-7f74-4edd-9a4f-f49379a3cadd", - "impid": "1C86242D-9535-47D6-9576-7B1FE87F282C", - "iurl": "https://bidstalkcreatives.s3.amazonaws.com/1x1.png", - "nurl": "https://ets-eu-west-1.track.smaato.net/v1/view?sessionId=e4e17adb-9599-42b1-bb5f-a1f1b3bee572&adSourceId=6906aae8-7f74-4edd-9a4f-f49379a3cadd&originalRequestTime=1552310449698&expires=1552311350698&winurl=ama8JbpJVpFWxvEja5viE3cLXFu58qRI8dGUh23xtsOn3N2-5UU0IwkgNEmR82pI37fcMXejL5IWTNAoW6Cnsjf-Dxl_vx2dUqMrVEevX-Vdx2VVnf-D5f73gZhvi4t36iPL8Dsw4aACekoLvVOV7-eXDjz7GHy60QFqcwKf5g2AlKPOInyZ6vJg_fn4qA9argvCRgwVybXE9Ndm2W0v8La4uFYWpJBOUveDDUrSQfzal7RsYvLb_OyaMlPHdrd_bwA9qqZWuyJXd-L9lxr7RQ%3D%3D%7CMw3kt91KJR0Uy5L-oNztAg%3D%3D&dpid=4XVofb_lH-__hr2JNGhKfg%3D%3D%7Cr9ciCU1cx3zmHXihItKO0g%3D%3D", - "price": 0.01, - "w": 350, - "h": 50 - } - ] - } - ], - "bidid": "04db8629-179d-4bcd-acce-e54722969006", - "cur": "USD" - } - } - } - ], - "expectedBidResponses": [{"currency":"USD","bids":[]}], - "expectedMakeBidsErrors": [ - { - "value": "Invalid ad markup {\"badmedia\":{\"mediadata\":{\"content\":\"
hello
\", \"w\":350,\"h\":50},\"impressiontrackers\":[\"//prebid-test.smaatolabs.net/track/imp/1\",\"//prebid-test.smaatolabs.net/track/imp/2\"],\"clicktrackers\":[\"//prebid-test.smaatolabs.net/track/click/1\",\"//prebid-test.smaatolabs.net/track/click/2\"]}}.", - "comparison": "literal" - } - ] -} diff --git a/adapters/smaato/smaatotest/supplemental/bad-adtype-header-response.json b/adapters/smaato/smaatotest/supplemental/bad-adtype-header-response.json index 98d490f9097..af739711bf4 100644 --- a/adapters/smaato/smaatotest/supplemental/bad-adtype-header-response.json +++ b/adapters/smaato/smaatotest/supplemental/bad-adtype-header-response.json @@ -123,7 +123,7 @@ "keywords": "power tools" }, "ext": { - "client": "prebid_server_0.7" + "client": "prebid_server_1.1" } }, "impIDs":["1C86242D-9535-47D6-9576-7B1FE87F282C"] @@ -140,7 +140,7 @@ "seat": "CM6523", "bid": [ { - "adm": "{\"image\":{\"img\":{\"url\":\"//prebid-test.smaatolabs.net/img/320x50.jpg\",\"w\":350,\"h\":50,\"ctaurl\":\"//prebid-test.smaatolabs.net/track/ctaurl/1\"},\"impressiontrackers\":[\"//prebid-test.smaatolabs.net/track/imp/1\",\"//prebid-test.smaatolabs.net/track/imp/2\"],\"clicktrackers\":[\"//prebid-test.smaatolabs.net/track/click/1\",\"//prebid-test.smaatolabs.net/track/click/2\"]}}", + "adm": "\"\"", "adomain": [ "smaato.com" ], diff --git a/adapters/smaato/smaatotest/supplemental/bad-expires-header-response.json b/adapters/smaato/smaatotest/supplemental/bad-expires-header-response.json index ac38f24537f..7368c666886 100644 --- a/adapters/smaato/smaatotest/supplemental/bad-expires-header-response.json +++ b/adapters/smaato/smaatotest/supplemental/bad-expires-header-response.json @@ -123,7 +123,7 @@ "keywords": "power tools" }, "ext": { - "client": "prebid_server_0.7" + "client": "prebid_server_1.1" } }, "impIDs":["1C86242D-9535-47D6-9576-7B1FE87F282C"] @@ -131,6 +131,7 @@ "mockResponse": { "status": 200, "headers": { + "X-Smt-Adtype": ["Img"], "X-Smt-Expires": ["something"] }, "body": { @@ -140,7 +141,7 @@ "seat": "CM6523", "bid": [ { - "adm": "{\"image\":{\"img\":{\"url\":\"//prebid-test.smaatolabs.net/img/320x50.jpg\",\"w\":350,\"h\":50,\"ctaurl\":\"//prebid-test.smaatolabs.net/track/ctaurl/1\"},\"impressiontrackers\":[\"//prebid-test.smaatolabs.net/track/imp/1\",\"//prebid-test.smaatolabs.net/track/imp/2\"],\"clicktrackers\":[\"//prebid-test.smaatolabs.net/track/click/1\",\"//prebid-test.smaatolabs.net/track/click/2\"]}}", + "adm": "\"\"", "adomain": [ "smaato.com" ], @@ -170,7 +171,7 @@ "bids": [ { "bid": { - "adm": "
\"\"\"\"
", + "adm": "\"\"", "adomain": [ "smaato.com" ], diff --git a/adapters/smaato/smaatotest/supplemental/bad-status-code-response.json b/adapters/smaato/smaatotest/supplemental/bad-status-code-response.json index fa77eb0e321..c00518e096f 100644 --- a/adapters/smaato/smaatotest/supplemental/bad-status-code-response.json +++ b/adapters/smaato/smaatotest/supplemental/bad-status-code-response.json @@ -123,7 +123,7 @@ "keywords": "power tools" }, "ext": { - "client": "prebid_server_0.7" + "client": "prebid_server_1.1" } }, "impIDs":["1C86242D-9535-47D6-9576-7B1FE87F282C"] diff --git a/adapters/smaato/smaatotest/supplemental/banner-w-and-h.json b/adapters/smaato/smaatotest/supplemental/banner-w-and-h.json index 7fea2733803..e3cc2174433 100644 --- a/adapters/smaato/smaatotest/supplemental/banner-w-and-h.json +++ b/adapters/smaato/smaatotest/supplemental/banner-w-and-h.json @@ -107,13 +107,16 @@ "keywords": "power tools" }, "ext": { - "client": "prebid_server_0.7" + "client": "prebid_server_1.1" } }, "impIDs":["1C86242D-9535-47D6-9576-7B1FE87F282C"] }, "mockResponse": { "status": 200, + "headers": { + "X-Smt-Adtype": ["Img"] + }, "body": { "id": "5ebea288-f13a-4754-be6d-4ade66c68877", "seatbid": [ @@ -121,7 +124,7 @@ "seat": "CM6523", "bid": [ { - "adm": "{\"image\":{\"img\":{\"url\":\"//prebid-test.smaatolabs.net/img/320x50.jpg\",\"w\":350,\"h\":50,\"ctaurl\":\"//prebid-test.smaatolabs.net/track/ctaurl/1\"},\"impressiontrackers\":[\"//prebid-test.smaatolabs.net/track/imp/1\",\"//prebid-test.smaatolabs.net/track/imp/2\"],\"clicktrackers\":[\"//prebid-test.smaatolabs.net/track/click/1\",\"//prebid-test.smaatolabs.net/track/click/2\"]}}", + "adm": "\"\"", "adomain": [ "smaato.com" ], @@ -151,7 +154,7 @@ "bids": [ { "bid": { - "adm": "
\"\"\"\"
", + "adm": "\"\"", "adomain": [ "smaato.com" ], diff --git a/adapters/smaato/smaatotest/exemplary/simple-banner-richMedia.json b/adapters/smaato/smaatotest/supplemental/curl-nil-response.json similarity index 82% rename from adapters/smaato/smaatotest/exemplary/simple-banner-richMedia.json rename to adapters/smaato/smaatotest/supplemental/curl-nil-response.json index 58dd502c0c0..9f0f3359ea6 100644 --- a/adapters/smaato/smaatotest/exemplary/simple-banner-richMedia.json +++ b/adapters/smaato/smaatotest/supplemental/curl-nil-response.json @@ -31,6 +31,8 @@ } ] }, + "instl": 1, + "bidfloor": 0.00123, "ext": { "bidder": { "publisherId": "1100042525", @@ -62,7 +64,9 @@ "coppa": 1, "ext": { "gdpr": 1, - "us_privacy": "uspConsentString" + "us_privacy": "uspConsentString", + "gpp": "gppString", + "gpp_sid": [7] } } }, @@ -70,12 +74,8 @@ { "expectedRequest": { "headers": { - "Content-Type": [ - "application/json;charset=utf-8" - ], - "Accept": [ - "application/json" - ] + "Content-Type": ["application/json;charset=utf-8"], + "Accept": ["application/json"] }, "uri": "https://prebid/bidder", "body": { @@ -84,6 +84,8 @@ { "id": "1C86242D-9535-47D6-9576-7B1FE87F282C", "tagid": "130563103", + "bidfloor": 0.00123, + "instl": 1, "banner": { "format": [ { @@ -99,12 +101,12 @@ } ], "user": { - "gender": "M", - "keywords": "a,b", - "yob": 1984, "ext": { "consent": "gdprConsentString" - } + }, + "gender": "M", + "keywords": "a,b", + "yob": 1984 }, "device": { "ua": "test-user-agent", @@ -116,7 +118,9 @@ "coppa": 1, "ext": { "gdpr": 1, - "us_privacy": "uspConsentString" + "us_privacy": "uspConsentString", + "gpp": "gppString", + "gpp_sid": [7] } }, "site": { @@ -127,13 +131,16 @@ "keywords": "power tools" }, "ext": { - "client": "prebid_server_0.7" + "client": "prebid_server_1.1" } }, "impIDs":["1C86242D-9535-47D6-9576-7B1FE87F282C"] }, "mockResponse": { "status": 200, + "headers": { + "X-Smt-Adtype": ["Img"] + }, "body": { "id": "5ebea288-f13a-4754-be6d-4ade66c68877", "seatbid": [ @@ -141,7 +148,7 @@ "seat": "CM6523", "bid": [ { - "adm": "{\"richmedia\":{\"mediadata\":{\"content\":\"
hello
\", \"w\":350,\"h\":50},\"impressiontrackers\":[\"//prebid-test.smaatolabs.net/track/imp/1\",\"//prebid-test.smaatolabs.net/track/imp/2\"],\"clicktrackers\":[\"//prebid-test.smaatolabs.net/track/click/1\",\"//prebid-test.smaatolabs.net/track/click/2\"]}}", + "adm": "\"\"", "adomain": [ "smaato.com" ], @@ -154,7 +161,10 @@ "nurl": "https://ets-eu-west-1.track.smaato.net/v1/view?sessionId=e4e17adb-9599-42b1-bb5f-a1f1b3bee572&adSourceId=6906aae8-7f74-4edd-9a4f-f49379a3cadd&originalRequestTime=1552310449698&expires=1552311350698&winurl=ama8JbpJVpFWxvEja5viE3cLXFu58qRI8dGUh23xtsOn3N2-5UU0IwkgNEmR82pI37fcMXejL5IWTNAoW6Cnsjf-Dxl_vx2dUqMrVEevX-Vdx2VVnf-D5f73gZhvi4t36iPL8Dsw4aACekoLvVOV7-eXDjz7GHy60QFqcwKf5g2AlKPOInyZ6vJg_fn4qA9argvCRgwVybXE9Ndm2W0v8La4uFYWpJBOUveDDUrSQfzal7RsYvLb_OyaMlPHdrd_bwA9qqZWuyJXd-L9lxr7RQ%3D%3D%7CMw3kt91KJR0Uy5L-oNztAg%3D%3D&dpid=4XVofb_lH-__hr2JNGhKfg%3D%3D%7Cr9ciCU1cx3zmHXihItKO0g%3D%3D", "price": 0.01, "w": 350, - "h": 50 + "h": 50, + "ext": { + "curls": null + } } ] } @@ -171,7 +181,7 @@ "bids": [ { "bid": { - "adm": "
hello
\"\"\"\"
", + "adm": "\"\"", "adomain": [ "smaato.com" ], @@ -184,7 +194,10 @@ "price": 0.01, "w": 350, "h": 50, - "exp": 300 + "exp": 300, + "ext": { + "curls": null + } }, "type": "banner" } diff --git a/adapters/smaato/smaatotest/supplemental/expires-header-response.json b/adapters/smaato/smaatotest/supplemental/expires-header-response.json index 1be49b0d16b..a063c7c1757 100644 --- a/adapters/smaato/smaatotest/supplemental/expires-header-response.json +++ b/adapters/smaato/smaatotest/supplemental/expires-header-response.json @@ -123,7 +123,7 @@ "keywords": "power tools" }, "ext": { - "client": "prebid_server_0.7" + "client": "prebid_server_1.1" } }, "impIDs":["1C86242D-9535-47D6-9576-7B1FE87F282C"] @@ -131,6 +131,7 @@ "mockResponse": { "status": 200, "headers": { + "X-Smt-Adtype": ["Img"], "X-Smt-Expires": ["1624618800000"] }, "body": { @@ -140,7 +141,7 @@ "seat": "CM6523", "bid": [ { - "adm": "{\"image\":{\"img\":{\"url\":\"//prebid-test.smaatolabs.net/img/320x50.jpg\",\"w\":350,\"h\":50,\"ctaurl\":\"//prebid-test.smaatolabs.net/track/ctaurl/1\"},\"impressiontrackers\":[\"//prebid-test.smaatolabs.net/track/imp/1\",\"//prebid-test.smaatolabs.net/track/imp/2\"],\"clicktrackers\":[\"//prebid-test.smaatolabs.net/track/click/1\",\"//prebid-test.smaatolabs.net/track/click/2\"]}}", + "adm": "\"\"", "adomain": [ "smaato.com" ], @@ -170,7 +171,7 @@ "bids": [ { "bid": { - "adm": "
\"\"\"\"
", + "adm": "\"\"", "adomain": [ "smaato.com" ], diff --git a/adapters/smaato/smaatotest/supplemental/no-app-site-request.json b/adapters/smaato/smaatotest/supplemental/no-app-site-dooh-request.json similarity index 92% rename from adapters/smaato/smaatotest/supplemental/no-app-site-request.json rename to adapters/smaato/smaatotest/supplemental/no-app-site-dooh-request.json index 04a73b4f40d..c6b2ead79da 100644 --- a/adapters/smaato/smaatotest/supplemental/no-app-site-request.json +++ b/adapters/smaato/smaatotest/supplemental/no-app-site-dooh-request.json @@ -23,7 +23,7 @@ }, "expectedMakeRequestsErrors": [ { - "value": "Missing Site/App.", + "value": "Missing Site/App/DOOH.", "comparison": "literal" } ] diff --git a/adapters/smaato/smaatotest/supplemental/no-bid-response.json b/adapters/smaato/smaatotest/supplemental/no-bid-response.json index 8127cdec258..be41b1f1c68 100644 --- a/adapters/smaato/smaatotest/supplemental/no-bid-response.json +++ b/adapters/smaato/smaatotest/supplemental/no-bid-response.json @@ -123,7 +123,7 @@ "keywords": "power tools" }, "ext": { - "client": "prebid_server_0.7" + "client": "prebid_server_1.1" } }, "impIDs":["1C86242D-9535-47D6-9576-7B1FE87F282C"] diff --git a/adapters/smaato/smaatotest/supplemental/no-consent-info-request.json b/adapters/smaato/smaatotest/supplemental/no-consent-info-request.json index 81f263797ba..6be49b1b4fb 100644 --- a/adapters/smaato/smaatotest/supplemental/no-consent-info-request.json +++ b/adapters/smaato/smaatotest/supplemental/no-consent-info-request.json @@ -70,13 +70,16 @@ } }, "ext": { - "client": "prebid_server_0.7" + "client": "prebid_server_1.1" } }, "impIDs":["1C86242D-9535-47D6-9576-7B1FE87F282C"] }, "mockResponse": { "status": 200, + "headers": { + "X-Smt-Adtype": ["Img"] + }, "body": { "id": "5ebea288-f13a-4754-be6d-4ade66c68877", "seatbid": [ @@ -84,7 +87,7 @@ "seat": "CM6523", "bid": [ { - "adm": "{\"image\":{\"img\":{\"url\":\"//prebid-test.smaatolabs.net/img/320x50.jpg\",\"w\":350,\"h\":50,\"ctaurl\":\"//prebid-test.smaatolabs.net/track/ctaurl/1\"},\"impressiontrackers\":[\"//prebid-test.smaatolabs.net/track/imp/1\",\"//prebid-test.smaatolabs.net/track/imp/2\"],\"clicktrackers\":[\"//prebid-test.smaatolabs.net/track/click/1\",\"//prebid-test.smaatolabs.net/track/click/2\"]}}", + "adm": "\"\"", "adomain": [ "smaato.com" ], @@ -114,7 +117,7 @@ "bids": [ { "bid": { - "adm": "
\"\"\"\"
", + "adm": "\"\"", "adomain": [ "smaato.com" ], diff --git a/adapters/smaato/smaatotest/supplemental/outdated-expires-header-response.json b/adapters/smaato/smaatotest/supplemental/outdated-expires-header-response.json index 96dea545bf4..fd52751aae6 100644 --- a/adapters/smaato/smaatotest/supplemental/outdated-expires-header-response.json +++ b/adapters/smaato/smaatotest/supplemental/outdated-expires-header-response.json @@ -123,7 +123,7 @@ "keywords": "power tools" }, "ext": { - "client": "prebid_server_0.7" + "client": "prebid_server_1.1" } }, "impIDs":["1C86242D-9535-47D6-9576-7B1FE87F282C"] @@ -131,6 +131,7 @@ "mockResponse": { "status": 200, "headers": { + "X-Smt-Adtype": ["Img"], "X-Smt-Expires": ["1524618800000"] }, "body": { @@ -140,7 +141,7 @@ "seat": "CM6523", "bid": [ { - "adm": "{\"image\":{\"img\":{\"url\":\"//prebid-test.smaatolabs.net/img/320x50.jpg\",\"w\":350,\"h\":50,\"ctaurl\":\"//prebid-test.smaatolabs.net/track/ctaurl/1\"},\"impressiontrackers\":[\"//prebid-test.smaatolabs.net/track/imp/1\",\"//prebid-test.smaatolabs.net/track/imp/2\"],\"clicktrackers\":[\"//prebid-test.smaatolabs.net/track/click/1\",\"//prebid-test.smaatolabs.net/track/click/2\"]}}", + "adm": "\"\"", "adomain": [ "smaato.com" ], @@ -170,7 +171,7 @@ "bids": [ { "bid": { - "adm": "
\"\"\"\"
", + "adm": "\"\"", "adomain": [ "smaato.com" ], diff --git a/adapters/smaato/smaatotest/video/multiple-adpods-skadn.json b/adapters/smaato/smaatotest/video/multiple-adpods-skadn.json index 52fb2a4d1f7..a9942bcbd93 100644 --- a/adapters/smaato/smaatotest/video/multiple-adpods-skadn.json +++ b/adapters/smaato/smaatotest/video/multiple-adpods-skadn.json @@ -301,13 +301,16 @@ } }, "ext": { - "client": "prebid_server_0.7" + "client": "prebid_server_1.1" } }, "impIDs":["1_1","1_2"] }, "mockResponse": { "status": 200, + "headers": { + "X-Smt-Adtype": ["Video"] + }, "body": { "id": "5ebea288-f13a-4754-be6d-4ade66c68877", "seatbid": [ @@ -513,13 +516,16 @@ } }, "ext": { - "client": "prebid_server_0.7" + "client": "prebid_server_1.1" } }, "impIDs":["2_1","2_2"] }, "mockResponse": { "status": 200, + "headers": { + "X-Smt-Adtype": ["Video"] + }, "body": { "id": "5ebea288-f13a-4754-be6d-4ade66c68877", "seatbid": [ diff --git a/adapters/smaato/smaatotest/video/multiple-adpods.json b/adapters/smaato/smaatotest/video/multiple-adpods.json index bd7498ddc7e..c2eac4dc65c 100644 --- a/adapters/smaato/smaatotest/video/multiple-adpods.json +++ b/adapters/smaato/smaatotest/video/multiple-adpods.json @@ -234,13 +234,16 @@ } }, "ext": { - "client": "prebid_server_0.7" + "client": "prebid_server_1.1" } }, "impIDs":["1_1","1_2"] }, "mockResponse": { "status": 200, + "headers": { + "X-Smt-Adtype": ["Video"] + }, "body": { "id": "5ebea288-f13a-4754-be6d-4ade66c68877", "seatbid": [ @@ -387,13 +390,16 @@ } }, "ext": { - "client": "prebid_server_0.7" + "client": "prebid_server_1.1" } }, "impIDs":["2_1","2_2"] }, "mockResponse": { "status": 200, + "headers": { + "X-Smt-Adtype": ["Video"] + }, "body": { "id": "5ebea288-f13a-4754-be6d-4ade66c68877", "seatbid": [ diff --git a/adapters/smaato/smaatotest/video/single-adpod-skadn.json b/adapters/smaato/smaatotest/video/single-adpod-skadn.json index a61a79e37fe..3f2070a3021 100644 --- a/adapters/smaato/smaatotest/video/single-adpod-skadn.json +++ b/adapters/smaato/smaatotest/video/single-adpod-skadn.json @@ -221,13 +221,16 @@ } }, "ext": { - "client": "prebid_server_0.7" + "client": "prebid_server_1.1" } }, "impIDs":["1_1","1_2"] }, "mockResponse": { "status": 200, + "headers": { + "X-Smt-Adtype": ["Video"] + }, "body": { "id": "5ebea288-f13a-4754-be6d-4ade66c68877", "seatbid": [ diff --git a/adapters/smaato/smaatotest/video/single-adpod.json b/adapters/smaato/smaatotest/video/single-adpod.json index b739c9049d1..11e6ccf710d 100644 --- a/adapters/smaato/smaatotest/video/single-adpod.json +++ b/adapters/smaato/smaatotest/video/single-adpod.json @@ -180,13 +180,16 @@ } }, "ext": { - "client": "prebid_server_0.7" + "client": "prebid_server_1.1" } }, "impIDs":["1_1","1_2"] }, "mockResponse": { "status": 200, + "headers": { + "X-Smt-Adtype": ["Video"] + }, "body": { "id": "5ebea288-f13a-4754-be6d-4ade66c68877", "seatbid": [ diff --git a/adapters/smaato/smaatotest/videosupplemental/bad-adm-response.json b/adapters/smaato/smaatotest/videosupplemental/bad-adtype-header-response.json similarity index 77% rename from adapters/smaato/smaatotest/videosupplemental/bad-adm-response.json rename to adapters/smaato/smaatotest/videosupplemental/bad-adtype-header-response.json index 91e1c25dd96..e831add95de 100644 --- a/adapters/smaato/smaatotest/videosupplemental/bad-adm-response.json +++ b/adapters/smaato/smaatotest/videosupplemental/bad-adtype-header-response.json @@ -176,13 +176,19 @@ } }, "ext": { - "client": "prebid_server_0.7" + "client": "prebid_server_1.1" } }, - "impIDs":["1_1","1_2"] + "impIDs": [ + "1_1", + "1_2" + ] }, "mockResponse": { "status": 200, + "headers": { + "X-Smt-Adtype": null + }, "body": { "id": "5ebea288-f13a-4754-be6d-4ade66c68877", "seatbid": [ @@ -204,29 +210,11 @@ "price": 0.01, "w": 1024, "h": 768, - "cat": ["IAB1"], - "ext": { - "duration": 5 - } - }, - { - "adm": "", - "adomain": [ - "smaato.com" + "cat": [ + "IAB1" ], - "bidderName": "smaato", - "cid": "CM6523", - "crid": "CR69381", - "id": "6906aae8-7f74-4edd-9a4f-f49379a3cadd", - "impid": "1_2", - "iurl": "https://iurl", - "nurl": "https://nurl", - "price": 0.01, - "w": 1024, - "h": 768, - "cat": ["IAB2"], "ext": { - "duration": 30 + "duration": 5 } } ] @@ -240,38 +228,9 @@ ], "expectedMakeBidsErrors": [ { - "value": "Invalid ad markup .", + "value": "X-Smt-Adtype header is missing.", "comparison": "literal" } ], - "expectedBidResponses": [ - { - "currency": "USD", - "bids": [ - { - "bid": { - "adm": "", - "adomain": [ - "smaato.com" - ], - "cid": "CM6523", - "crid": "CR69381", - "id": "6906aae8-7f74-4edd-9a4f-f49379a3cadd", - "impid": "1_1", - "iurl": "https://iurl", - "nurl": "https://nurl", - "price": 0.01, - "w": 1024, - "h": 768, - "cat": ["IAB1"], - "ext": { - "duration": 5 - }, - "exp": 300 - }, - "type": "video" - } - ] - } - ] + "expectedBidResponses": [] } diff --git a/adapters/smaato/smaatotest/videosupplemental/bad-bid-ext-response.json b/adapters/smaato/smaatotest/videosupplemental/bad-bid-ext-response.json index ff724cb3d2d..7fca5d38592 100644 --- a/adapters/smaato/smaatotest/videosupplemental/bad-bid-ext-response.json +++ b/adapters/smaato/smaatotest/videosupplemental/bad-bid-ext-response.json @@ -176,13 +176,16 @@ } }, "ext": { - "client": "prebid_server_0.7" + "client": "prebid_server_1.1" } }, "impIDs":["1_1","1_2"] }, "mockResponse": { "status": 200, + "headers": { + "X-Smt-Adtype": ["Video"] + }, "body": { "id": "5ebea288-f13a-4754-be6d-4ade66c68877", "seatbid": [ diff --git a/adapters/smartadserver/params_test.go b/adapters/smartadserver/params_test.go index fcd07278be6..fb71edb414d 100644 --- a/adapters/smartadserver/params_test.go +++ b/adapters/smartadserver/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/smartadserver.json diff --git a/adapters/smartadserver/smartadserver.go b/adapters/smartadserver/smartadserver.go index f28c0f618f7..edcb146adaf 100644 --- a/adapters/smartadserver/smartadserver.go +++ b/adapters/smartadserver/smartadserver.go @@ -9,10 +9,11 @@ import ( "strconv" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type SmartAdserverAdapter struct { @@ -61,7 +62,7 @@ func (a *SmartAdserverAdapter) MakeRequests(request *openrtb2.BidRequest, reqInf // We send one serialized "smartRequest" per impression of the original request. for _, imp := range request.Imp { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { errs = append(errs, &errortypes.BadInput{ Message: "Error parsing bidderExt object", }) @@ -69,7 +70,7 @@ func (a *SmartAdserverAdapter) MakeRequests(request *openrtb2.BidRequest, reqInf } var smartadserverExt openrtb_ext.ExtImpSmartadserver - if err := json.Unmarshal(bidderExt.Bidder, &smartadserverExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &smartadserverExt); err != nil { errs = append(errs, &errortypes.BadInput{ Message: "Error parsing smartadserverExt parameters", }) @@ -137,7 +138,7 @@ func (a *SmartAdserverAdapter) MakeBids(internalRequest *openrtb2.BidRequest, ex } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } diff --git a/adapters/smartadserver/smartadserver_test.go b/adapters/smartadserver/smartadserver_test.go index be5c13d54e2..51b1fb09147 100644 --- a/adapters/smartadserver/smartadserver_test.go +++ b/adapters/smartadserver/smartadserver_test.go @@ -3,9 +3,9 @@ package smartadserver import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/smartadserver/smartadservertest/supplemental/response-200-without-body.json b/adapters/smartadserver/smartadservertest/supplemental/response-200-without-body.json index 87196e8c1ad..2b925662e52 100644 --- a/adapters/smartadserver/smartadservertest/supplemental/response-200-without-body.json +++ b/adapters/smartadserver/smartadservertest/supplemental/response-200-without-body.json @@ -56,8 +56,8 @@ ], "expectedMakeBidsErrors": [ { - "value": "unexpected end of JSON input", - "comparison": "literal" + "value": "expect { or n, but found", + "comparison": "startswith" } ] } diff --git a/adapters/smarthub/params_test.go b/adapters/smarthub/params_test.go index 3d9a6c351bc..96799700710 100644 --- a/adapters/smarthub/params_test.go +++ b/adapters/smarthub/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/smarthub/smarthub.go b/adapters/smarthub/smarthub.go index c170ba5dbd1..080fe01fd1a 100644 --- a/adapters/smarthub/smarthub.go +++ b/adapters/smarthub/smarthub.go @@ -7,11 +7,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) const ( @@ -41,14 +42,14 @@ func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server co func (a *adapter) getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtSmartHub, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: "Bidder extension not provided or can't be unmarshalled", } } var smarthubExt openrtb_ext.ExtSmartHub - if err := json.Unmarshal(bidderExt.Bidder, &smarthubExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &smarthubExt); err != nil { return nil, &errortypes.BadInput{ Message: "Error while unmarshaling bidder extension", } @@ -135,7 +136,7 @@ func (a *adapter) MakeBids( responseBody := bidderRawResponse.Body var bidResp openrtb2.BidResponse - if err := json.Unmarshal(responseBody, &bidResp); err != nil { + if err := jsonutil.Unmarshal(responseBody, &bidResp); err != nil { return nil, []error{err} } @@ -160,7 +161,7 @@ func (a *adapter) MakeBids( var bidExt bidExt var bidType openrtb_ext.BidType - if err := json.Unmarshal(bid.Ext, &bidExt); err != nil { + if err := jsonutil.Unmarshal(bid.Ext, &bidExt); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: "Field BidExt is required", }} diff --git a/adapters/smarthub/smarthub_test.go b/adapters/smarthub/smarthub_test.go index 7194421a20e..a932364bd00 100644 --- a/adapters/smarthub/smarthub_test.go +++ b/adapters/smarthub/smarthub_test.go @@ -3,9 +3,9 @@ package smarthub import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/smarthub/smarthubtest/supplemental/bad-response.json b/adapters/smarthub/smarthubtest/supplemental/bad-response.json index 09e5d9ab442..5911c140a05 100644 --- a/adapters/smarthub/smarthubtest/supplemental/bad-response.json +++ b/adapters/smarthub/smarthubtest/supplemental/bad-response.json @@ -101,7 +101,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ], diff --git a/adapters/smartrtb/smartrtb.go b/adapters/smartrtb/smartrtb.go index 1c5d1abb1de..68fd9bfccb0 100644 --- a/adapters/smartrtb/smartrtb.go +++ b/adapters/smartrtb/smartrtb.go @@ -7,11 +7,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) // Base adapter structure. @@ -62,14 +63,14 @@ func (adapter *SmartRTBAdapter) buildEndpointURL(pubID string) (string, error) { func parseExtImp(dst *bidRequestExt, imp *openrtb2.Imp) error { var ext adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &ext); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &ext); err != nil { return &errortypes.BadInput{ Message: err.Error(), } } var src openrtb_ext.ExtImpSmartRTB - if err := json.Unmarshal(ext.Bidder, &src); err != nil { + if err := jsonutil.Unmarshal(ext.Bidder, &src); err != nil { return &errortypes.BadInput{ Message: err.Error(), } @@ -160,7 +161,7 @@ func (s *SmartRTBAdapter) MakeBids( } var brs openrtb2.BidResponse - if err := json.Unmarshal(rs.Body, &brs); err != nil { + if err := jsonutil.Unmarshal(rs.Body, &brs); err != nil { return nil, []error{err} } @@ -168,7 +169,7 @@ func (s *SmartRTBAdapter) MakeBids( for _, seat := range brs.SeatBid { for i := range seat.Bid { var ext bidExt - if err := json.Unmarshal(seat.Bid[i].Ext, &ext); err != nil { + if err := jsonutil.Unmarshal(seat.Bid[i].Ext, &ext); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: "Invalid bid extension from endpoint.", }} diff --git a/adapters/smartrtb/smartrtb_test.go b/adapters/smartrtb/smartrtb_test.go index c0e83d3b826..060323a7ac9 100644 --- a/adapters/smartrtb/smartrtb_test.go +++ b/adapters/smartrtb/smartrtb_test.go @@ -3,9 +3,9 @@ package smartrtb import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/smartrtb/smartrtbtest/supplemental/bad-bidder-ext.json b/adapters/smartrtb/smartrtbtest/supplemental/bad-bidder-ext.json index b261415de4d..774cd2141d6 100644 --- a/adapters/smartrtb/smartrtbtest/supplemental/bad-bidder-ext.json +++ b/adapters/smartrtb/smartrtbtest/supplemental/bad-bidder-ext.json @@ -24,8 +24,8 @@ "expectedMakeRequestsErrors": [ { - "value": "unexpected end of JSON input", - "comparison": "literal" + "value": "expect { or n, but found", + "comparison": "startswith" } ] } diff --git a/adapters/smartrtb/smartrtbtest/supplemental/bad-imp-ext.json b/adapters/smartrtb/smartrtbtest/supplemental/bad-imp-ext.json index 1c0f57d2f34..b5b77d9e57a 100644 --- a/adapters/smartrtb/smartrtbtest/supplemental/bad-imp-ext.json +++ b/adapters/smartrtb/smartrtbtest/supplemental/bad-imp-ext.json @@ -25,8 +25,8 @@ "expectedMakeRequestsErrors": [ { - "value": "unexpected end of JSON input", - "comparison": "literal" + "value": "expect { or n, but found", + "comparison": "startswith" } ] } diff --git a/adapters/smartrtb/smartrtbtest/supplemental/bad-pub-value.json b/adapters/smartrtb/smartrtbtest/supplemental/bad-pub-value.json index 93b45c747fd..cff39cc06b1 100644 --- a/adapters/smartrtb/smartrtbtest/supplemental/bad-pub-value.json +++ b/adapters/smartrtb/smartrtbtest/supplemental/bad-pub-value.json @@ -30,7 +30,7 @@ "expectedMakeRequestsErrors": [ { - "value": "json: cannot unmarshal number into Go struct field ExtImpSmartRTB.pub_id of type string", + "value": "cannot unmarshal PubID: expects \" or n, but found 0", "comparison": "literal" } ] diff --git a/adapters/smartrtb/smartrtbtest/supplemental/invalid-bid-json.json b/adapters/smartrtb/smartrtbtest/supplemental/invalid-bid-json.json index a8065446443..51b2ec8b794 100644 --- a/adapters/smartrtb/smartrtbtest/supplemental/invalid-bid-json.json +++ b/adapters/smartrtb/smartrtbtest/supplemental/invalid-bid-json.json @@ -70,7 +70,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/smartrtb/smartrtbtest/supplemental/invalid-imp-ext.json b/adapters/smartrtb/smartrtbtest/supplemental/invalid-imp-ext.json index 13485f797ba..743f492bba1 100644 --- a/adapters/smartrtb/smartrtbtest/supplemental/invalid-imp-ext.json +++ b/adapters/smartrtb/smartrtbtest/supplemental/invalid-imp-ext.json @@ -25,7 +25,7 @@ "expectedMakeRequestsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type adapters.ExtImpBidder", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/smartx/params_test.go b/adapters/smartx/params_test.go index 81ee269a5ef..837c63568a4 100644 --- a/adapters/smartx/params_test.go +++ b/adapters/smartx/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/smartx/smartx.go b/adapters/smartx/smartx.go index 9254ec0d95c..154f511f03c 100644 --- a/adapters/smartx/smartx.go +++ b/adapters/smartx/smartx.go @@ -7,9 +7,10 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -63,7 +64,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, _ *adapters.RequestData } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } diff --git a/adapters/smartx/smartx_test.go b/adapters/smartx/smartx_test.go index 503a547d2fc..6d257528656 100644 --- a/adapters/smartx/smartx_test.go +++ b/adapters/smartx/smartx_test.go @@ -3,9 +3,9 @@ package smartx import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) const testsDir = "smartxtest" diff --git a/adapters/smartyads/params_test.go b/adapters/smartyads/params_test.go index 0e1b7186397..ed49894629d 100644 --- a/adapters/smartyads/params_test.go +++ b/adapters/smartyads/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/smartyads/smartyads.go b/adapters/smartyads/smartyads.go index d00a808d025..3a07edaf628 100644 --- a/adapters/smartyads/smartyads.go +++ b/adapters/smartyads/smartyads.go @@ -8,11 +8,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type SmartyAdsAdapter struct { @@ -109,13 +110,13 @@ func (a *SmartyAdsAdapter) MakeRequests( func (a *SmartyAdsAdapter) getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtSmartyAds, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: "ext.bidder not provided", } } var smartyadsExt openrtb_ext.ExtSmartyAds - if err := json.Unmarshal(bidderExt.Bidder, &smartyadsExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &smartyadsExt); err != nil { return nil, &errortypes.BadInput{ Message: "ext.bidder not provided", } @@ -169,7 +170,7 @@ func (a *SmartyAdsAdapter) MakeBids( responseBody := bidderRawResponse.Body var bidResp openrtb2.BidResponse - if err := json.Unmarshal(responseBody, &bidResp); err != nil { + if err := jsonutil.Unmarshal(responseBody, &bidResp); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: "Bad Server Response", }} diff --git a/adapters/smartyads/smartyads_test.go b/adapters/smartyads/smartyads_test.go index 6a697c1d5f4..330f3900a00 100644 --- a/adapters/smartyads/smartyads_test.go +++ b/adapters/smartyads/smartyads_test.go @@ -3,9 +3,9 @@ package smartyads import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/smilewanted/params_test.go b/adapters/smilewanted/params_test.go index ac055542417..78a29dc046d 100644 --- a/adapters/smilewanted/params_test.go +++ b/adapters/smilewanted/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/smilewanted.json diff --git a/adapters/smilewanted/smilewanted.go b/adapters/smilewanted/smilewanted.go index b17b3825540..5484c8419d9 100644 --- a/adapters/smilewanted/smilewanted.go +++ b/adapters/smilewanted/smilewanted.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -61,14 +62,14 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: fmt.Sprintf("Bad server response: %s.", err), }} } var bidReq openrtb2.BidRequest - if err := json.Unmarshal(externalRequest.Body, &bidReq); err != nil { + if err := jsonutil.Unmarshal(externalRequest.Body, &bidReq); err != nil { return nil, []error{err} } diff --git a/adapters/smilewanted/smilewanted_test.go b/adapters/smilewanted/smilewanted_test.go index 3df23f42911..b63c2172e93 100644 --- a/adapters/smilewanted/smilewanted_test.go +++ b/adapters/smilewanted/smilewanted_test.go @@ -3,9 +3,9 @@ package smilewanted import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/smilewanted/smilewantedtest/supplemental/bad-server-response.json b/adapters/smilewanted/smilewantedtest/supplemental/bad-server-response.json index 63826e325fa..e6f59ab83a1 100644 --- a/adapters/smilewanted/smilewantedtest/supplemental/bad-server-response.json +++ b/adapters/smilewanted/smilewantedtest/supplemental/bad-server-response.json @@ -57,7 +57,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "Bad server response: json: cannot unmarshal string into Go value of type openrtb2.BidResponse.", + "value": "Bad server response: expect { or n, but found \".", "comparison": "literal" } ] diff --git a/adapters/smrtconnect/smrtconnect.go b/adapters/smrtconnect/smrtconnect.go index bd68e267eaf..4ecde49cea5 100644 --- a/adapters/smrtconnect/smrtconnect.go +++ b/adapters/smrtconnect/smrtconnect.go @@ -6,11 +6,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -64,13 +65,13 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte func getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtSmrtconnect, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: "ext.bidder not provided", } } var smrtconnectExt openrtb_ext.ExtSmrtconnect - if err := json.Unmarshal(bidderExt.Bidder, &smrtconnectExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &smrtconnectExt); err != nil { return nil, &errortypes.BadInput{ Message: "ext.bidder not provided", } @@ -94,7 +95,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: "Bad Server Response", }} diff --git a/adapters/smrtconnect/smrtconnect_test.go b/adapters/smrtconnect/smrtconnect_test.go index 38d071d94d1..2b020c1e3ae 100644 --- a/adapters/smrtconnect/smrtconnect_test.go +++ b/adapters/smrtconnect/smrtconnect_test.go @@ -3,9 +3,9 @@ package smrtconnect import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/sonobi/params_test.go b/adapters/sonobi/params_test.go index c84a99edfdf..7ffff8ffdd0 100644 --- a/adapters/sonobi/params_test.go +++ b/adapters/sonobi/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/sonobi.json diff --git a/adapters/sonobi/sonobi.go b/adapters/sonobi/sonobi.go index 65ea0d33e7c..cf00595c6bf 100644 --- a/adapters/sonobi/sonobi.go +++ b/adapters/sonobi/sonobi.go @@ -4,12 +4,14 @@ import ( "encoding/json" "fmt" "net/http" + "strings" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) // SonobiAdapter - Sonobi SonobiAdapter definition @@ -41,18 +43,37 @@ func (a *SonobiAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adap reqCopy.Imp = append(make([]openrtb2.Imp, 0, 1), imp) var bidderExt adapters.ExtImpBidder - if err = json.Unmarshal(reqCopy.Imp[0].Ext, &bidderExt); err != nil { + if err = jsonutil.Unmarshal(reqCopy.Imp[0].Ext, &bidderExt); err != nil { errs = append(errs, err) continue } - if err = json.Unmarshal(bidderExt.Bidder, &sonobiExt); err != nil { + if err = jsonutil.Unmarshal(bidderExt.Bidder, &sonobiExt); err != nil { errs = append(errs, err) continue } reqCopy.Imp[0].TagID = sonobiExt.TagID + // If the bid floor currency is not USD, do the conversion to USD + if reqCopy.Imp[0].BidFloor > 0 && reqCopy.Imp[0].BidFloorCur != "" && strings.ToUpper(reqCopy.Imp[0].BidFloorCur) != "USD" { + + // Convert to US dollars + convertedValue, err := reqInfo.ConvertCurrency(reqCopy.Imp[0].BidFloor, reqCopy.Imp[0].BidFloorCur, "USD") + if err != nil { + errs = append(errs, err) + continue + } + + // Update after conversion. All imp elements inside request.Imp are shallow copies + // therefore, their non-pointer values are not shared memory and are safe to modify. + reqCopy.Imp[0].BidFloorCur = "USD" + reqCopy.Imp[0].BidFloor = convertedValue + } + + // Sonobi only bids in USD + reqCopy.Cur = append(make([]string, 0, 1), "USD") + adapterReq, errors := a.makeRequest(&reqCopy) if adapterReq != nil { adapterRequests = append(adapterRequests, adapterReq) @@ -110,24 +131,24 @@ func (a *SonobiAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalR var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } bidResponse := adapters.NewBidderResponseWithBidsCapacity(5) + bidResponse.Currency = "USD" // Sonobi only bids in USD for _, sb := range bidResp.SeatBid { for i := range sb.Bid { - bidType, err := getMediaTypeForImp(sb.Bid[i].ImpID, internalRequest.Imp) + bid := sb.Bid[i] + bidType, err := getMediaTypeForImp(bid.ImpID, internalRequest.Imp) if err != nil { - errs = append(errs, err) - } else { - b := &adapters.TypedBid{ - Bid: &sb.Bid[i], - BidType: bidType, - } - bidResponse.Bids = append(bidResponse.Bids, b) + return nil, []error{err} } + bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ + Bid: &bid, + BidType: bidType, + }) } } return bidResponse, errs @@ -140,6 +161,9 @@ func getMediaTypeForImp(impID string, imps []openrtb2.Imp) (openrtb_ext.BidType, if imp.Banner == nil && imp.Video != nil { mediaType = openrtb_ext.BidTypeVideo } + if imp.Banner == nil && imp.Video == nil && imp.Native != nil { + mediaType = openrtb_ext.BidTypeNative + } return mediaType, nil } } diff --git a/adapters/sonobi/sonobi_test.go b/adapters/sonobi/sonobi_test.go index 3123781323d..aa9f44ed7a2 100644 --- a/adapters/sonobi/sonobi_test.go +++ b/adapters/sonobi/sonobi_test.go @@ -3,9 +3,9 @@ package sonobi import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/sonobi/sonobitest/exemplary/banner.json b/adapters/sonobi/sonobitest/exemplary/banner.json index d60ddb44a8b..f3a39f74a27 100644 --- a/adapters/sonobi/sonobitest/exemplary/banner.json +++ b/adapters/sonobi/sonobitest/exemplary/banner.json @@ -1,5 +1,6 @@ { "mockBidRequest": { + "cur": ["GBP"], "id": "some-request-id", "site": { "page": "http://tester.go.sonobi.com", @@ -48,6 +49,7 @@ }, "uri": "https://apex.go.sonobi.com/prebid?partnerid=71d9d3d8af", "body": { + "cur": ["USD"], "id": "some-request-id", "imp": [ { diff --git a/adapters/sonobi/sonobitest/exemplary/native.json b/adapters/sonobi/sonobitest/exemplary/native.json new file mode 100644 index 00000000000..ff9eb4c4693 --- /dev/null +++ b/adapters/sonobi/sonobitest/exemplary/native.json @@ -0,0 +1,143 @@ +{ + "mockBidRequest": { + "cur": ["USD"], + "id": "some-request-id", + "site": { + "page": "http://tester.go.sonobi.com", + "domain": "sonobi.com" + }, + "device": { + "ip": "123.123.123.123" + }, + "imp": [ + { + "id": "some-impression-id", + "native": { + "request": "{\"ver\":\"1.2\",\"context\":1,\"contextsubtype\":11,\"plcmttype\":2,\"plcmtcnt\":3,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":1000}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":600,\"hmin\":600}},{\"id\":3,\"required\":0,\"data\":{\"type\":1,\"len\":200}},{\"id\":4,\"required\":0,\"data\":{\"type\":2,\"len\":3000}},{\"id\":5,\"required\":0,\"data\":{\"type\":6,\"len\":60}},{\"id\":6,\"required\":0,\"data\":{\"type\":500}},{\"id\":10,\"required\":0,\"data\":{\"type\":12,\"len\":15}}],\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"privacy\":1}", + "ver": "1.2", + "battr": [ + 1, + 2, + 6, + 7, + 8, + 9, + 10, + 14 + ] + }, + "ext": { + "bidder": { + "TagID": "/7780971/apex_3pdm_integration" + } + } + } + ], + "test": 1, + "tmax": 500 + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ] + }, + "uri": "https://apex.go.sonobi.com/prebid?partnerid=71d9d3d8af", + "body": { + "cur": ["USD"], + "id": "some-request-id", + "imp": [ + { + "id": "some-impression-id", + "native": { + "request": "{\"ver\":\"1.2\",\"context\":1,\"contextsubtype\":11,\"plcmttype\":2,\"plcmtcnt\":3,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":1000}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":600,\"hmin\":600}},{\"id\":3,\"required\":0,\"data\":{\"type\":1,\"len\":200}},{\"id\":4,\"required\":0,\"data\":{\"type\":2,\"len\":3000}},{\"id\":5,\"required\":0,\"data\":{\"type\":6,\"len\":60}},{\"id\":6,\"required\":0,\"data\":{\"type\":500}},{\"id\":10,\"required\":0,\"data\":{\"type\":12,\"len\":15}}],\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"privacy\":1}", + "ver": "1.2", + "battr": [ + 1, + 2, + 6, + 7, + 8, + 9, + 10, + 14 + ] + }, + "tagid": "/7780971/apex_3pdm_integration", + "ext": { + "bidder": { + "TagID": "/7780971/apex_3pdm_integration" + } + } + } + ], + "site": { + "domain": "sonobi.com", + "page": "http://tester.go.sonobi.com" + }, + "device": { + "ip": "123.123.123.123" + }, + "test": 1, + "tmax": 500 + }, + "impIDs": [ + "some-impression-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "some-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "1", + "impid": "some-impression-id", + "price": 2.8649999999999998, + "adm": "test-markup", + "adomain": [ + "sonobi.com" + ], + "cid": "house", + "crid": "sandbox" + + } + ], + "seat": "sonobi" + } + ], + "bidid": "sandbox_642305097", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "1", + "impid": "some-impression-id", + "price": 2.8649999999999998, + "adm": "test-markup", + "adomain": [ + "sonobi.com" + ], + "cid": "house", + "crid": "sandbox" + }, + "type": "native" + } + ] + } + ] +} diff --git a/adapters/sonobi/sonobitest/exemplary/no-bid.json b/adapters/sonobi/sonobitest/exemplary/no-bid.json index ef31c9f2ba4..a43d1f670a0 100644 --- a/adapters/sonobi/sonobitest/exemplary/no-bid.json +++ b/adapters/sonobi/sonobitest/exemplary/no-bid.json @@ -1,5 +1,6 @@ { "mockBidRequest": { + "cur": ["USD"], "id": "some-request-id", "site": { "page": "http://tester.go.sonobi.com", @@ -48,6 +49,7 @@ }, "uri": "https://apex.go.sonobi.com/prebid?partnerid=71d9d3d8af", "body": { + "cur": ["USD"], "id": "some-request-id", "imp": [ { diff --git a/adapters/sonobi/sonobitest/supplemental/currency-conversion.json b/adapters/sonobi/sonobitest/supplemental/currency-conversion.json new file mode 100644 index 00000000000..522e1bd7326 --- /dev/null +++ b/adapters/sonobi/sonobitest/supplemental/currency-conversion.json @@ -0,0 +1,172 @@ +{ + "mockBidRequest": { + "cur": ["GBP"], + "id": "some-request-id", + "site": { + "page": "http://tester.go.sonobi.com", + "domain": "sonobi.com" + }, + "device": { + "ip": "123.123.123.123" + }, + "imp": [ + { + "id": "some-impression-id", + "banner": { + "w": 300, + "h": 250, + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "bidfloor": 1.00, + "bidfloorcur": "GBP", + "ext": { + "bidder": { + "TagID": "/7780971/apex_3pdm_integration" + } + } + } + ], + "ext": { + "prebid": { + "currency": { + "rates": { + "GBP": { + "USD": 0.05 + } + }, + "usepbsrates": false + } + } + }, + "test": 1, + "tmax": 500 + }, + "httpCalls": [ + { + "expectedRequest": { + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json;charset=utf-8" + ] + }, + "uri": "https://apex.go.sonobi.com/prebid?partnerid=71d9d3d8af", + "body": { + "cur": ["USD"], + "id": "some-request-id", + "imp": [ + { + "id": "some-impression-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ], + "w": 300, + "h": 250 + }, + "bidfloor": 0.05, + "bidfloorcur": "USD", + "tagid": "/7780971/apex_3pdm_integration", + "ext": { + "bidder": { + "TagID": "/7780971/apex_3pdm_integration" + } + } + } + ], + "ext": { + "prebid": { + "currency": { + "rates": { + "GBP": { + "USD": 0.05 + } + }, + "usepbsrates": false + } + } + }, + "site": { + "domain": "sonobi.com", + "page": "http://tester.go.sonobi.com" + }, + "device": { + "ip": "123.123.123.123" + }, + "test": 1, + "tmax": 500 + }, + "impIDs":["some-impression-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "some-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "1", + "impid": "some-impression-id", + "price": 2.8649999999999998, + "adm": "", + "adomain": [ + "sonobi.com" + ], + "cid": "house", + "crid": "sandbox", + "h": 1, + "w": 1 + } + ], + "seat": "sonobi" + } + ], + "bidid": "sandbox_642305097", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "1", + "impid": "some-impression-id", + "price": 2.8649999999999998, + "adm": "", + "adomain": [ + "sonobi.com" + ], + "cid": "house", + "crid": "sandbox", + "h": 1, + "w": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/sovrn/sovrn.go b/adapters/sovrn/sovrn.go index 83ab136c963..ea28891883d 100644 --- a/adapters/sovrn/sovrn.go +++ b/adapters/sovrn/sovrn.go @@ -8,10 +8,11 @@ import ( "strconv" "strings" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" "github.com/prebid/openrtb/v20/openrtb2" ) @@ -50,7 +51,7 @@ func (s *SovrnAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapt for _, imp := range request.Imp { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { errs = append(errs, &errortypes.BadInput{ Message: err.Error(), }) @@ -58,7 +59,7 @@ func (s *SovrnAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapt } var sovrnExt openrtb_ext.ExtImpSovrn - if err := json.Unmarshal(bidderExt.Bidder, &sovrnExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &sovrnExt); err != nil { errs = append(errs, &errortypes.BadInput{ Message: err.Error(), }) @@ -154,7 +155,7 @@ func (s *SovrnAdapter) MakeBids(request *openrtb2.BidRequest, bidderRequest *ada } var bidResponse openrtb2.BidResponse - if err := json.Unmarshal(bidderResponse.Body, &bidResponse); err != nil { + if err := jsonutil.Unmarshal(bidderResponse.Body, &bidResponse); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: err.Error(), }} diff --git a/adapters/sovrn/sovrn_test.go b/adapters/sovrn/sovrn_test.go index 1e041933e6c..f2d61d166e2 100644 --- a/adapters/sovrn/sovrn_test.go +++ b/adapters/sovrn/sovrn_test.go @@ -3,9 +3,9 @@ package sovrn import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/sovrnXsp/params_test.go b/adapters/sovrnXsp/params_test.go index cca8b22cf51..91d31ec54dc 100644 --- a/adapters/sovrnXsp/params_test.go +++ b/adapters/sovrnXsp/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/sovrnXsp/sovrnXsp.go b/adapters/sovrnXsp/sovrnXsp.go index ed97697e824..7dc90adfd7f 100644 --- a/adapters/sovrnXsp/sovrnXsp.go +++ b/adapters/sovrnXsp/sovrnXsp.go @@ -5,10 +5,11 @@ import ( "fmt" "net/http" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" "github.com/prebid/openrtb/v20/openrtb2" ) @@ -49,7 +50,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte } var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { err = &errortypes.BadInput{ Message: fmt.Sprintf("imp #%d: ext.bidder not provided", idx), } @@ -58,7 +59,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte } var xspExt openrtb_ext.ExtImpSovrnXsp - if err := json.Unmarshal(bidderExt.Bidder, &xspExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &xspExt); err != nil { err = &errortypes.BadInput{ Message: fmt.Sprintf("imp #%d: %s", idx, err.Error()), } @@ -111,7 +112,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } @@ -122,7 +123,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R for _, bid := range seatBid.Bid { bid := bid var ext bidExt - if err := json.Unmarshal(bid.Ext, &ext); err != nil { + if err := jsonutil.Unmarshal(bid.Ext, &ext); err != nil { errors = append(errors, err) continue } diff --git a/adapters/sovrnXsp/sovrnXsp_test.go b/adapters/sovrnXsp/sovrnXsp_test.go index 4c93fc39fa8..3a82e29a54c 100644 --- a/adapters/sovrnXsp/sovrnXsp_test.go +++ b/adapters/sovrnXsp/sovrnXsp_test.go @@ -3,9 +3,9 @@ package sovrnXsp import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/sspBC/sspbc.go b/adapters/sspBC/sspbc.go index 59dffbdfbea..ae7d5f40e14 100644 --- a/adapters/sspBC/sspbc.go +++ b/adapters/sspBC/sspbc.go @@ -11,10 +11,11 @@ import ( "strings" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) const ( @@ -147,7 +148,7 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest } var response openrtb2.BidResponse - if err := json.Unmarshal(externalResponse.Body, &response); err != nil { + if err := jsonutil.Unmarshal(externalResponse.Body, &response); err != nil { return nil, []error{err} } @@ -192,7 +193,7 @@ func (a *adapter) impToBid(internalRequest *openrtb2.BidRequest, seatBid openrtb // read additional data from proxy var bidDataExt responseExt - if err := json.Unmarshal(bid.Ext, &bidDataExt); err != nil { + if err := jsonutil.Unmarshal(bid.Ext, &bidDataExt); err != nil { return err } /* @@ -289,8 +290,8 @@ func getBidParameters(imp openrtb2.Imp) openrtb_ext.ExtImpSspbc { var extBidder adapters.ExtImpBidder var extSSP openrtb_ext.ExtImpSspbc - if err := json.Unmarshal(imp.Ext, &extBidder); err == nil { - _ = json.Unmarshal(extBidder.Bidder, &extSSP) + if err := jsonutil.Unmarshal(imp.Ext, &extBidder); err == nil { + _ = jsonutil.Unmarshal(extBidder.Bidder, &extSSP) } return extSSP diff --git a/adapters/sspBC/sspbc_test.go b/adapters/sspBC/sspbc_test.go index 3c1f931bfb3..2d709f4c463 100644 --- a/adapters/sspBC/sspbc_test.go +++ b/adapters/sspBC/sspbc_test.go @@ -3,9 +3,9 @@ package sspBC import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/sspBC/sspbctest/supplemental/bad_response.json b/adapters/sspBC/sspbctest/supplemental/bad_response.json index 7859596d2f6..14f7d4ddb11 100644 --- a/adapters/sspBC/sspbctest/supplemental/bad_response.json +++ b/adapters/sspBC/sspbctest/supplemental/bad_response.json @@ -93,7 +93,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/stroeerCore/params_test.go b/adapters/stroeerCore/params_test.go index ac8075c2251..4050a219599 100644 --- a/adapters/stroeerCore/params_test.go +++ b/adapters/stroeerCore/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/stroeerCore/stroeercore.go b/adapters/stroeerCore/stroeercore.go index 4975c32e3b3..1d503726eb3 100644 --- a/adapters/stroeerCore/stroeercore.go +++ b/adapters/stroeerCore/stroeercore.go @@ -7,10 +7,11 @@ import ( "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -59,7 +60,7 @@ func (a *adapter) MakeBids(bidRequest *openrtb2.BidRequest, requestData *adapter var errors []error stroeerResponse := response{} - if err := json.Unmarshal(responseData.Body, &stroeerResponse); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &stroeerResponse); err != nil { errors = append(errors, err) return nil, errors } @@ -111,13 +112,13 @@ func (a *adapter) MakeRequests(bidRequest *openrtb2.BidRequest, extraRequestInfo for idx := range bidRequest.Imp { imp := &bidRequest.Imp[idx] var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { errors = append(errors, err) continue } var stroeerExt openrtb_ext.ExtImpStroeerCore - if err := json.Unmarshal(bidderExt.Bidder, &stroeerExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &stroeerExt); err != nil { errors = append(errors, err) continue } diff --git a/adapters/stroeerCore/stroeercore_test.go b/adapters/stroeerCore/stroeercore_test.go index 153f3137c07..b0f6204880c 100644 --- a/adapters/stroeerCore/stroeercore_test.go +++ b/adapters/stroeerCore/stroeercore_test.go @@ -3,9 +3,9 @@ package stroeerCore import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/taboola/params_test.go b/adapters/taboola/params_test.go index adcaa0334f7..8018c4b9d97 100644 --- a/adapters/taboola/params_test.go +++ b/adapters/taboola/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/taboola/taboola.go b/adapters/taboola/taboola.go index 9d950bef2cb..a11fbf6ce73 100644 --- a/adapters/taboola/taboola.go +++ b/adapters/taboola/taboola.go @@ -11,11 +11,12 @@ import ( "github.com/prebid/openrtb/v20/adcom1" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -86,7 +87,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } @@ -131,7 +132,14 @@ func (a *adapter) buildRequest(request *openrtb2.BidRequest) (*adapters.RequestD return nil, fmt.Errorf("unsupported media type for imp: %v", request.Imp[0]) } - url, err := a.buildEndpointURL(request.Site.ID, mediaType) + var taboolaPublisherId string + if request.Site != nil && request.Site.ID != "" { + taboolaPublisherId = request.Site.ID + } else if request.App != nil && request.App.ID != "" { + taboolaPublisherId = request.App.ID + } + + url, err := a.buildEndpointURL(taboolaPublisherId, mediaType) if err != nil { return nil, err } @@ -167,11 +175,11 @@ func createTaboolaRequests(request *openrtb2.BidRequest) (taboolaRequests []*ope imp := modifiedRequest.Imp[i] var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { errs = append(errs, err) continue } - if err := json.Unmarshal(bidderExt.Bidder, &taboolaExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &taboolaExt); err != nil { errs = append(errs, err) continue } @@ -207,22 +215,20 @@ func createTaboolaRequests(request *openrtb2.BidRequest) (taboolaRequests []*ope ID: taboolaExt.PublisherId, } - if modifiedRequest.Site == nil { - newSite := &openrtb2.Site{ - ID: taboolaExt.PublisherId, - Name: taboolaExt.PublisherId, - Domain: evaluateDomain(taboolaExt.PublisherDomain, request), - Publisher: publisher, - } - modifiedRequest.Site = newSite - } else { + if modifiedRequest.Site != nil { modifiedSite := *modifiedRequest.Site - modifiedSite.Publisher = publisher modifiedSite.ID = taboolaExt.PublisherId modifiedSite.Name = taboolaExt.PublisherId modifiedSite.Domain = evaluateDomain(taboolaExt.PublisherDomain, request) + modifiedSite.Publisher = publisher modifiedRequest.Site = &modifiedSite } + if modifiedRequest.App != nil { + modifiedApp := *modifiedRequest.App + modifiedApp.ID = taboolaExt.PublisherId + modifiedApp.Publisher = publisher + modifiedRequest.App = &modifiedApp + } if taboolaExt.BCat != nil { modifiedRequest.BCat = taboolaExt.BCat diff --git a/adapters/taboola/taboola_test.go b/adapters/taboola/taboola_test.go index bd674440150..082e480943e 100644 --- a/adapters/taboola/taboola_test.go +++ b/adapters/taboola/taboola_test.go @@ -3,9 +3,9 @@ package taboola import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/taboola/taboolatest/supplemental/emptySiteInRequest.json b/adapters/taboola/taboolatest/exemplary/bannerAppRequest.json similarity index 93% rename from adapters/taboola/taboolatest/supplemental/emptySiteInRequest.json rename to adapters/taboola/taboolatest/exemplary/bannerAppRequest.json index 3245290f756..34322399a00 100644 --- a/adapters/taboola/taboolatest/supplemental/emptySiteInRequest.json +++ b/adapters/taboola/taboolatest/exemplary/bannerAppRequest.json @@ -23,13 +23,14 @@ "ext": { "bidder": { "publisherId": "publisher-id", - "tagid": "tag-id" + "tagid": "tag-id", + "tagId": "tag-Id" } } } ], "app": { - "domain": "http://domain.com" + "bundle": "com.app.my" }, "device": { "ua": "Mozilla/5.0 (Linux; Android 12; Pixel 6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.62 Mobile Safari/537.36", @@ -62,21 +63,19 @@ } ] }, - "tagid" : "tag-id", + "tagid" : "tag-Id", "ext": { "bidder": { "publisherId": "publisher-id", - "tagid": "tag-id" + "tagid": "tag-id", + "tagId": "tag-Id" } } } ], "app": { - "domain": "http://domain.com" - }, - "site": { "id": "publisher-id", - "name": "publisher-id", + "bundle": "com.app.my", "publisher": { "id": "publisher-id" } diff --git a/adapters/taboola/taboolatest/supplemental/noValidImpression.json b/adapters/taboola/taboolatest/supplemental/noValidImpression.json index 2ecf5594817..eb3ff2ec384 100644 --- a/adapters/taboola/taboolatest/supplemental/noValidImpression.json +++ b/adapters/taboola/taboolatest/supplemental/noValidImpression.json @@ -40,7 +40,7 @@ }, "expectedMakeRequestsErrors": [ { - "value": "json: cannot unmarshal number into Go struct field ImpExtTaboola.publisherId of type string", + "value": "cannot unmarshal openrtb_ext.ImpExtTaboola.PublisherId: expects \" or n, but found 1", "comparison": "literal" } ] diff --git a/adapters/tappx/params_test.go b/adapters/tappx/params_test.go index ddfcbeb021f..07b56bf80c8 100644 --- a/adapters/tappx/params_test.go +++ b/adapters/tappx/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/tappx/tappx.go b/adapters/tappx/tappx.go index e50a5089c1d..a0c6d9c7dd2 100644 --- a/adapters/tappx/tappx.go +++ b/adapters/tappx/tappx.go @@ -11,11 +11,12 @@ import ( "time" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) const TAPPX_BIDDER_VERSION = "1.5" @@ -57,13 +58,13 @@ func (a *TappxAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapt } var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(request.Imp[0].Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(request.Imp[0].Ext, &bidderExt); err != nil { return nil, []error{&errortypes.BadInput{ Message: "Error parsing bidderExt object", }} } var tappxExt openrtb_ext.ExtImpTappx - if err := json.Unmarshal(bidderExt.Bidder, &tappxExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &tappxExt); err != nil { return nil, []error{&errortypes.BadInput{ Message: "Error parsing tappxExt parameters", }} @@ -198,7 +199,7 @@ func (a *TappxAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRe } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } diff --git a/adapters/tappx/tappx_test.go b/adapters/tappx/tappx_test.go index 803dfa5bde2..bf4e4f9f17e 100644 --- a/adapters/tappx/tappx_test.go +++ b/adapters/tappx/tappx_test.go @@ -4,9 +4,9 @@ import ( "regexp" "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/adapters/teads/teads.go b/adapters/teads/teads.go index fbea4fcd96f..402392d1ccc 100644 --- a/adapters/teads/teads.go +++ b/adapters/teads/teads.go @@ -9,11 +9,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) // Builder builds a new instance of the Teads adapter for the given bidder with the given config. @@ -77,7 +78,7 @@ func updateImpObject(imps []openrtb2.Imp) error { } var defaultImpExt defaultBidderImpExtension - if err := json.Unmarshal(imp.Ext, &defaultImpExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &defaultImpExt); err != nil { return &errortypes.BadInput{ Message: "Error parsing Imp.Ext object", } @@ -136,7 +137,7 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, _ *adapters.Req } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } @@ -172,7 +173,7 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, _ *adapters.Req func getTeadsRendererFromBidExt(ext json.RawMessage) (*teadsBidExt, []error) { var bidExtTeads teadsBidExt - if err := json.Unmarshal(ext, &bidExtTeads); err != nil { + if err := jsonutil.Unmarshal(ext, &bidExtTeads); err != nil { return nil, []error{err} } if bidExtTeads.Prebid.Meta.RendererName == "" { diff --git a/adapters/teads/teads_test.go b/adapters/teads/teads_test.go index c9f807ace21..8499e6f1399 100644 --- a/adapters/teads/teads_test.go +++ b/adapters/teads/teads_test.go @@ -3,9 +3,9 @@ package teads import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/telaria/params_test.go b/adapters/telaria/params_test.go index 9e451ca091e..7b1dfe08546 100644 --- a/adapters/telaria/params_test.go +++ b/adapters/telaria/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/telaria/telaria.go b/adapters/telaria/telaria.go index 3658bfdf0b7..1805bfaea0a 100644 --- a/adapters/telaria/telaria.go +++ b/adapters/telaria/telaria.go @@ -7,10 +7,11 @@ import ( "strconv" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) const Endpoint = "https://ads.tremorhub.com/ad/rtb/prebid" @@ -99,7 +100,7 @@ func GetHeaders(request *openrtb2.BidRequest) *http.Header { // Checks the imp[i].ext object and returns a imp.ext object as per ExtImpTelaria format func (a *TelariaAdapter) FetchTelariaExtImpParams(imp *openrtb2.Imp) (*openrtb_ext.ExtImpTelaria, error) { var bidderExt adapters.ExtImpBidder - err := json.Unmarshal(imp.Ext, &bidderExt) + err := jsonutil.Unmarshal(imp.Ext, &bidderExt) if err != nil { err = &errortypes.BadInput{ @@ -110,7 +111,7 @@ func (a *TelariaAdapter) FetchTelariaExtImpParams(imp *openrtb2.Imp) (*openrtb_e } var telariaExt openrtb_ext.ExtImpTelaria - err = json.Unmarshal(bidderExt.Bidder, &telariaExt) + err = jsonutil.Unmarshal(bidderExt.Bidder, &telariaExt) if err != nil { return nil, err @@ -271,7 +272,7 @@ func (a *TelariaAdapter) MakeBids(internalRequest *openrtb2.BidRequest, external responseBody := response.Body var bidResp openrtb2.BidResponse - if err := json.Unmarshal(responseBody, &bidResp); err != nil { + if err := jsonutil.Unmarshal(responseBody, &bidResp); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: "Telaria: Bad Server Response", }} diff --git a/adapters/telaria/telaria_test.go b/adapters/telaria/telaria_test.go index 3c7d1bea46e..8c55e7b900c 100644 --- a/adapters/telaria/telaria_test.go +++ b/adapters/telaria/telaria_test.go @@ -3,9 +3,9 @@ package telaria import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/theadx/params_test.go b/adapters/theadx/params_test.go index c9e10e2f0be..09440b335c6 100644 --- a/adapters/theadx/params_test.go +++ b/adapters/theadx/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/theadx.json diff --git a/adapters/theadx/theadx.go b/adapters/theadx/theadx.go index 48af365f105..34b1e1a3b48 100644 --- a/adapters/theadx/theadx.go +++ b/adapters/theadx/theadx.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -52,7 +53,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte for _, imp := range request.Imp { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { errors = append(errors, &errortypes.BadInput{ Message: err.Error(), }) @@ -60,7 +61,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte } var theadxImpExt openrtb_ext.ExtImpTheadx - if err := json.Unmarshal(bidderExt.Bidder, &theadxImpExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &theadxImpExt); err != nil { errors = append(errors, &errortypes.BadInput{ Message: err.Error(), }) @@ -110,7 +111,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } @@ -137,7 +138,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) { if bid.Ext != nil { var bidExt openrtb_ext.ExtBid - err := json.Unmarshal(bid.Ext, &bidExt) + err := jsonutil.Unmarshal(bid.Ext, &bidExt) if err == nil && bidExt.Prebid != nil { return openrtb_ext.ParseBidType(string(bidExt.Prebid.Type)) } diff --git a/adapters/theadx/theadx_test.go b/adapters/theadx/theadx_test.go index e64126c6a10..a945bd15fee 100644 --- a/adapters/theadx/theadx_test.go +++ b/adapters/theadx/theadx_test.go @@ -3,9 +3,9 @@ package theadx import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/theadx/theadxtest/supplemental/unparsable-response.json b/adapters/theadx/theadxtest/supplemental/unparsable-response.json index db9c246e15a..fa74cfdc989 100644 --- a/adapters/theadx/theadxtest/supplemental/unparsable-response.json +++ b/adapters/theadx/theadxtest/supplemental/unparsable-response.json @@ -43,7 +43,7 @@ "expectedBidResponses": [], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/thetradedesk/params_test.go b/adapters/thetradedesk/params_test.go new file mode 100644 index 00000000000..05febe45fab --- /dev/null +++ b/adapters/thetradedesk/params_test.go @@ -0,0 +1,53 @@ +package thetradedesk + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v3/openrtb_ext" +) + +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schemas. %v", err) + } + + for _, validParam := range validParams { + if err := validator.Validate(openrtb_ext.BidderTheTradeDesk, json.RawMessage(validParam)); err != nil { + t.Errorf("Schema rejected TheTradeDesk params: %s", validParam) + } + } +} + +// TestInvalidParams makes sure that the TheTradeDesk schema rejects all the imp.ext fields we don't support. +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schemas. %v", err) + } + + for _, invalidParam := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderTheTradeDesk, json.RawMessage(invalidParam)); err == nil { + t.Errorf("Schema allowed unexpected params: %s", invalidParam) + } + } +} + +var validParams = []string{ + `{"publisherId": "123456"}`, + `{"publisherId": "pub-123456"}`, + `{"publisherId": "publisherIDAllString"}`, +} + +var invalidParams = []string{ + ``, + `null`, + `true`, + `5`, + `4.2`, + `[]`, + `{}`, + `{"publisherId": 123456}`, + `{"publisherId": 0}`, +} diff --git a/adapters/thetradedesk/thetradedesk.go b/adapters/thetradedesk/thetradedesk.go new file mode 100644 index 00000000000..0288b4bb097 --- /dev/null +++ b/adapters/thetradedesk/thetradedesk.go @@ -0,0 +1,197 @@ +package thetradedesk + +import ( + "encoding/json" + "errors" + "fmt" + "net/http" + "regexp" + "text/template" + + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" + + "github.com/prebid/openrtb/v20/openrtb2" +) + +const PREBID_INTEGRATION_TYPE = "1" + +type adapter struct { + bidderEndpoint string +} + +type ExtImpBidderTheTradeDesk struct { + adapters.ExtImpBidder +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + pubID, err := getPublisherId(request.Imp) + + if err != nil { + return nil, []error{err} + } + + modifiedImps := make([]openrtb2.Imp, 0, len(request.Imp)) + + for _, imp := range request.Imp { + + if imp.Banner != nil { + if len(imp.Banner.Format) > 0 { + firstFormat := imp.Banner.Format[0] + bannerCopy := *imp.Banner + bannerCopy.H = &firstFormat.H + bannerCopy.W = &firstFormat.W + imp.Banner = &bannerCopy + + } + } + + modifiedImps = append(modifiedImps, imp) + } + + request.Imp = modifiedImps + + if request.Site != nil { + siteCopy := *request.Site + if siteCopy.Publisher != nil { + publisherCopy := *siteCopy.Publisher + if pubID != "" { + publisherCopy.ID = pubID + } + siteCopy.Publisher = &publisherCopy + } else { + siteCopy.Publisher = &openrtb2.Publisher{ID: pubID} + } + request.Site = &siteCopy + } else if request.App != nil { + appCopy := *request.App + if appCopy.Publisher != nil { + publisherCopy := *appCopy.Publisher + if pubID != "" { + publisherCopy.ID = pubID + } + appCopy.Publisher = &publisherCopy + } else { + appCopy.Publisher = &openrtb2.Publisher{ID: pubID} + } + request.App = &appCopy + } + + errs := make([]error, 0, len(request.Imp)) + reqJSON, err := json.Marshal(request) + if err != nil { + errs = append(errs, err) + return nil, errs + } + + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + headers.Add("Accept", "application/json") + headers.Add("x-integration-type", PREBID_INTEGRATION_TYPE) + return []*adapters.RequestData{{ + Method: "POST", + Uri: a.bidderEndpoint, + Body: reqJSON, + Headers: headers, + ImpIDs: openrtb_ext.GetImpIDs(request.Imp), + }}, errs +} + +func getPublisherId(impressions []openrtb2.Imp) (string, error) { + for _, imp := range impressions { + + var bidderExt ExtImpBidderTheTradeDesk + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { + return "", err + } + + var ttdExt openrtb_ext.ExtImpTheTradeDesk + if err := jsonutil.Unmarshal(bidderExt.Bidder, &ttdExt); err != nil { + return "", err + } + + if ttdExt.PublisherId != "" { + return ttdExt.PublisherId, nil + } + } + return "", nil +} + +func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if adapters.IsResponseStatusCodeNoContent(response) { + return adapters.NewBidderResponse(), nil + } + + if err := adapters.CheckResponseStatusCodeForErrors(response); err != nil { + return nil, []error{err} + } + + var bidResponse openrtb2.BidResponse + if err := jsonutil.Unmarshal(response.Body, &bidResponse); err != nil { + return nil, []error{err} + } + + bidderResponse := adapters.NewBidderResponse() + bidderResponse.Currency = bidResponse.Cur + + for _, seatBid := range bidResponse.SeatBid { + for _, bid := range seatBid.Bid { + bid := bid + + bidType, err := getBidType(bid.MType) + + if err != nil { + return nil, []error{err} + } + + b := &adapters.TypedBid{ + Bid: &bid, + BidType: bidType, + } + bidderResponse.Bids = append(bidderResponse.Bids, b) + } + } + + return bidderResponse, nil +} + +func getBidType(markupType openrtb2.MarkupType) (openrtb_ext.BidType, error) { + switch markupType { + case openrtb2.MarkupBanner: + return openrtb_ext.BidTypeBanner, nil + case openrtb2.MarkupVideo: + return openrtb_ext.BidTypeVideo, nil + case openrtb2.MarkupNative: + return openrtb_ext.BidTypeNative, nil + default: + return "", fmt.Errorf("unsupported mtype: %d", markupType) + } +} + +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + template, err := template.New("endpointTemplate").Parse(config.Endpoint) + if err != nil { + return nil, fmt.Errorf("unable to parse endpoint url template: %v", err) + } + + if len(config.ExtraAdapterInfo) > 0 { + isValidEndpoint, err := regexp.Match("([a-z]+)$", []byte(config.ExtraAdapterInfo)) + if !isValidEndpoint || err != nil { + return nil, errors.New("ExtraAdapterInfo must be a simple string provided by TheTradeDesk") + } + } + + urlParams := macros.EndpointTemplateParams{SupplyId: config.ExtraAdapterInfo} + bidderEndpoint, err := macros.ResolveMacros(template, urlParams) + + if err != nil { + return nil, fmt.Errorf("unable to resolve endpoint macros: %v", err) + } + + return &adapter{ + bidderEndpoint: bidderEndpoint, + }, nil +} diff --git a/adapters/thetradedesk/thetradedesk_test.go b/adapters/thetradedesk/thetradedesk_test.go new file mode 100644 index 00000000000..658d812bcac --- /dev/null +++ b/adapters/thetradedesk/thetradedesk_test.go @@ -0,0 +1,385 @@ +package thetradedesk + +import ( + "encoding/json" + "net/http" + "testing" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/stretchr/testify/assert" +) + +func TestEndpointTemplateMalformed(t *testing.T) { + _, buildErr := Builder(openrtb_ext.BidderTheTradeDesk, config.Adapter{ + Endpoint: "{{Malformed}}"}, + config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + assert.Error(t, buildErr) +} + +func TestBadConfig(t *testing.T) { + _, buildErr := Builder(openrtb_ext.BidderTheTradeDesk, config.Adapter{ + Endpoint: `http://it.doesnt.matter/bid`, + ExtraAdapterInfo: "12365217635", + }, + config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + assert.Error(t, buildErr) +} + +func TestCorrectConfig(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderTheTradeDesk, config.Adapter{ + Endpoint: `http://it.doesnt.matter/bid`, + ExtraAdapterInfo: `abcde`, + }, + config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + assert.NoError(t, buildErr) + assert.NotNil(t, bidder) +} + +func TestEmptyConfig(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderTheTradeDesk, config.Adapter{ + Endpoint: `https://direct.adsrvr.org/bid/bidder/{{.SupplyId}}`, + ExtraAdapterInfo: `ttd`, + }, + config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + assert.NoError(t, buildErr) + assert.NotNil(t, bidder) +} + +func TestJsonSamples(t *testing.T) { + bidder, err := Builder( + openrtb_ext.BidderTheTradeDesk, + config.Adapter{Endpoint: "https://direct.adsrvr.org/bid/bidder/{{.SupplyId}}", ExtraAdapterInfo: "ttd"}, + config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "1"}, + ) + assert.Nil(t, err) + adapterstest.RunJSONBidderTest(t, "thetradedesktest", bidder) +} + +func TestGetBidType(t *testing.T) { + type args struct { + markupType openrtb2.MarkupType + } + tests := []struct { + name string + args args + markupType openrtb2.MarkupType + expectedBidTypeId openrtb_ext.BidType + wantErr bool + }{ + { + name: "banner", + args: args{ + markupType: openrtb2.MarkupBanner, + }, + expectedBidTypeId: openrtb_ext.BidTypeBanner, + wantErr: false, + }, + { + name: "video", + args: args{ + markupType: openrtb2.MarkupVideo, + }, + expectedBidTypeId: openrtb_ext.BidTypeVideo, + wantErr: false, + }, + { + name: "native", + args: args{ + markupType: openrtb2.MarkupNative, + }, + expectedBidTypeId: openrtb_ext.BidTypeNative, + wantErr: false, + }, + { + name: "invalid", + args: args{ + markupType: -1, + }, + expectedBidTypeId: "", + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + bidType, err := getBidType(tt.args.markupType) + assert.Equal(t, tt.wantErr, err != nil) + assert.Equal(t, tt.expectedBidTypeId, bidType) + }) + } +} + +func TestGetPublisherId(t *testing.T) { + type args struct { + impressions []openrtb2.Imp + } + tests := []struct { + name string + args args + expectedPublisherId string + wantErr bool + }{ + { + name: "valid_publisher_Id", + args: args{ + impressions: []openrtb2.Imp{ + { + Video: &openrtb2.Video{}, + Ext: json.RawMessage(`{"bidder":{"publisherId":"1"}}`), + }, + }, + }, + expectedPublisherId: "1", + wantErr: false, + }, + { + name: "multiple_valid_publisher_Id", + args: args{ + impressions: []openrtb2.Imp{ + { + Video: &openrtb2.Video{}, + Ext: json.RawMessage(`{"bidder":{"publisherId":"1"}}`), + }, + { + Video: &openrtb2.Video{}, + Ext: json.RawMessage(`{"bidder":{"publisherId":"2"}}`), + }, + }, + }, + expectedPublisherId: "1", + wantErr: false, + }, + { + name: "not_publisherId_present", + args: args{ + impressions: []openrtb2.Imp{ + { + Video: &openrtb2.Video{}, + Ext: json.RawMessage(`{"bidder":{}}`), + }, + }, + }, + expectedPublisherId: "", + wantErr: false, + }, + { + name: "nil_publisherId_present", + args: args{ + impressions: []openrtb2.Imp{ + { + Video: &openrtb2.Video{}, + Ext: json.RawMessage(`{"bidder":{"publisherId":""}}`), + }, + }, + }, + expectedPublisherId: "", + wantErr: false, + }, + { + name: "no_impressions", + args: args{ + impressions: []openrtb2.Imp{}, + }, + expectedPublisherId: "", + wantErr: false, + }, + { + name: "invalid_bidder_object", + args: args{ + impressions: []openrtb2.Imp{ + { + Video: &openrtb2.Video{}, + Ext: json.RawMessage(`{"bidder":{"doesnotexistprop":""}}`), + }, + }, + }, + expectedPublisherId: "", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + publisherId, err := getPublisherId(tt.args.impressions) + assert.Equal(t, tt.wantErr, err != nil) + assert.Equal(t, tt.expectedPublisherId, publisherId) + }) + } +} + +func TestTheTradeDeskAdapter_MakeRequests(t *testing.T) { + type fields struct { + URI string + } + type args struct { + request *openrtb2.BidRequest + reqInfo *adapters.ExtraRequestInfo + } + tests := []struct { + name string + fields fields + args args + expectedReqData []*adapters.RequestData + wantErr bool + }{ + { + name: "invalid_bidderparams", + args: args{ + request: &openrtb2.BidRequest{Ext: json.RawMessage(`{"prebid":{"bidderparams":{:"123"}}}`)}, + }, + wantErr: true, + }, + { + name: "request_with_App", + args: args{ + request: &openrtb2.BidRequest{ + App: &openrtb2.App{}, + Ext: json.RawMessage(`{"prebid":{"bidderparams":{"wrapper":"123"}}}`), + }, + }, + wantErr: false, + }, + { + name: "request_with_App_and_publisher", + args: args{ + request: &openrtb2.BidRequest{ + App: &openrtb2.App{Publisher: &openrtb2.Publisher{}}, + Ext: json.RawMessage(`{"prebid":{"bidderparams":{"wrapper":"123"}}}`), + }, + }, + wantErr: false, + }, + { + name: "request_with_Site", + args: args{ + request: &openrtb2.BidRequest{ + Site: &openrtb2.Site{}, + Ext: json.RawMessage(`{"prebid":{"bidderparams":{"wrapper":"123"}}}`), + }, + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + a := &adapter{ + bidderEndpoint: tt.fields.URI, + } + gotReqData, gotErr := a.MakeRequests(tt.args.request, tt.args.reqInfo) + assert.Equal(t, tt.wantErr, len(gotErr) != 0) + if tt.wantErr == false { + assert.NotNil(t, gotReqData) + } + }) + } +} + +func TestTheTradeDeskAdapter_MakeBids(t *testing.T) { + type fields struct { + URI string + } + type args struct { + internalRequest *openrtb2.BidRequest + externalRequest *adapters.RequestData + response *adapters.ResponseData + } + tests := []struct { + name string + fields fields + args args + wantErr []error + wantResp *adapters.BidderResponse + }{ + { + name: "happy_path_valid_response_with_all_bid_params", + args: args{ + response: &adapters.ResponseData{ + StatusCode: http.StatusOK, + Body: []byte(`{"id": "test-request-id", "seatbid":[{"seat": "958", "bid":[{"mtype": 1, "id": "7706636740145184841", "impid": "test-imp-id", "price": 0.500000, "adid": "29681110", "adm": "some-test-ad", "adomain":["ttd.com"], "crid": "29681110", "h": 250, "w": 300, "dealid": "testdeal", "ext":{"dspid": 6, "deal_channel": 1, "prebiddealpriority": 1}}]}], "bidid": "5778926625248726496", "cur": "USD"}`), + }, + }, + wantErr: nil, + wantResp: &adapters.BidderResponse{ + Bids: []*adapters.TypedBid{ + { + Bid: &openrtb2.Bid{ + ID: "7706636740145184841", + ImpID: "test-imp-id", + Price: 0.500000, + AdID: "29681110", + AdM: "some-test-ad", + ADomain: []string{"ttd.com"}, + CrID: "29681110", + H: 250, + W: 300, + DealID: "testdeal", + Ext: json.RawMessage(`{"dspid": 6, "deal_channel": 1, "prebiddealpriority": 1}`), + MType: openrtb2.MarkupBanner, + }, + BidType: openrtb_ext.BidTypeBanner, + }, + }, + Currency: "USD", + }, + }, + { + name: "ignore_invalid_prebiddealpriority", + args: args{ + response: &adapters.ResponseData{ + StatusCode: http.StatusOK, + Body: []byte(`{"id": "test-request-id", "seatbid":[{"seat": "958", "bid":[{"mtype": 2, "id": "7706636740145184841", "impid": "test-imp-id", "price": 0.500000, "adid": "29681110", "adm": "some-test-ad", "adomain":["ttd.com"], "crid": "29681110", "h": 250, "w": 300, "dealid": "testdeal", "ext":{"dspid": 6, "deal_channel": 1, "prebiddealpriority": -1}}]}], "bidid": "5778926625248726496", "cur": "USD"}`), + }, + }, + wantErr: nil, + wantResp: &adapters.BidderResponse{ + Bids: []*adapters.TypedBid{ + { + Bid: &openrtb2.Bid{ + ID: "7706636740145184841", + ImpID: "test-imp-id", + Price: 0.500000, + AdID: "29681110", + AdM: "some-test-ad", + ADomain: []string{"ttd.com"}, + CrID: "29681110", + H: 250, + W: 300, + DealID: "testdeal", + Ext: json.RawMessage(`{"dspid": 6, "deal_channel": 1, "prebiddealpriority": -1}`), + MType: openrtb2.MarkupVideo, + }, + BidType: openrtb_ext.BidTypeVideo, + }, + }, + Currency: "USD", + }, + }, + { + name: "no_content_response", + args: args{ + response: &adapters.ResponseData{ + StatusCode: http.StatusNoContent, + Body: nil, + }, + }, + wantErr: nil, + wantResp: adapters.NewBidderResponse(), + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + a := &adapter{ + bidderEndpoint: tt.fields.URI, + } + gotResp, gotErr := a.MakeBids(tt.args.internalRequest, tt.args.externalRequest, tt.args.response) + assert.Equal(t, tt.wantErr, gotErr, gotErr) + assert.Equal(t, tt.wantResp, gotResp) + }) + } +} diff --git a/adapters/thetradedesk/thetradedesktest/exemplary/simple-banner-inapp.json b/adapters/thetradedesk/thetradedesktest/exemplary/simple-banner-inapp.json new file mode 100644 index 00000000000..e10445382c8 --- /dev/null +++ b/adapters/thetradedesk/thetradedesktest/exemplary/simple-banner-inapp.json @@ -0,0 +1,144 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "bundle": "test.app.bundle", + "publisher": { + "id": "this_id_will_be_replaced" + } + }, + "device": { + "ifa": "test-ifa-123456", + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 100, + "h": 150 + }, + "ext": { + "bidder": { + "publisherId": "123456" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://direct.adsrvr.org/bid/bidder/ttd", + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Integration-Type": ["1"] + }, + "body": { + "id": "test-request-id", + "app": { + "bundle": "test.app.bundle", + "publisher": { + "id": "123456" + } + }, + "device": { + "ifa": "test-ifa-123456", + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "publisherId": "123456" + } + } + } + ] + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "currency": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner", + "networkName": "TheTradeDesk" + } + }, + "mtype": 1 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner", + "networkName": "TheTradeDesk" + } + }, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} + diff --git a/adapters/thetradedesk/thetradedesktest/exemplary/simple-banner-multiple-bids-and-formats.json b/adapters/thetradedesk/thetradedesktest/exemplary/simple-banner-multiple-bids-and-formats.json new file mode 100644 index 00000000000..0180d48dde2 --- /dev/null +++ b/adapters/thetradedesk/thetradedesktest/exemplary/simple-banner-multiple-bids-and-formats.json @@ -0,0 +1,231 @@ +{ + "mockBidRequest": { + "id": "test-request-id-multiple-bids", + "site": { + "id": "site-id", + "page": "ttd.com", + "publisher": { + "id": "123456" + } + }, + "device": { + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 500, + "h": 300 + } + ], + "w": 55, + "h": 33 + }, + "ext": { + "bidder": { + "publisherId": "123456" + } + } + }, + { + "id": "test-imp-id2", + "banner": { + "format": [ + { + "w": 900, + "h": 450 + }, + { + "w": 500, + "h": 300 + } + ], + "w": 88, + "h": 99 + }, + "ext": { + "bidder": { + "publisherId": "123456" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://direct.adsrvr.org/bid/bidder/ttd", + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Integration-Type": ["1"] + }, + "body": { + "id": "test-request-id-multiple-bids", + "site": { + "id": "site-id", + "page": "ttd.com", + "publisher": { + "id": "123456" + } + }, + "device": { + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 500, + "h": 300 + } + ], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "publisherId": "123456" + } + } + }, + { + "id": "test-imp-id2", + "banner": { + "format": [ + { + "w": 900, + "h": 450 + }, + { + "w": 500, + "h": 300 + } + ], + "w": 900, + "h": 450 + }, + "ext": { + "bidder": { + "publisherId": "123456" + } + } + } + ] + }, + "impIDs":["test-imp-id","test-imp-id2"] + }, + "mockResponse": { + "status": 200, + "body": { + "currency": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + }, + "mtype": 1 + } + ] + }, + { + "bid": [ + { + "id": "test-slot-id2", + "impid": "test-imp-id2", + "price": 0.5, + "crid": "creative-123", + "adm": "", + "w": 900, + "h": 450, + "ext": { + "prebid": { + "type": "banner" + } + }, + "mtype": 1 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + }, + "mtype": 1 + }, + "type": "banner" + }, + { + "bid": { + "id": "test-slot-id2", + "impid": "test-imp-id2", + "price": 0.5, + "crid": "creative-123", + "adm": "", + "w": 900, + "h": 450, + "ext": { + "prebid": { + "type": "banner" + } + }, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} + diff --git a/adapters/thetradedesk/thetradedesktest/exemplary/simple-banner-multiple-bids.json b/adapters/thetradedesk/thetradedesktest/exemplary/simple-banner-multiple-bids.json new file mode 100644 index 00000000000..4d46fa6907b --- /dev/null +++ b/adapters/thetradedesk/thetradedesktest/exemplary/simple-banner-multiple-bids.json @@ -0,0 +1,215 @@ +{ + "mockBidRequest": { + "id": "test-request-id-multiple-bids", + "site": { + "id": "site-id", + "page": "ttd.com", + "publisher": { + "id": "123456" + } + }, + "device": { + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "publisherId": "123456" + } + } + }, + { + "id": "test-imp-id2", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "publisherId": "123456" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://direct.adsrvr.org/bid/bidder/ttd", + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Integration-Type": ["1"] + }, + "body": { + "id": "test-request-id-multiple-bids", + "site": { + "id": "site-id", + "page": "ttd.com", + "publisher": { + "id": "123456" + } + }, + "device": { + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "publisherId": "123456" + } + } + }, + { + "id": "test-imp-id2", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "publisherId": "123456" + } + } + } + ] + }, + "impIDs":["test-imp-id","test-imp-id2"] + }, + "mockResponse": { + "status": 200, + "body": { + "currency": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + }, + "mtype": 1 + } + ] + }, + { + "bid": [ + { + "id": "test-slot-id2", + "impid": "test-imp-id2", + "price": 0.5, + "crid": "creative-123", + "adm": "", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + }, + "mtype": 1 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + }, + "mtype": 1 + }, + "type": "banner" + }, + { + "bid": { + "id": "test-slot-id2", + "impid": "test-imp-id2", + "price": 0.5, + "crid": "creative-123", + "adm": "", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + }, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} + diff --git a/adapters/thetradedesk/thetradedesktest/exemplary/simple-banner.json b/adapters/thetradedesk/thetradedesktest/exemplary/simple-banner.json new file mode 100644 index 00000000000..4ac6acb0556 --- /dev/null +++ b/adapters/thetradedesk/thetradedesktest/exemplary/simple-banner.json @@ -0,0 +1,142 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "ttd.com", + "publisher": { + "id": "123456" + } + }, + "device": { + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 100, + "h": 150 + }, + "ext": { + "bidder": { + "publisherId": "123456" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://direct.adsrvr.org/bid/bidder/ttd", + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Integration-Type": ["1"] + }, + "body": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "ttd.com", + "publisher": { + "id": "123456" + } + }, + "device": { + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "publisherId": "123456" + } + } + } + ] + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "currency": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + }, + "mtype": 1 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + }, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} + diff --git a/adapters/thetradedesk/thetradedesktest/exemplary/simple-empty-publisherId.json b/adapters/thetradedesk/thetradedesktest/exemplary/simple-empty-publisherId.json new file mode 100644 index 00000000000..ef6f6695553 --- /dev/null +++ b/adapters/thetradedesk/thetradedesktest/exemplary/simple-empty-publisherId.json @@ -0,0 +1,142 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "ttd.com", + "publisher": { + "id": "did_not_override" + } + }, + "device": { + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "publisherId": "" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://direct.adsrvr.org/bid/bidder/ttd", + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Integration-Type": ["1"] + }, + "body": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "ttd.com", + "publisher": { + "id": "did_not_override" + } + }, + "device": { + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "publisherId": "" + } + } + } + ] + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "currency": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + }, + "mtype": 1 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + }, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} + diff --git a/adapters/thetradedesk/thetradedesktest/exemplary/simple-multi-type-banner.json b/adapters/thetradedesk/thetradedesktest/exemplary/simple-multi-type-banner.json new file mode 100644 index 00000000000..10286c96081 --- /dev/null +++ b/adapters/thetradedesk/thetradedesktest/exemplary/simple-multi-type-banner.json @@ -0,0 +1,151 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "ttd.com" + }, + "device": { + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 300, + "h": 250 + }, + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "publisherId": "123456" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://direct.adsrvr.org/bid/bidder/ttd", + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Integration-Type": ["1"] + }, + "body": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "ttd.com", + "publisher": { + "id": "123456" + } + }, + "device": { + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 300, + "h": 250 + }, + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "publisherId": "123456" + } + } + } + ] + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "currency": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "", + "h": 250, + "w": 300, + "ext": { + "prebid": { + "type": "banner" + } + }, + "mtype": 1 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "", + "h": 250, + "w": 300, + "ext": { + "prebid": { + "type": "banner" + } + }, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} + diff --git a/adapters/thetradedesk/thetradedesktest/exemplary/simple-multi-type-video.json b/adapters/thetradedesk/thetradedesktest/exemplary/simple-multi-type-video.json new file mode 100644 index 00000000000..e8f4bbca57c --- /dev/null +++ b/adapters/thetradedesk/thetradedesktest/exemplary/simple-multi-type-video.json @@ -0,0 +1,151 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "ttd.com" + }, + "device": { + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 300, + "h": 250 + }, + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "publisherId": "123456" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://direct.adsrvr.org/bid/bidder/ttd", + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Integration-Type": ["1"] + }, + "body": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "ttd.com", + "publisher": { + "id": "123456" + } + }, + "device": { + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": ["video/mp4"], + "protocols": [2, 5], + "w": 300, + "h": 250 + }, + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "publisherId": "123456" + } + } + } + ] + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "currency": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "some-test-ad-vast", + "h": 250, + "w": 300, + "ext": { + "prebid": { + "type": "video" + } + }, + "mtype": 2 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "some-test-ad-vast", + "h": 250, + "w": 300, + "ext": { + "prebid": { + "type": "video" + } + }, + "mtype": 2 + }, + "type": "video" + } + ] + } + ] +} + diff --git a/adapters/thetradedesk/thetradedesktest/exemplary/simple-native.json b/adapters/thetradedesk/thetradedesktest/exemplary/simple-native.json new file mode 100644 index 00000000000..4d1b77ab0fb --- /dev/null +++ b/adapters/thetradedesk/thetradedesktest/exemplary/simple-native.json @@ -0,0 +1,115 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "ttd.com" + }, + "imp": [ + { + "id": "test-imp-id", + "native": { + "request": "" + }, + "ext": { + "bidder": { + "publisherId": "123456" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://direct.adsrvr.org/bid/bidder/ttd", + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Integration-Type": ["1"] + }, + "body": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "ttd.com", + "publisher": { + "id": "123456" + } + }, + "imp": [ + { + "id": "test-imp-id", + "native": { + "request": "" + }, + "ext": { + "bidder": { + "publisherId": "123456" + } + } + } + ] + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "currency": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "", + "h": 250, + "w": 300, + "ext": { + "prebid": { + "type": "native" + } + }, + "mtype": 4 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "", + "h": 250, + "w": 300, + "ext": { + "prebid": { + "type": "native" + } + }, + "mtype": 4 + }, + "type": "native" + } + ] + } + ] +} + diff --git a/adapters/thetradedesk/thetradedesktest/exemplary/simple-video.json b/adapters/thetradedesk/thetradedesktest/exemplary/simple-video.json new file mode 100644 index 00000000000..5dc945bab1f --- /dev/null +++ b/adapters/thetradedesk/thetradedesktest/exemplary/simple-video.json @@ -0,0 +1,154 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "ttd.com" + }, + "device": { + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "pbs-local/preroll", + "video": { + "minduration": 0, + "maxduration": 60, + "api": [1,2], + "mimes": [ + "video/mp4", + "video/webm", + "application/javascript" + ], + "placement": 1, + "protocols": [2,3,4,5,6], + "w": 300, + "h": 250, + "playbackmethod": [1,2,3,4,5,6], + "plcmt": 1, + "skip": 1 + }, + "ext": { + "bidder": { + "publisherId": "123456" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://direct.adsrvr.org/bid/bidder/ttd", + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Integration-Type": ["1"] + }, + "body": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "ttd.com", + "publisher": { + "id": "123456" + } + }, + "device": { + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "imp": [ + { + "id": "test-imp-id", + "tagid": "pbs-local/preroll", + "video": { + "maxduration": 60, + "api": [1,2], + "mimes": [ + "video/mp4", + "video/webm", + "application/javascript" + ], + "placement": 1, + "protocols": [2,3,4,5,6], + "w": 300, + "h": 250, + "playbackmethod": [1,2,3,4,5,6], + "plcmt": 1, + "skip": 1 + }, + "ext": { + "bidder": { + "publisherId": "123456" + } + } + } + ] + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "currency": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "some-test-ad-vast", + "h": 250, + "w": 300, + "ext": { + "prebid": { + "type": "video" + } + }, + "mtype": 2 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "some-test-ad-vast", + "h": 250, + "w": 300, + "ext": { + "prebid": { + "type": "video" + } + }, + "mtype": 2 + }, + "type": "video" + } + ] + } + ] +} + diff --git a/adapters/thetradedesk/thetradedesktest/supplemental/200-response-from-target.json b/adapters/thetradedesk/thetradedesktest/supplemental/200-response-from-target.json new file mode 100644 index 00000000000..fdbe15ac48e --- /dev/null +++ b/adapters/thetradedesk/thetradedesktest/supplemental/200-response-from-target.json @@ -0,0 +1,105 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "bundle": "test.app.bundle" + }, + "device": { + "ifa": "test-ifa-123456", + "ip": "91.199.242.236", + "ua": "random user agent", + "os": "android" + }, + "regs": { + "ext": { + "us_privacy": "1YYY" + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "publisherId": "123456" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://direct.adsrvr.org/bid/bidder/ttd", + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Integration-Type": ["1"] + }, + "body": { + "id": "test-request-id", + "app": { + "bundle": "test.app.bundle", + "publisher": { + "id": "123456" + } + }, + "device": { + "ifa": "test-ifa-123456", + "ip": "91.199.242.236", + "ua": "random user agent", + "os": "android" + }, + "regs": { + "ext": { + "us_privacy": "1YYY" + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "publisherId": "123456" + } + } + } + ] + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200 + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "expect { or n, but found", + "comparison": "startswith" + } + ] + } diff --git a/adapters/thetradedesk/thetradedesktest/supplemental/204-response-from-target.json b/adapters/thetradedesk/thetradedesktest/supplemental/204-response-from-target.json new file mode 100644 index 00000000000..a329982ea50 --- /dev/null +++ b/adapters/thetradedesk/thetradedesktest/supplemental/204-response-from-target.json @@ -0,0 +1,105 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "bundle": "test.app.bundle" + }, + "device": { + "ifa": "test-ifa-123456", + "ip": "91.199.242.236", + "ua": "random user agent", + "os": "android" + }, + "regs": { + "ext": { + "us_privacy": "1YYY" + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "publisherId": "123456" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://direct.adsrvr.org/bid/bidder/ttd", + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Integration-Type": ["1"] + }, + "body": { + "id": "test-request-id", + "app": { + "bundle": "test.app.bundle", + "publisher": { + "id": "123456" + } + }, + "device": { + "ifa": "test-ifa-123456", + "ip": "91.199.242.236", + "ua": "random user agent", + "os": "android" + }, + "regs": { + "ext": { + "us_privacy": "1YYY" + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "publisherId": "123456" + } + } + } + ] + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 204 + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [] + } + ] + } diff --git a/adapters/thetradedesk/thetradedesktest/supplemental/400-response-from-target.json b/adapters/thetradedesk/thetradedesktest/supplemental/400-response-from-target.json new file mode 100644 index 00000000000..ad5ffc62b51 --- /dev/null +++ b/adapters/thetradedesk/thetradedesktest/supplemental/400-response-from-target.json @@ -0,0 +1,105 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "bundle": "test.app.bundle" + }, + "device": { + "ifa": "test-ifa-123456", + "ip": "91.199.242.236", + "ua": "random user agent", + "os": "android" + }, + "regs": { + "ext": { + "us_privacy": "1YYY" + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "publisherId": "123456" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://direct.adsrvr.org/bid/bidder/ttd", + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Integration-Type": ["1"] + }, + "body": { + "id": "test-request-id", + "app": { + "bundle": "test.app.bundle", + "publisher": { + "id": "123456" + } + }, + "device": { + "ifa": "test-ifa-123456", + "ip": "91.199.242.236", + "ua": "random user agent", + "os": "android" + }, + "regs": { + "ext": { + "us_privacy": "1YYY" + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "publisherId": "123456" + } + } + } + ] + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 400 + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] + } diff --git a/adapters/thetradedesk/thetradedesktest/supplemental/500-response-from-target.json b/adapters/thetradedesk/thetradedesktest/supplemental/500-response-from-target.json new file mode 100644 index 00000000000..f2ccb342113 --- /dev/null +++ b/adapters/thetradedesk/thetradedesktest/supplemental/500-response-from-target.json @@ -0,0 +1,105 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "bundle": "test.app.bundle" + }, + "device": { + "ifa": "test-ifa-123456", + "ip": "91.199.242.236", + "ua": "random user agent", + "os": "android" + }, + "regs": { + "ext": { + "us_privacy": "1YYY" + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "publisherId": "123456" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://direct.adsrvr.org/bid/bidder/ttd", + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Integration-Type": ["1"] + }, + "body": { + "id": "test-request-id", + "app": { + "bundle": "test.app.bundle", + "publisher": { + "id": "123456" + } + }, + "device": { + "ifa": "test-ifa-123456", + "ip": "91.199.242.236", + "ua": "random user agent", + "os": "android" + }, + "regs": { + "ext": { + "us_privacy": "1YYY" + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "publisherId": "123456" + } + } + } + ] + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 500 + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 500. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] + } diff --git a/adapters/thetradedesk/thetradedesktest/supplemental/invalid-mtype.json b/adapters/thetradedesk/thetradedesktest/supplemental/invalid-mtype.json new file mode 100644 index 00000000000..52b392eb835 --- /dev/null +++ b/adapters/thetradedesk/thetradedesktest/supplemental/invalid-mtype.json @@ -0,0 +1,86 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "native": { + "request": "" + }, + "ext": { + "bidder": { + "publisherId": "123456" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://direct.adsrvr.org/bid/bidder/ttd", + "headers": { + "Content-Type": [ + "application/json;charset=utf-8" + ], + "Accept": [ + "application/json" + ], + "X-Integration-Type": ["1"] + }, + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "native": { + "request": "" + }, + "ext": { + "bidder": { + "publisherId": "123456" + } + } + } + ] + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "currency": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "", + "h": 250, + "w": 300, + "ext": { + "prebid": { + "type": "native" + } + }, + "mtype": -1 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "unsupported mtype: -1", + "comparison": "literal" + } + ] +} + diff --git a/adapters/thetradedesk/thetradedesktest/supplemental/invalid-publisher.json b/adapters/thetradedesk/thetradedesktest/supplemental/invalid-publisher.json new file mode 100644 index 00000000000..9e2426d79b2 --- /dev/null +++ b/adapters/thetradedesk/thetradedesktest/supplemental/invalid-publisher.json @@ -0,0 +1,45 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "bundle": "test.app.bundle", + "publisher": { + "id": "this_id_will_be_replaced" + } + }, + "device": { + "ifa": "test-ifa-123456", + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ], + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "publisherId": 123456 + } + } + } + ] + }, + "httpCalls": [], + "expectedMakeRequestsErrors": [ + { + "value": "cannot unmarshal openrtb_ext.ExtImpTheTradeDesk.PublisherId: expects \" or n, but found 1", + "comparison": "literal" + } + ] +} + diff --git a/adapters/tpmn/params_test.go b/adapters/tpmn/params_test.go index 4715d910855..674da5fb65a 100644 --- a/adapters/tpmn/params_test.go +++ b/adapters/tpmn/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/tpmn/tpmn.go b/adapters/tpmn/tpmn.go index 77357866a6a..262fc28ac6e 100644 --- a/adapters/tpmn/tpmn.go +++ b/adapters/tpmn/tpmn.go @@ -7,9 +7,10 @@ import ( "strings" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) // TpmnAdapter struct @@ -83,7 +84,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, _ *adapters.RequestData } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{fmt.Errorf("bid response unmarshal: %v", err)} } diff --git a/adapters/tpmn/tpmn_test.go b/adapters/tpmn/tpmn_test.go index 7170dbb3d5f..865771e89ca 100644 --- a/adapters/tpmn/tpmn_test.go +++ b/adapters/tpmn/tpmn_test.go @@ -3,9 +3,9 @@ package tpmn import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/tpmn/tpmntest/supplemental/bad_response.json b/adapters/tpmn/tpmntest/supplemental/bad_response.json index 21ebfb968c7..c8096e9df2a 100644 --- a/adapters/tpmn/tpmntest/supplemental/bad_response.json +++ b/adapters/tpmn/tpmntest/supplemental/bad_response.json @@ -81,7 +81,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "bid response unmarshal: json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "bid response unmarshal: expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/tpmn/tpmntest/supplemental/no-imp-ext.json b/adapters/tpmn/tpmntest/supplemental/no-imp-ext.json index a22f0a16d12..9bb91e4c167 100644 --- a/adapters/tpmn/tpmntest/supplemental/no-imp-ext.json +++ b/adapters/tpmn/tpmntest/supplemental/no-imp-ext.json @@ -74,7 +74,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "bid response unmarshal: json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "bid response unmarshal: expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/trafficgate/params_test.go b/adapters/trafficgate/params_test.go index adc11c08335..0667a8bc5a1 100644 --- a/adapters/trafficgate/params_test.go +++ b/adapters/trafficgate/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // TestValidParams makes sure that the trafficgate schema accepts all imp.ext fields which we intend to support. diff --git a/adapters/trafficgate/trafficgate.go b/adapters/trafficgate/trafficgate.go index 24e8be20c6c..d4d181399dd 100644 --- a/adapters/trafficgate/trafficgate.go +++ b/adapters/trafficgate/trafficgate.go @@ -7,11 +7,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -91,7 +92,7 @@ func (a *adapter) MakeBids( var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: err.Error(), }} @@ -103,7 +104,7 @@ func (a *adapter) MakeBids( for _, seatBid := range bidResp.SeatBid { for i := range seatBid.Bid { var bidExt BidResponseExt - if err := json.Unmarshal(seatBid.Bid[i].Ext, &bidExt); err != nil { + if err := jsonutil.Unmarshal(seatBid.Bid[i].Ext, &bidExt); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: "Missing response ext", }} @@ -141,13 +142,13 @@ func splitImpressions(imps []openrtb2.Imp) (map[openrtb_ext.ExtImpTrafficGate][] func getBidderParams(imp *openrtb2.Imp) (*openrtb_ext.ExtImpTrafficGate, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: "Missing bidder ext", } } var TrafficGateExt openrtb_ext.ExtImpTrafficGate - if err := json.Unmarshal(bidderExt.Bidder, &TrafficGateExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &TrafficGateExt); err != nil { return nil, &errortypes.BadInput{ Message: "Bidder parameters required", } diff --git a/adapters/trafficgate/trafficgate_test.go b/adapters/trafficgate/trafficgate_test.go index 473c9d5d5c3..df932538d96 100644 --- a/adapters/trafficgate/trafficgate_test.go +++ b/adapters/trafficgate/trafficgate_test.go @@ -3,9 +3,9 @@ package trafficgate import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/trafficgate/trafficgatetest/supplemental/bad_response.json b/adapters/trafficgate/trafficgatetest/supplemental/bad_response.json index e4177fd79ea..64cccbf6905 100644 --- a/adapters/trafficgate/trafficgatetest/supplemental/bad_response.json +++ b/adapters/trafficgate/trafficgatetest/supplemental/bad_response.json @@ -81,7 +81,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/triplelift/triplelift.go b/adapters/triplelift/triplelift.go index 773048fc32e..c5d89cd2507 100644 --- a/adapters/triplelift/triplelift.go +++ b/adapters/triplelift/triplelift.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type TripleliftAdapter struct { @@ -36,10 +37,10 @@ func processImp(imp *openrtb2.Imp) error { // get the triplelift extension var ext adapters.ExtImpBidder var tlext openrtb_ext.ExtImpTriplelift - if err := json.Unmarshal(imp.Ext, &ext); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &ext); err != nil { return err } - if err := json.Unmarshal(ext.Bidder, &tlext); err != nil { + if err := jsonutil.Unmarshal(ext.Bidder, &tlext); err != nil { return err } if imp.Banner == nil && imp.Video == nil { @@ -118,7 +119,7 @@ func (a *TripleliftAdapter) MakeBids(internalRequest *openrtb2.BidRequest, exter return nil, []error{fmt.Errorf("Unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode)} } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } var errs []error @@ -129,7 +130,7 @@ func (a *TripleliftAdapter) MakeBids(internalRequest *openrtb2.BidRequest, exter for i := 0; i < len(sb.Bid); i++ { bid := sb.Bid[i] var bidExt TripleliftRespExt - if err := json.Unmarshal(bid.Ext, &bidExt); err != nil { + if err := jsonutil.Unmarshal(bid.Ext, &bidExt); err != nil { errs = append(errs, err) } else { bidType := getBidType(bidExt) diff --git a/adapters/triplelift/triplelift_test.go b/adapters/triplelift/triplelift_test.go index c4468a93faa..1fd5fc8d559 100644 --- a/adapters/triplelift/triplelift_test.go +++ b/adapters/triplelift/triplelift_test.go @@ -3,9 +3,9 @@ package triplelift import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/triplelift/triplelifttest/supplemental/badext.json b/adapters/triplelift/triplelifttest/supplemental/badext.json index a36454c86d8..7c4b8190faf 100644 --- a/adapters/triplelift/triplelifttest/supplemental/badext.json +++ b/adapters/triplelift/triplelifttest/supplemental/badext.json @@ -1,7 +1,7 @@ { "expectedMakeRequestsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type adapters.ExtImpBidder", + "value": "expect { or n, but found \"", "comparison": "literal" }, { diff --git a/adapters/triplelift/triplelifttest/supplemental/badextbidder.json b/adapters/triplelift/triplelifttest/supplemental/badextbidder.json index 744de84d45d..c5b0c1fcbed 100644 --- a/adapters/triplelift/triplelifttest/supplemental/badextbidder.json +++ b/adapters/triplelift/triplelifttest/supplemental/badextbidder.json @@ -1,7 +1,7 @@ { "expectedMakeRequestsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb_ext.ExtImpTriplelift", + "value": "expect { or n, but found \"", "comparison": "literal" }, { diff --git a/adapters/triplelift/triplelifttest/supplemental/badresponseext.json b/adapters/triplelift/triplelifttest/supplemental/badresponseext.json index 881ead4da6f..3c217f64f4e 100644 --- a/adapters/triplelift/triplelifttest/supplemental/badresponseext.json +++ b/adapters/triplelift/triplelifttest/supplemental/badresponseext.json @@ -97,7 +97,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type triplelift.TripleliftRespExt", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/triplelift_native/params_test.go b/adapters/triplelift_native/params_test.go new file mode 100644 index 00000000000..743c3d87ed2 --- /dev/null +++ b/adapters/triplelift_native/params_test.go @@ -0,0 +1,53 @@ +package triplelift_native + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v3/openrtb_ext" +) + +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schemas. %v", err) + } + + for _, validParam := range validParams { + if err := validator.Validate(openrtb_ext.BidderTripleliftNative, json.RawMessage(validParam)); err != nil { + t.Errorf("Schema rejected triplelift native params: %s", validParam) + } + } +} + +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json-schemas. %v", err) + } + + for _, invalidParam := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderTripleliftNative, json.RawMessage(invalidParam)); err == nil { + t.Errorf("Schema allowed unexpected params: %s", invalidParam) + } + } +} + +var validParams = []string{ + `{"inventoryCode":"1"}`, + `{"inventoryCode":"test"}`, + `{"inventoryCode":"test", "floor":10}`, +} + +var invalidParams = []string{ + ``, + `null`, + `true`, + `5`, + `4.2`, + `[]`, + `{}`, + `{"inventoryCode":1}`, + `{"inventoryCode":""}`, + `{"inventoryCode":"1", "floor": "10"}`, +} diff --git a/adapters/triplelift_native/triplelift_native.go b/adapters/triplelift_native/triplelift_native.go index c3556cfa8bb..1d4c6bf638d 100644 --- a/adapters/triplelift_native/triplelift_native.go +++ b/adapters/triplelift_native/triplelift_native.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type TripleliftNativeAdapter struct { @@ -33,42 +34,65 @@ type TripleliftNativeExtInfo struct { PublisherWhitelistMap map[string]struct{} } +type ExtImpData struct { + TagCode string `json:"tag_code"` +} + +type ExtImp struct { + *adapters.ExtImpBidder + Data *ExtImpData `json:"data,omitempty"` +} + func getBidType(ext TripleliftRespExt) openrtb_ext.BidType { return openrtb_ext.BidTypeNative } -func processImp(imp *openrtb2.Imp) error { +func processImp(imp *openrtb2.Imp, request *openrtb2.BidRequest) error { // get the triplelift extension - var ext adapters.ExtImpBidder + var ext ExtImp var tlext openrtb_ext.ExtImpTriplelift - if err := json.Unmarshal(imp.Ext, &ext); err != nil { + + if err := jsonutil.Unmarshal(imp.Ext, &ext); err != nil { return err } - if err := json.Unmarshal(ext.Bidder, &tlext); err != nil { + if err := jsonutil.Unmarshal(ext.Bidder, &tlext); err != nil { return err } if imp.Native == nil { return fmt.Errorf("no native object specified") } - if tlext.InvCode == "" { - return fmt.Errorf("no inv_code specified") + + if ext.Data != nil && len(ext.Data.TagCode) > 0 && (msnInSite(request) || msnInApp(request)) { + imp.TagID = ext.Data.TagCode + } else { + imp.TagID = tlext.InvCode } - imp.TagID = tlext.InvCode + // floor is optional if tlext.Floor == nil { return nil } imp.BidFloor = *tlext.Floor - // no error + return nil } +// msnInApp returns whether msn.com is in request.app.publisher.domain +func msnInApp(request *openrtb2.BidRequest) bool { + return request.App != nil && request.App.Publisher != nil && request.App.Publisher.Domain == "msn.com" +} + +// msnInSite returns whether msn.com is in request.site.publisher.domain +func msnInSite(request *openrtb2.BidRequest) bool { + return request.Site != nil && request.Site.Publisher != nil && request.Site.Publisher.Domain == "msn.com" +} + // Returns the effective publisher ID func effectivePubID(pub *openrtb2.Publisher) string { if pub != nil { if pub.Ext != nil { var pubExt openrtb_ext.ExtPublisher - err := json.Unmarshal(pub.Ext, &pubExt) + err := jsonutil.Unmarshal(pub.Ext, &pubExt) if err == nil && pubExt.Prebid != nil && pubExt.Prebid.ParentAccount != nil && *pubExt.Prebid.ParentAccount != "" { return *pubExt.Prebid.ParentAccount } @@ -89,7 +113,7 @@ func (a *TripleliftNativeAdapter) MakeRequests(request *openrtb2.BidRequest, ext var validImps []openrtb2.Imp // pre-process the imps for _, imp := range tlRequest.Imp { - if err := processImp(&imp); err == nil { + if err := processImp(&imp, request); err == nil { validImps = append(validImps, imp) } else { errs = append(errs, err) @@ -155,7 +179,7 @@ func (a *TripleliftNativeAdapter) MakeBids(internalRequest *openrtb2.BidRequest, return nil, []error{&errortypes.BadServerResponse{Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode)}} } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } var errs []error @@ -202,7 +226,7 @@ func getExtraInfo(v string) (TripleliftNativeExtInfo, error) { } var extraInfo TripleliftNativeExtInfo - if err := json.Unmarshal([]byte(v), &extraInfo); err != nil { + if err := jsonutil.Unmarshal([]byte(v), &extraInfo); err != nil { return extraInfo, fmt.Errorf("invalid extra info: %v", err) } diff --git a/adapters/triplelift_native/triplelift_native_test.go b/adapters/triplelift_native/triplelift_native_test.go index c1c82501b32..651890b01e0 100644 --- a/adapters/triplelift_native/triplelift_native_test.go +++ b/adapters/triplelift_native/triplelift_native_test.go @@ -3,9 +3,9 @@ package triplelift_native import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/triplelift_native/triplelift_nativetest/exemplary/app-msn-no-tag-code.json b/adapters/triplelift_native/triplelift_nativetest/exemplary/app-msn-no-tag-code.json new file mode 100644 index 00000000000..6950942f19d --- /dev/null +++ b/adapters/triplelift_native/triplelift_nativetest/exemplary/app-msn-no-tag-code.json @@ -0,0 +1,112 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "publisher": { + "id": "foo", + "name": "foo", + "domain": "msn.com" + } + }, + "imp": [{ + "native": { + "request": "{\"plcmtcnt\":1,\"plcmttype\":2,\"privacy\":1,\"context\":1,\"contextsubtype\":12,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"assets\":[{\"data\":{\"type\":12},\"required\":1},{\"title\":{\"len\":50},\"required\":1},{\"img\":{\"w\":80,\"h\":80,\"type\":1},\"required\":1},{\"img\":{\"w\":1200,\"h\":627,\"type\":3},\"required\":1},{\"data\":{\"type\":3},\"required\":0},{\"data\":{\"len\":100,\"type\":2},\"required\":1},{\"video\":{\"mimes\":[\"video/mpeg\",\"video/mp4\"],\"minduration\":2,\"protocols\":[2,5],\"maxduration\":2,\"ext\":{\"playbackmethod\":[1,2]}},\"required\":1}],\"ver\":\"1.2\"}" + }, + "id": "test-imp-id", + "ext": { + "bidder": { + "inventoryCode": "invcode", + "floor": 20 + }, + "data": { + "tag_code": "" + } + } + }] + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://tlx.3lift.net/s2sn/auction?supplier_id=20", + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "native": { + "request": "{\"plcmtcnt\":1,\"plcmttype\":2,\"privacy\":1,\"context\":1,\"contextsubtype\":12,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"assets\":[{\"data\":{\"type\":12},\"required\":1},{\"title\":{\"len\":50},\"required\":1},{\"img\":{\"w\":80,\"h\":80,\"type\":1},\"required\":1},{\"img\":{\"w\":1200,\"h\":627,\"type\":3},\"required\":1},{\"data\":{\"type\":3},\"required\":0},{\"data\":{\"len\":100,\"type\":2},\"required\":1},{\"video\":{\"mimes\":[\"video/mpeg\",\"video/mp4\"],\"minduration\":2,\"protocols\":[2,5],\"maxduration\":2,\"ext\":{\"playbackmethod\":[1,2]}},\"required\":1}],\"ver\":\"1.2\"}" + }, + "tagid": "invcode", + "bidfloor": 20, + "ext": { + "bidder": { + "inventoryCode": "invcode", + "floor": 20 + }, + "data": { + "tag_code": "" + } + } + }], + "app": { + "publisher": { + "id": "foo", + "name": "foo", + "domain": "msn.com" + } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [{ + "seat": "958", + "bid": [{ + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.5, + "adid": "29681110", + "adm": "some-test-ad", + "adomain": [ + "triplelift.com" + ], + "iurl": "http://example.com", + "cid": "958", + "crid": "29681110", + "h": 250, + "w": 300, + "ext": "aaa" + }] + }], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + }], + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "id": "test-request-id", + "type": "native", + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.5, + "adid": "29681110", + "adm": "some-test-ad", + "adomain": [ + "triplelift.com" + ], + "iurl": "http://example.com", + "cid": "958", + "crid": "29681110", + "h": 250, + "w": 300, + "ext": "aaa" + }, + "bidid": "5778926625248726496", + "cur": "USD" + }] + }] +} \ No newline at end of file diff --git a/adapters/triplelift_native/triplelift_nativetest/exemplary/app-msn.json b/adapters/triplelift_native/triplelift_nativetest/exemplary/app-msn.json new file mode 100644 index 00000000000..420cab5aff0 --- /dev/null +++ b/adapters/triplelift_native/triplelift_nativetest/exemplary/app-msn.json @@ -0,0 +1,112 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "publisher": { + "id": "foo", + "name": "foo", + "domain": "msn.com" + } + }, + "imp": [{ + "native": { + "request": "{\"plcmtcnt\":1,\"plcmttype\":2,\"privacy\":1,\"context\":1,\"contextsubtype\":12,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"assets\":[{\"data\":{\"type\":12},\"required\":1},{\"title\":{\"len\":50},\"required\":1},{\"img\":{\"w\":80,\"h\":80,\"type\":1},\"required\":1},{\"img\":{\"w\":1200,\"h\":627,\"type\":3},\"required\":1},{\"data\":{\"type\":3},\"required\":0},{\"data\":{\"len\":100,\"type\":2},\"required\":1},{\"video\":{\"mimes\":[\"video/mpeg\",\"video/mp4\"],\"minduration\":2,\"protocols\":[2,5],\"maxduration\":2,\"ext\":{\"playbackmethod\":[1,2]}},\"required\":1}],\"ver\":\"1.2\"}" + }, + "id": "test-imp-id", + "ext": { + "bidder": { + "inventoryCode": "invcode", + "floor": 20 + }, + "data": { + "tag_code": "bar" + } + } + }] + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://tlx.3lift.net/s2sn/auction?supplier_id=20", + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "native": { + "request": "{\"plcmtcnt\":1,\"plcmttype\":2,\"privacy\":1,\"context\":1,\"contextsubtype\":12,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"assets\":[{\"data\":{\"type\":12},\"required\":1},{\"title\":{\"len\":50},\"required\":1},{\"img\":{\"w\":80,\"h\":80,\"type\":1},\"required\":1},{\"img\":{\"w\":1200,\"h\":627,\"type\":3},\"required\":1},{\"data\":{\"type\":3},\"required\":0},{\"data\":{\"len\":100,\"type\":2},\"required\":1},{\"video\":{\"mimes\":[\"video/mpeg\",\"video/mp4\"],\"minduration\":2,\"protocols\":[2,5],\"maxduration\":2,\"ext\":{\"playbackmethod\":[1,2]}},\"required\":1}],\"ver\":\"1.2\"}" + }, + "tagid": "bar", + "bidfloor": 20, + "ext": { + "bidder": { + "inventoryCode": "invcode", + "floor": 20 + }, + "data": { + "tag_code": "bar" + } + } + }], + "app": { + "publisher": { + "id": "foo", + "name": "foo", + "domain": "msn.com" + } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [{ + "seat": "958", + "bid": [{ + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.5, + "adid": "29681110", + "adm": "some-test-ad", + "adomain": [ + "triplelift.com" + ], + "iurl": "http://example.com", + "cid": "958", + "crid": "29681110", + "h": 250, + "w": 300, + "ext": "aaa" + }] + }], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + }], + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "id": "test-request-id", + "type": "native", + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.5, + "adid": "29681110", + "adm": "some-test-ad", + "adomain": [ + "triplelift.com" + ], + "iurl": "http://example.com", + "cid": "958", + "crid": "29681110", + "h": 250, + "w": 300, + "ext": "aaa" + }, + "bidid": "5778926625248726496", + "cur": "USD" + }] + }] +} \ No newline at end of file diff --git a/adapters/triplelift_native/triplelift_nativetest/exemplary/app.json b/adapters/triplelift_native/triplelift_nativetest/exemplary/app.json new file mode 100644 index 00000000000..d1cd72947b7 --- /dev/null +++ b/adapters/triplelift_native/triplelift_nativetest/exemplary/app.json @@ -0,0 +1,112 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "publisher": { + "id": "foo", + "name": "foo", + "domain": "foo.com" + } + }, + "imp": [{ + "native": { + "request": "{\"plcmtcnt\":1,\"plcmttype\":2,\"privacy\":1,\"context\":1,\"contextsubtype\":12,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"assets\":[{\"data\":{\"type\":12},\"required\":1},{\"title\":{\"len\":50},\"required\":1},{\"img\":{\"w\":80,\"h\":80,\"type\":1},\"required\":1},{\"img\":{\"w\":1200,\"h\":627,\"type\":3},\"required\":1},{\"data\":{\"type\":3},\"required\":0},{\"data\":{\"len\":100,\"type\":2},\"required\":1},{\"video\":{\"mimes\":[\"video/mpeg\",\"video/mp4\"],\"minduration\":2,\"protocols\":[2,5],\"maxduration\":2,\"ext\":{\"playbackmethod\":[1,2]}},\"required\":1}],\"ver\":\"1.2\"}" + }, + "id": "test-imp-id", + "ext": { + "bidder": { + "inventoryCode": "invcode", + "floor": 20 + }, + "data": { + "tag_code": "bar" + } + } + }] + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://tlx.3lift.net/s2sn/auction?supplier_id=20", + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "native": { + "request": "{\"plcmtcnt\":1,\"plcmttype\":2,\"privacy\":1,\"context\":1,\"contextsubtype\":12,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"assets\":[{\"data\":{\"type\":12},\"required\":1},{\"title\":{\"len\":50},\"required\":1},{\"img\":{\"w\":80,\"h\":80,\"type\":1},\"required\":1},{\"img\":{\"w\":1200,\"h\":627,\"type\":3},\"required\":1},{\"data\":{\"type\":3},\"required\":0},{\"data\":{\"len\":100,\"type\":2},\"required\":1},{\"video\":{\"mimes\":[\"video/mpeg\",\"video/mp4\"],\"minduration\":2,\"protocols\":[2,5],\"maxduration\":2,\"ext\":{\"playbackmethod\":[1,2]}},\"required\":1}],\"ver\":\"1.2\"}" + }, + "tagid": "invcode", + "bidfloor": 20, + "ext": { + "bidder": { + "inventoryCode": "invcode", + "floor": 20 + }, + "data": { + "tag_code": "bar" + } + } + }], + "app": { + "publisher": { + "id": "foo", + "name": "foo", + "domain": "foo.com" + } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [{ + "seat": "958", + "bid": [{ + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.5, + "adid": "29681110", + "adm": "some-test-ad", + "adomain": [ + "triplelift.com" + ], + "iurl": "http://example.com", + "cid": "958", + "crid": "29681110", + "h": 250, + "w": 300, + "ext": "aaa" + }] + }], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + }], + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "id": "test-request-id", + "type": "native", + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.5, + "adid": "29681110", + "adm": "some-test-ad", + "adomain": [ + "triplelift.com" + ], + "iurl": "http://example.com", + "cid": "958", + "crid": "29681110", + "h": 250, + "w": 300, + "ext": "aaa" + }, + "bidid": "5778926625248726496", + "cur": "USD" + }] + }] +} \ No newline at end of file diff --git a/adapters/triplelift_native/triplelift_nativetest/exemplary/optional-params.json b/adapters/triplelift_native/triplelift_nativetest/exemplary/optional-params.json deleted file mode 100644 index f04f3eef557..00000000000 --- a/adapters/triplelift_native/triplelift_nativetest/exemplary/optional-params.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "mockBidRequest": { - "id": "test-request-id", - "site": { "publisher": {"id":"foo","name":"foo"}}, - "imp": [ - { - "native":{ - "request" : "{\"plcmtcnt\":1,\"plcmttype\":2,\"privacy\":1,\"context\":1,\"contextsubtype\":12,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"assets\":[{\"data\":{\"type\":12},\"required\":1},{\"title\":{\"len\":50},\"required\":1},{\"img\":{\"w\":80,\"h\":80,\"type\":1},\"required\":1},{\"img\":{\"w\":1200,\"h\":627,\"type\":3},\"required\":1},{\"data\":{\"type\":3},\"required\":0},{\"data\":{\"len\":100,\"type\":2},\"required\":1},{\"video\":{\"mimes\":[\"video/mpeg\",\"video/mp4\"],\"minduration\":2,\"protocols\":[2,5],\"maxduration\":2,\"ext\":{\"playbackmethod\":[1,2]}},\"required\":1}],\"ver\":\"1.2\"}" - }, - "id": "test-imp-id", - "ext": { - "bidder": { - "inventoryCode": "foo", - "floor" : 20 - } - } - } - ] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://tlx.3lift.net/s2sn/auction?supplier_id=20", - "body": { - "id": "test-request-id", - "imp": [ - { - "id": "test-imp-id", - "native": { - "request" : "{\"plcmtcnt\":1,\"plcmttype\":2,\"privacy\":1,\"context\":1,\"contextsubtype\":12,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"assets\":[{\"data\":{\"type\":12},\"required\":1},{\"title\":{\"len\":50},\"required\":1},{\"img\":{\"w\":80,\"h\":80,\"type\":1},\"required\":1},{\"img\":{\"w\":1200,\"h\":627,\"type\":3},\"required\":1},{\"data\":{\"type\":3},\"required\":0},{\"data\":{\"len\":100,\"type\":2},\"required\":1},{\"video\":{\"mimes\":[\"video/mpeg\",\"video/mp4\"],\"minduration\":2,\"protocols\":[2,5],\"maxduration\":2,\"ext\":{\"playbackmethod\":[1,2]}},\"required\":1}],\"ver\":\"1.2\"}" - }, - "tagid": "foo", - "bidfloor": 20, - "ext": { - "bidder": { - "inventoryCode": "foo", - "floor" : 20 - } - } - } - ], - "site": { - "publisher": { - "id": "foo", - "name": "foo" - } - } - }, - "impIDs":["test-imp-id"] - }, - "mockResponse": { - "status": 204 - } - } - ], - "expectedBidResponses": [] -} diff --git a/adapters/triplelift_native/triplelift_nativetest/exemplary/site-msn-no-tag-code.json b/adapters/triplelift_native/triplelift_nativetest/exemplary/site-msn-no-tag-code.json new file mode 100644 index 00000000000..48162742a17 --- /dev/null +++ b/adapters/triplelift_native/triplelift_nativetest/exemplary/site-msn-no-tag-code.json @@ -0,0 +1,112 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "publisher": { + "id": "foo", + "name": "foo", + "domain": "msn.com" + } + }, + "imp": [{ + "native": { + "request": "{\"plcmtcnt\":1,\"plcmttype\":2,\"privacy\":1,\"context\":1,\"contextsubtype\":12,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"assets\":[{\"data\":{\"type\":12},\"required\":1},{\"title\":{\"len\":50},\"required\":1},{\"img\":{\"w\":80,\"h\":80,\"type\":1},\"required\":1},{\"img\":{\"w\":1200,\"h\":627,\"type\":3},\"required\":1},{\"data\":{\"type\":3},\"required\":0},{\"data\":{\"len\":100,\"type\":2},\"required\":1},{\"video\":{\"mimes\":[\"video/mpeg\",\"video/mp4\"],\"minduration\":2,\"protocols\":[2,5],\"maxduration\":2,\"ext\":{\"playbackmethod\":[1,2]}},\"required\":1}],\"ver\":\"1.2\"}" + }, + "id": "test-imp-id", + "ext": { + "bidder": { + "inventoryCode": "invcode", + "floor": 20 + }, + "data": { + "tag_code": "" + } + } + }] + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://tlx.3lift.net/s2sn/auction?supplier_id=20", + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "native": { + "request": "{\"plcmtcnt\":1,\"plcmttype\":2,\"privacy\":1,\"context\":1,\"contextsubtype\":12,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"assets\":[{\"data\":{\"type\":12},\"required\":1},{\"title\":{\"len\":50},\"required\":1},{\"img\":{\"w\":80,\"h\":80,\"type\":1},\"required\":1},{\"img\":{\"w\":1200,\"h\":627,\"type\":3},\"required\":1},{\"data\":{\"type\":3},\"required\":0},{\"data\":{\"len\":100,\"type\":2},\"required\":1},{\"video\":{\"mimes\":[\"video/mpeg\",\"video/mp4\"],\"minduration\":2,\"protocols\":[2,5],\"maxduration\":2,\"ext\":{\"playbackmethod\":[1,2]}},\"required\":1}],\"ver\":\"1.2\"}" + }, + "tagid": "invcode", + "bidfloor": 20, + "ext": { + "bidder": { + "inventoryCode": "invcode", + "floor": 20 + }, + "data": { + "tag_code": "" + } + } + }], + "site": { + "publisher": { + "id": "foo", + "name": "foo", + "domain": "msn.com" + } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [{ + "seat": "958", + "bid": [{ + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.5, + "adid": "29681110", + "adm": "some-test-ad", + "adomain": [ + "triplelift.com" + ], + "iurl": "http://example.com", + "cid": "958", + "crid": "29681110", + "h": 250, + "w": 300, + "ext": "aaa" + }] + }], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + }], + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "id": "test-request-id", + "type": "native", + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.5, + "adid": "29681110", + "adm": "some-test-ad", + "adomain": [ + "triplelift.com" + ], + "iurl": "http://example.com", + "cid": "958", + "crid": "29681110", + "h": 250, + "w": 300, + "ext": "aaa" + }, + "bidid": "5778926625248726496", + "cur": "USD" + }] + }] +} \ No newline at end of file diff --git a/adapters/triplelift_native/triplelift_nativetest/exemplary/site-msn.json b/adapters/triplelift_native/triplelift_nativetest/exemplary/site-msn.json new file mode 100644 index 00000000000..5aaa5a1ddc2 --- /dev/null +++ b/adapters/triplelift_native/triplelift_nativetest/exemplary/site-msn.json @@ -0,0 +1,112 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "publisher": { + "id": "foo", + "name": "foo", + "domain": "msn.com" + } + }, + "imp": [{ + "native": { + "request": "{\"plcmtcnt\":1,\"plcmttype\":2,\"privacy\":1,\"context\":1,\"contextsubtype\":12,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"assets\":[{\"data\":{\"type\":12},\"required\":1},{\"title\":{\"len\":50},\"required\":1},{\"img\":{\"w\":80,\"h\":80,\"type\":1},\"required\":1},{\"img\":{\"w\":1200,\"h\":627,\"type\":3},\"required\":1},{\"data\":{\"type\":3},\"required\":0},{\"data\":{\"len\":100,\"type\":2},\"required\":1},{\"video\":{\"mimes\":[\"video/mpeg\",\"video/mp4\"],\"minduration\":2,\"protocols\":[2,5],\"maxduration\":2,\"ext\":{\"playbackmethod\":[1,2]}},\"required\":1}],\"ver\":\"1.2\"}" + }, + "id": "test-imp-id", + "ext": { + "bidder": { + "inventoryCode": "invcode", + "floor": 20 + }, + "data": { + "tag_code": "bar" + } + } + }] + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://tlx.3lift.net/s2sn/auction?supplier_id=20", + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "native": { + "request": "{\"plcmtcnt\":1,\"plcmttype\":2,\"privacy\":1,\"context\":1,\"contextsubtype\":12,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"assets\":[{\"data\":{\"type\":12},\"required\":1},{\"title\":{\"len\":50},\"required\":1},{\"img\":{\"w\":80,\"h\":80,\"type\":1},\"required\":1},{\"img\":{\"w\":1200,\"h\":627,\"type\":3},\"required\":1},{\"data\":{\"type\":3},\"required\":0},{\"data\":{\"len\":100,\"type\":2},\"required\":1},{\"video\":{\"mimes\":[\"video/mpeg\",\"video/mp4\"],\"minduration\":2,\"protocols\":[2,5],\"maxduration\":2,\"ext\":{\"playbackmethod\":[1,2]}},\"required\":1}],\"ver\":\"1.2\"}" + }, + "tagid": "bar", + "bidfloor": 20, + "ext": { + "bidder": { + "inventoryCode": "invcode", + "floor": 20 + }, + "data": { + "tag_code": "bar" + } + } + }], + "site": { + "publisher": { + "id": "foo", + "name": "foo", + "domain": "msn.com" + } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [{ + "seat": "958", + "bid": [{ + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.5, + "adid": "29681110", + "adm": "some-test-ad", + "adomain": [ + "triplelift.com" + ], + "iurl": "http://example.com", + "cid": "958", + "crid": "29681110", + "h": 250, + "w": 300, + "ext": "aaa" + }] + }], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + }], + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "id": "test-request-id", + "type": "native", + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.5, + "adid": "29681110", + "adm": "some-test-ad", + "adomain": [ + "triplelift.com" + ], + "iurl": "http://example.com", + "cid": "958", + "crid": "29681110", + "h": 250, + "w": 300, + "ext": "aaa" + }, + "bidid": "5778926625248726496", + "cur": "USD" + }] + }] +} \ No newline at end of file diff --git a/adapters/triplelift_native/triplelift_nativetest/exemplary/site.json b/adapters/triplelift_native/triplelift_nativetest/exemplary/site.json new file mode 100644 index 00000000000..d273f4d411d --- /dev/null +++ b/adapters/triplelift_native/triplelift_nativetest/exemplary/site.json @@ -0,0 +1,112 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "publisher": { + "id": "foo", + "name": "foo", + "domain": "foo.com" + } + }, + "imp": [{ + "native": { + "request": "{\"plcmtcnt\":1,\"plcmttype\":2,\"privacy\":1,\"context\":1,\"contextsubtype\":12,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"assets\":[{\"data\":{\"type\":12},\"required\":1},{\"title\":{\"len\":50},\"required\":1},{\"img\":{\"w\":80,\"h\":80,\"type\":1},\"required\":1},{\"img\":{\"w\":1200,\"h\":627,\"type\":3},\"required\":1},{\"data\":{\"type\":3},\"required\":0},{\"data\":{\"len\":100,\"type\":2},\"required\":1},{\"video\":{\"mimes\":[\"video/mpeg\",\"video/mp4\"],\"minduration\":2,\"protocols\":[2,5],\"maxduration\":2,\"ext\":{\"playbackmethod\":[1,2]}},\"required\":1}],\"ver\":\"1.2\"}" + }, + "id": "test-imp-id", + "ext": { + "bidder": { + "inventoryCode": "invcode", + "floor": 20 + }, + "data": { + "tag_code": "bar" + } + } + }] + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://tlx.3lift.net/s2sn/auction?supplier_id=20", + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "native": { + "request": "{\"plcmtcnt\":1,\"plcmttype\":2,\"privacy\":1,\"context\":1,\"contextsubtype\":12,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"assets\":[{\"data\":{\"type\":12},\"required\":1},{\"title\":{\"len\":50},\"required\":1},{\"img\":{\"w\":80,\"h\":80,\"type\":1},\"required\":1},{\"img\":{\"w\":1200,\"h\":627,\"type\":3},\"required\":1},{\"data\":{\"type\":3},\"required\":0},{\"data\":{\"len\":100,\"type\":2},\"required\":1},{\"video\":{\"mimes\":[\"video/mpeg\",\"video/mp4\"],\"minduration\":2,\"protocols\":[2,5],\"maxduration\":2,\"ext\":{\"playbackmethod\":[1,2]}},\"required\":1}],\"ver\":\"1.2\"}" + }, + "tagid": "invcode", + "bidfloor": 20, + "ext": { + "bidder": { + "inventoryCode": "invcode", + "floor": 20 + }, + "data": { + "tag_code": "bar" + } + } + }], + "site": { + "publisher": { + "id": "foo", + "name": "foo", + "domain": "foo.com" + } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [{ + "seat": "958", + "bid": [{ + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.5, + "adid": "29681110", + "adm": "some-test-ad", + "adomain": [ + "triplelift.com" + ], + "iurl": "http://example.com", + "cid": "958", + "crid": "29681110", + "h": 250, + "w": 300, + "ext": "aaa" + }] + }], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + }], + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "id": "test-request-id", + "type": "native", + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.5, + "adid": "29681110", + "adm": "some-test-ad", + "adomain": [ + "triplelift.com" + ], + "iurl": "http://example.com", + "cid": "958", + "crid": "29681110", + "h": 250, + "w": 300, + "ext": "aaa" + }, + "bidid": "5778926625248726496", + "cur": "USD" + }] + }] +} \ No newline at end of file diff --git a/adapters/triplelift_native/triplelift_nativetest/supplemental/app-no-publisher.json b/adapters/triplelift_native/triplelift_nativetest/supplemental/app-no-publisher.json new file mode 100644 index 00000000000..56b339a1d79 --- /dev/null +++ b/adapters/triplelift_native/triplelift_nativetest/supplemental/app-no-publisher.json @@ -0,0 +1,25 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": {}, + "imp": [{ + "native": { + "request": "{\"plcmtcnt\":1,\"plcmttype\":2,\"privacy\":1,\"context\":1,\"contextsubtype\":12,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"assets\":[{\"data\":{\"type\":12},\"required\":1},{\"title\":{\"len\":50},\"required\":1},{\"img\":{\"w\":80,\"h\":80,\"type\":1},\"required\":1},{\"img\":{\"w\":1200,\"h\":627,\"type\":3},\"required\":1},{\"data\":{\"type\":3},\"required\":0},{\"data\":{\"len\":100,\"type\":2},\"required\":1},{\"video\":{\"mimes\":[\"video/mpeg\",\"video/mp4\"],\"minduration\":2,\"protocols\":[2,5],\"maxduration\":2,\"ext\":{\"playbackmethod\":[1,2]}},\"required\":1}],\"ver\":\"1.2\"}" + }, + "id": "test-imp-id", + "ext": { + "bidder": { + "inventoryCode": "invcode", + "floor": 20 + }, + "data": { + "tag_code": "bar" + } + } + }] + }, + "expectedMakeRequestsErrors": [{ + "value": "Unsupported publisher for triplelift_native", + "comparison": "literal" + }] +} \ No newline at end of file diff --git a/adapters/triplelift_native/triplelift_nativetest/supplemental/app-publisher-no-domain.json b/adapters/triplelift_native/triplelift_nativetest/supplemental/app-publisher-no-domain.json new file mode 100644 index 00000000000..ac119354c36 --- /dev/null +++ b/adapters/triplelift_native/triplelift_nativetest/supplemental/app-publisher-no-domain.json @@ -0,0 +1,60 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "app": { + "publisher": { + "id": "foo" + } + }, + "imp": [{ + "native": { + "request": "{\"plcmtcnt\":1,\"plcmttype\":2,\"privacy\":1,\"context\":1,\"contextsubtype\":12,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"assets\":[{\"data\":{\"type\":12},\"required\":1},{\"title\":{\"len\":50},\"required\":1},{\"img\":{\"w\":80,\"h\":80,\"type\":1},\"required\":1},{\"img\":{\"w\":1200,\"h\":627,\"type\":3},\"required\":1},{\"data\":{\"type\":3},\"required\":0},{\"data\":{\"len\":100,\"type\":2},\"required\":1},{\"video\":{\"mimes\":[\"video/mpeg\",\"video/mp4\"],\"minduration\":2,\"protocols\":[2,5],\"maxduration\":2,\"ext\":{\"playbackmethod\":[1,2]}},\"required\":1}],\"ver\":\"1.2\"}" + }, + "id": "test-imp-id", + "ext": { + "bidder": { + "inventoryCode": "invcode", + "floor": 20 + }, + "data": { + "tag_code": "bar" + } + } + }] + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://tlx.3lift.net/s2sn/auction?supplier_id=20", + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "native": { + "request": "{\"plcmtcnt\":1,\"plcmttype\":2,\"privacy\":1,\"context\":1,\"contextsubtype\":12,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"assets\":[{\"data\":{\"type\":12},\"required\":1},{\"title\":{\"len\":50},\"required\":1},{\"img\":{\"w\":80,\"h\":80,\"type\":1},\"required\":1},{\"img\":{\"w\":1200,\"h\":627,\"type\":3},\"required\":1},{\"data\":{\"type\":3},\"required\":0},{\"data\":{\"len\":100,\"type\":2},\"required\":1},{\"video\":{\"mimes\":[\"video/mpeg\",\"video/mp4\"],\"minduration\":2,\"protocols\":[2,5],\"maxduration\":2,\"ext\":{\"playbackmethod\":[1,2]}},\"required\":1}],\"ver\":\"1.2\"}" + }, + "tagid": "invcode", + "bidfloor": 20, + "ext": { + "bidder": { + "inventoryCode": "invcode", + "floor": 20 + }, + "data": { + "tag_code": "bar" + } + } + }], + "app": { + "publisher": { + "id": "foo" + } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 204 + } + }], + "expectedBidResponses": [] +} \ No newline at end of file diff --git a/adapters/triplelift_native/triplelift_nativetest/supplemental/badext.json b/adapters/triplelift_native/triplelift_nativetest/supplemental/badext.json index 7df178bdd00..eb2d6a1e19d 100644 --- a/adapters/triplelift_native/triplelift_nativetest/supplemental/badext.json +++ b/adapters/triplelift_native/triplelift_nativetest/supplemental/badext.json @@ -1,7 +1,7 @@ { "expectedMakeRequestsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type adapters.ExtImpBidder", + "value": "expect { or n, but found \"", "comparison": "literal" }, { diff --git a/adapters/triplelift_native/triplelift_nativetest/supplemental/badextbidder.json b/adapters/triplelift_native/triplelift_nativetest/supplemental/badextbidder.json index 59ebe048b19..deb9dfce308 100644 --- a/adapters/triplelift_native/triplelift_nativetest/supplemental/badextbidder.json +++ b/adapters/triplelift_native/triplelift_nativetest/supplemental/badextbidder.json @@ -1,7 +1,7 @@ { "expectedMakeRequestsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb_ext.ExtImpTriplelift", + "value": "expect { or n, but found \"", "comparison": "literal" }, { diff --git a/adapters/triplelift_native/triplelift_nativetest/supplemental/effective-publisher-allowed.json b/adapters/triplelift_native/triplelift_nativetest/supplemental/effective-publisher-allowed.json new file mode 100644 index 00000000000..74ac9294783 --- /dev/null +++ b/adapters/triplelift_native/triplelift_nativetest/supplemental/effective-publisher-allowed.json @@ -0,0 +1,122 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "publisher": { + "id": "baz", + "name": "foo", + "domain": "foo.com", + "ext": { + "prebid": { + "parentAccount": "foo" + } + } + } + }, + "imp": [{ + "native": { + "request": "{\"plcmtcnt\":1,\"plcmttype\":2,\"privacy\":1,\"context\":1,\"contextsubtype\":12,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"assets\":[{\"data\":{\"type\":12},\"required\":1},{\"title\":{\"len\":50},\"required\":1},{\"img\":{\"w\":80,\"h\":80,\"type\":1},\"required\":1},{\"img\":{\"w\":1200,\"h\":627,\"type\":3},\"required\":1},{\"data\":{\"type\":3},\"required\":0},{\"data\":{\"len\":100,\"type\":2},\"required\":1},{\"video\":{\"mimes\":[\"video/mpeg\",\"video/mp4\"],\"minduration\":2,\"protocols\":[2,5],\"maxduration\":2,\"ext\":{\"playbackmethod\":[1,2]}},\"required\":1}],\"ver\":\"1.2\"}" + }, + "id": "test-imp-id", + "ext": { + "bidder": { + "inventoryCode": "invcode", + "floor": 20 + }, + "data": { + "tag_code": "bar" + } + } + }] + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://tlx.3lift.net/s2sn/auction?supplier_id=20", + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "native": { + "request": "{\"plcmtcnt\":1,\"plcmttype\":2,\"privacy\":1,\"context\":1,\"contextsubtype\":12,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"assets\":[{\"data\":{\"type\":12},\"required\":1},{\"title\":{\"len\":50},\"required\":1},{\"img\":{\"w\":80,\"h\":80,\"type\":1},\"required\":1},{\"img\":{\"w\":1200,\"h\":627,\"type\":3},\"required\":1},{\"data\":{\"type\":3},\"required\":0},{\"data\":{\"len\":100,\"type\":2},\"required\":1},{\"video\":{\"mimes\":[\"video/mpeg\",\"video/mp4\"],\"minduration\":2,\"protocols\":[2,5],\"maxduration\":2,\"ext\":{\"playbackmethod\":[1,2]}},\"required\":1}],\"ver\":\"1.2\"}" + }, + "tagid": "invcode", + "bidfloor": 20, + "ext": { + "bidder": { + "inventoryCode": "invcode", + "floor": 20 + }, + "data": { + "tag_code": "bar" + } + } + }], + "site": { + "publisher": { + "id": "baz", + "name": "foo", + "domain": "foo.com", + "ext": { + "prebid": { + "parentAccount": "foo" + } + } + } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [{ + "seat": "958", + "bid": [{ + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.5, + "adid": "29681110", + "adm": "some-test-ad", + "adomain": [ + "triplelift.com" + ], + "iurl": "http://example.com", + "cid": "958", + "crid": "29681110", + "h": 250, + "w": 300, + "ext": "aaa" + }] + }], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + }], + "expectedBidResponses": [{ + "currency": "USD", + "bids": [{ + "id": "test-request-id", + "type": "native", + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.5, + "adid": "29681110", + "adm": "some-test-ad", + "adomain": [ + "triplelift.com" + ], + "iurl": "http://example.com", + "cid": "958", + "crid": "29681110", + "h": 250, + "w": 300, + "ext": "aaa" + }, + "bidid": "5778926625248726496", + "cur": "USD" + }] + }] +} \ No newline at end of file diff --git a/adapters/triplelift_native/triplelift_nativetest/supplemental/effective-publisher-not-allowed.json b/adapters/triplelift_native/triplelift_nativetest/supplemental/effective-publisher-not-allowed.json new file mode 100644 index 00000000000..d43c18cc402 --- /dev/null +++ b/adapters/triplelift_native/triplelift_nativetest/supplemental/effective-publisher-not-allowed.json @@ -0,0 +1,36 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "publisher": { + "id": "baz", + "name": "foo", + "domain": "foo.com", + "ext": { + "prebid": { + "parentAccount": "faz" + } + } + } + }, + "imp": [{ + "native": { + "request": "{\"plcmtcnt\":1,\"plcmttype\":2,\"privacy\":1,\"context\":1,\"contextsubtype\":12,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"assets\":[{\"data\":{\"type\":12},\"required\":1},{\"title\":{\"len\":50},\"required\":1},{\"img\":{\"w\":80,\"h\":80,\"type\":1},\"required\":1},{\"img\":{\"w\":1200,\"h\":627,\"type\":3},\"required\":1},{\"data\":{\"type\":3},\"required\":0},{\"data\":{\"len\":100,\"type\":2},\"required\":1},{\"video\":{\"mimes\":[\"video/mpeg\",\"video/mp4\"],\"minduration\":2,\"protocols\":[2,5],\"maxduration\":2,\"ext\":{\"playbackmethod\":[1,2]}},\"required\":1}],\"ver\":\"1.2\"}" + }, + "id": "test-imp-id", + "ext": { + "bidder": { + "inventoryCode": "invcode", + "floor": 20 + }, + "data": { + "tag_code": "bar" + } + } + }] + }, + "expectedMakeRequestsErrors": [{ + "value": "Unsupported publisher for triplelift_native", + "comparison": "literal" + }] +} \ No newline at end of file diff --git a/adapters/triplelift_native/triplelift_nativetest/supplemental/no-imp-ext-data.json b/adapters/triplelift_native/triplelift_nativetest/supplemental/no-imp-ext-data.json new file mode 100644 index 00000000000..a46d0483fea --- /dev/null +++ b/adapters/triplelift_native/triplelift_nativetest/supplemental/no-imp-ext-data.json @@ -0,0 +1,85 @@ +{ + "mockBidRequest": { + "site": { + "publisher": { + "id": "foo", + "name": "foo" + } + }, + "id": "test-request-id", + "imp": [{ + "native": { + "request": "{\"plcmtcnt\":1,\"plcmttype\":2,\"privacy\":1,\"context\":1,\"contextsubtype\":12,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"assets\":[{\"data\":{\"type\":12},\"required\":1},{\"title\":{\"len\":50},\"required\":1},{\"img\":{\"w\":80,\"h\":80,\"type\":1},\"required\":1},{\"img\":{\"w\":1200,\"h\":627,\"type\":3},\"required\":1},{\"data\":{\"type\":3},\"required\":0},{\"data\":{\"len\":100,\"type\":2},\"required\":1},{\"video\":{\"mimes\":[\"video/mpeg\",\"video/mp4\"],\"minduration\":2,\"protocols\":[2,5],\"maxduration\":2,\"ext\":{\"playbackmethod\":[1,2]}},\"required\":1}],\"ver\":\"1.2\"}" + }, + "id": "test-imp-id", + "ext": { + "bidder": { + "inventoryCode": "invcode" + } + } + }] + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://tlx.3lift.net/s2sn/auction?supplier_id=20", + "body": { + "site": { + "publisher": { + "id": "foo", + "name": "foo" + } + }, + "id": "test-request-id", + "imp": [{ + "native": { + "request": "{\"plcmtcnt\":1,\"plcmttype\":2,\"privacy\":1,\"context\":1,\"contextsubtype\":12,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"assets\":[{\"data\":{\"type\":12},\"required\":1},{\"title\":{\"len\":50},\"required\":1},{\"img\":{\"w\":80,\"h\":80,\"type\":1},\"required\":1},{\"img\":{\"w\":1200,\"h\":627,\"type\":3},\"required\":1},{\"data\":{\"type\":3},\"required\":0},{\"data\":{\"len\":100,\"type\":2},\"required\":1},{\"video\":{\"mimes\":[\"video/mpeg\",\"video/mp4\"],\"minduration\":2,\"protocols\":[2,5],\"maxduration\":2,\"ext\":{\"playbackmethod\":[1,2]}},\"required\":1}],\"ver\":\"1.2\"}" + }, + "id": "test-imp-id", + "tagid": "invcode", + "ext": { + "bidder": { + "inventoryCode": "invcode" + } + } + }] + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 302, + "body": { + "id": "test-request-id", + "seatbid": [{ + "seat": "958", + "bid": [{ + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.5, + "adid": "29681110", + "adm": "some-test-ad", + "adomain": [ + "triplelift.com" + ], + "iurl": "http://nym1-ib.adnxs.com/cr?id=29681110", + "cid": "958", + "crid": "29681110", + "h": 250, + "w": 300, + "ext": { + "triplelift_pb": { + "format": 2 + } + } + }] + }], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + }], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [{ + "value": "Unexpected status code: 302. Run with request.debug = 1 for more info", + "comparison": "literal" + }] +} \ No newline at end of file diff --git a/adapters/triplelift_native/triplelift_nativetest/supplemental/nopub.json b/adapters/triplelift_native/triplelift_nativetest/supplemental/nopub.json deleted file mode 100644 index cdeaff3961a..00000000000 --- a/adapters/triplelift_native/triplelift_nativetest/supplemental/nopub.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "expectedMakeRequestsErrors": [ - { - "value": "Unsupported publisher for triplelift_native", - "comparison": "literal" - } - ], - "mockBidRequest": { - "id": "test-request-id", - "app": { "publisher": {"ext":{"prebid":{"parentAccount":"faz"}}, "id":"far","name":"bar"}}, - "imp": [ - { - "id": "test-imp-id", - "banner": { - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 600 - } - ] - }, - "ext": { - "bidder": { - "inventoryCode": "foo", - "floor": 20 - } - } - } - ] - }, - "httpCalls": [ - ] -} diff --git a/adapters/triplelift_native/triplelift_nativetest/supplemental/notgoodstatuscode.json b/adapters/triplelift_native/triplelift_nativetest/supplemental/notgoodstatuscode.json deleted file mode 100644 index 46588f2e068..00000000000 --- a/adapters/triplelift_native/triplelift_nativetest/supplemental/notgoodstatuscode.json +++ /dev/null @@ -1,87 +0,0 @@ -{ - "mockBidRequest": { - "site": { "publisher": {"id":"foo","name":"foo"}}, - "id": "test-request-id", - "imp": [ - { - "native":{ - "request" : "{\"plcmtcnt\":1,\"plcmttype\":2,\"privacy\":1,\"context\":1,\"contextsubtype\":12,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"assets\":[{\"data\":{\"type\":12},\"required\":1},{\"title\":{\"len\":50},\"required\":1},{\"img\":{\"w\":80,\"h\":80,\"type\":1},\"required\":1},{\"img\":{\"w\":1200,\"h\":627,\"type\":3},\"required\":1},{\"data\":{\"type\":3},\"required\":0},{\"data\":{\"len\":100,\"type\":2},\"required\":1},{\"video\":{\"mimes\":[\"video/mpeg\",\"video/mp4\"],\"minduration\":2,\"protocols\":[2,5],\"maxduration\":2,\"ext\":{\"playbackmethod\":[1,2]}},\"required\":1}],\"ver\":\"1.2\"}" - }, - "id": "test-imp-id", - "ext": { - "bidder": { - "inventoryCode": "aa" - } - } - } - ] - }, - "httpCalls": [ - { - "expectedRequest": { - "uri": "http://tlx.3lift.net/s2sn/auction?supplier_id=20", - "body": { - "site": { "publisher": {"id":"foo","name":"foo"}}, - "id": "test-request-id", - "imp": [ - { - "native":{ - "request" : "{\"plcmtcnt\":1,\"plcmttype\":2,\"privacy\":1,\"context\":1,\"contextsubtype\":12,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"assets\":[{\"data\":{\"type\":12},\"required\":1},{\"title\":{\"len\":50},\"required\":1},{\"img\":{\"w\":80,\"h\":80,\"type\":1},\"required\":1},{\"img\":{\"w\":1200,\"h\":627,\"type\":3},\"required\":1},{\"data\":{\"type\":3},\"required\":0},{\"data\":{\"len\":100,\"type\":2},\"required\":1},{\"video\":{\"mimes\":[\"video/mpeg\",\"video/mp4\"],\"minduration\":2,\"protocols\":[2,5],\"maxduration\":2,\"ext\":{\"playbackmethod\":[1,2]}},\"required\":1}],\"ver\":\"1.2\"}" - }, - "id": "test-imp-id", - "tagid" : "aa", - "ext": { - "bidder": { - "inventoryCode": "aa" - } - } - } - ] - }, - "impIDs":["test-imp-id"] - }, - "mockResponse": { - "status": 302, - "body": { - "id": "test-request-id", - "seatbid": [ - { - "seat": "958", - "bid": [ - { - "id": "7706636740145184841", - "impid": "test-imp-id", - "price": 0.5, - "adid": "29681110", - "adm": "some-test-ad", - "adomain": [ - "triplelift.com" - ], - "iurl": "http://nym1-ib.adnxs.com/cr?id=29681110", - "cid": "958", - "crid": "29681110", - "h": 250, - "w": 300, - "ext": { - "triplelift_pb": { - "format": 2 - } - } - } - ] - } - ], - "bidid": "5778926625248726496", - "cur": "USD" - } - } - } - ], - "expectedBidResponses": [], - "expectedMakeBidsErrors": [ - { - "value": "Unexpected status code: 302. Run with request.debug = 1 for more info", - "comparison": "literal" - } - ] -} diff --git a/adapters/triplelift_native/triplelift_nativetest/supplemental/site-no-publisher.json b/adapters/triplelift_native/triplelift_nativetest/supplemental/site-no-publisher.json new file mode 100644 index 00000000000..62f9bdab17c --- /dev/null +++ b/adapters/triplelift_native/triplelift_nativetest/supplemental/site-no-publisher.json @@ -0,0 +1,25 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": {}, + "imp": [{ + "native": { + "request": "{\"plcmtcnt\":1,\"plcmttype\":2,\"privacy\":1,\"context\":1,\"contextsubtype\":12,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"assets\":[{\"data\":{\"type\":12},\"required\":1},{\"title\":{\"len\":50},\"required\":1},{\"img\":{\"w\":80,\"h\":80,\"type\":1},\"required\":1},{\"img\":{\"w\":1200,\"h\":627,\"type\":3},\"required\":1},{\"data\":{\"type\":3},\"required\":0},{\"data\":{\"len\":100,\"type\":2},\"required\":1},{\"video\":{\"mimes\":[\"video/mpeg\",\"video/mp4\"],\"minduration\":2,\"protocols\":[2,5],\"maxduration\":2,\"ext\":{\"playbackmethod\":[1,2]}},\"required\":1}],\"ver\":\"1.2\"}" + }, + "id": "test-imp-id", + "ext": { + "bidder": { + "inventoryCode": "invcode", + "floor": 20 + }, + "data": { + "tag_code": "bar" + } + } + }] + }, + "expectedMakeRequestsErrors": [{ + "value": "Unsupported publisher for triplelift_native", + "comparison": "literal" + }] +} \ No newline at end of file diff --git a/adapters/triplelift_native/triplelift_nativetest/supplemental/site-publisher-no-domain.json b/adapters/triplelift_native/triplelift_nativetest/supplemental/site-publisher-no-domain.json new file mode 100644 index 00000000000..d44ae442fab --- /dev/null +++ b/adapters/triplelift_native/triplelift_nativetest/supplemental/site-publisher-no-domain.json @@ -0,0 +1,62 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "publisher": { + "id": "foo", + "name": "foo" + } + }, + "imp": [{ + "native": { + "request": "{\"plcmtcnt\":1,\"plcmttype\":2,\"privacy\":1,\"context\":1,\"contextsubtype\":12,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"assets\":[{\"data\":{\"type\":12},\"required\":1},{\"title\":{\"len\":50},\"required\":1},{\"img\":{\"w\":80,\"h\":80,\"type\":1},\"required\":1},{\"img\":{\"w\":1200,\"h\":627,\"type\":3},\"required\":1},{\"data\":{\"type\":3},\"required\":0},{\"data\":{\"len\":100,\"type\":2},\"required\":1},{\"video\":{\"mimes\":[\"video/mpeg\",\"video/mp4\"],\"minduration\":2,\"protocols\":[2,5],\"maxduration\":2,\"ext\":{\"playbackmethod\":[1,2]}},\"required\":1}],\"ver\":\"1.2\"}" + }, + "id": "test-imp-id", + "ext": { + "bidder": { + "inventoryCode": "invcode", + "floor": 20 + }, + "data": { + "tag_code": "bar" + } + } + }] + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "http://tlx.3lift.net/s2sn/auction?supplier_id=20", + "body": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "native": { + "request": "{\"plcmtcnt\":1,\"plcmttype\":2,\"privacy\":1,\"context\":1,\"contextsubtype\":12,\"eventtrackers\":[{\"event\":1,\"methods\":[1,2]},{\"event\":2,\"methods\":[1]}],\"assets\":[{\"data\":{\"type\":12},\"required\":1},{\"title\":{\"len\":50},\"required\":1},{\"img\":{\"w\":80,\"h\":80,\"type\":1},\"required\":1},{\"img\":{\"w\":1200,\"h\":627,\"type\":3},\"required\":1},{\"data\":{\"type\":3},\"required\":0},{\"data\":{\"len\":100,\"type\":2},\"required\":1},{\"video\":{\"mimes\":[\"video/mpeg\",\"video/mp4\"],\"minduration\":2,\"protocols\":[2,5],\"maxduration\":2,\"ext\":{\"playbackmethod\":[1,2]}},\"required\":1}],\"ver\":\"1.2\"}" + }, + "tagid": "invcode", + "bidfloor": 20, + "ext": { + "bidder": { + "inventoryCode": "invcode", + "floor": 20 + }, + "data": { + "tag_code": "bar" + } + } + }], + "site": { + "publisher": { + "id": "foo", + "name": "foo" + } + } + }, + "impIDs": ["test-imp-id"] + }, + "mockResponse": { + "status": 204 + } + }], + "expectedBidResponses": [] +} \ No newline at end of file diff --git a/adapters/trustedstack/params_test.go b/adapters/trustedstack/params_test.go index 55812126cae..a38e0bb7227 100644 --- a/adapters/trustedstack/params_test.go +++ b/adapters/trustedstack/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/trustedstack.json diff --git a/adapters/trustedstack/trustedstack.go b/adapters/trustedstack/trustedstack.go index f79f43ffe35..7c2fd4df50a 100644 --- a/adapters/trustedstack/trustedstack.go +++ b/adapters/trustedstack/trustedstack.go @@ -7,9 +7,10 @@ import ( "net/url" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -48,7 +49,7 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } diff --git a/adapters/trustedstack/trustedstack_test.go b/adapters/trustedstack/trustedstack_test.go index c2e1742c55c..d12202802e0 100644 --- a/adapters/trustedstack/trustedstack_test.go +++ b/adapters/trustedstack/trustedstack_test.go @@ -5,9 +5,9 @@ import ( "github.com/stretchr/testify/assert" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/trustedstack/trustedstacktest/supplemental/valid-req-200-incorrect-response-format.json b/adapters/trustedstack/trustedstacktest/supplemental/valid-req-200-incorrect-response-format.json index c2cf9a06110..2852d8a2443 100644 --- a/adapters/trustedstack/trustedstacktest/supplemental/valid-req-200-incorrect-response-format.json +++ b/adapters/trustedstack/trustedstacktest/supplemental/valid-req-200-incorrect-response-format.json @@ -114,7 +114,7 @@ "expectedBidResponses": [], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go struct field Bid.seatbid.bid.price of type float64", + "value": "cannot unmarshal openrtb2.Bid.Price: invalid number", "comparison": "literal" } ] diff --git a/adapters/ucfunnel/params_test.go b/adapters/ucfunnel/params_test.go index 9bba397a084..47954e8aadb 100644 --- a/adapters/ucfunnel/params_test.go +++ b/adapters/ucfunnel/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/ucfunnel.json diff --git a/adapters/ucfunnel/ucfunnel.go b/adapters/ucfunnel/ucfunnel.go index f74e79bddcf..efee7736d42 100644 --- a/adapters/ucfunnel/ucfunnel.go +++ b/adapters/ucfunnel/ucfunnel.go @@ -7,10 +7,11 @@ import ( "net/url" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type UcfunnelAdapter struct { @@ -44,12 +45,12 @@ func (a *UcfunnelAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externa var errs []error var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } var bidReq openrtb2.BidRequest - if err := json.Unmarshal(externalRequest.Body, &bidReq); err != nil { + if err := jsonutil.Unmarshal(externalRequest.Body, &bidReq); err != nil { return nil, []error{err} } @@ -105,7 +106,7 @@ func (a *UcfunnelAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *ad func getPartnerId(request *openrtb2.BidRequest) (string, []error) { var ext ExtBidderUcfunnel var errs = []error{} - err := json.Unmarshal(request.Imp[0].Ext, &ext) + err := jsonutil.Unmarshal(request.Imp[0].Ext, &ext) if err != nil { errs = append(errs, err) return "", errs diff --git a/adapters/ucfunnel/ucfunnel_test.go b/adapters/ucfunnel/ucfunnel_test.go index 6e93c5e10ef..ec1b777c79b 100644 --- a/adapters/ucfunnel/ucfunnel_test.go +++ b/adapters/ucfunnel/ucfunnel_test.go @@ -6,9 +6,9 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/undertone/params_test.go b/adapters/undertone/params_test.go index 3144f757078..dad74a08e8c 100644 --- a/adapters/undertone/params_test.go +++ b/adapters/undertone/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/undertone/undertone.go b/adapters/undertone/undertone.go index f3b48e33eab..91b2527c6d3 100644 --- a/adapters/undertone/undertone.go +++ b/adapters/undertone/undertone.go @@ -8,10 +8,11 @@ import ( "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) const adapterId = 4 @@ -88,7 +89,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } @@ -165,7 +166,7 @@ func getImpsAndPublisherId(bidRequest *openrtb2.BidRequest) ([]openrtb2.Imp, int for _, imp := range bidRequest.Imp { var ext impExt - if err := json.Unmarshal(imp.Ext, &ext); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &ext); err != nil { errs = append(errs, getInvalidImpErr(imp.ID, err)) continue } diff --git a/adapters/undertone/undertone_test.go b/adapters/undertone/undertone_test.go index c08460e8627..45281a1d150 100644 --- a/adapters/undertone/undertone_test.go +++ b/adapters/undertone/undertone_test.go @@ -3,9 +3,9 @@ package undertone import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/unicorn/params_test.go b/adapters/unicorn/params_test.go index fd76995d1c0..89768ea8245 100644 --- a/adapters/unicorn/params_test.go +++ b/adapters/unicorn/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/unicorn/unicorn.go b/adapters/unicorn/unicorn.go index 21864d3d492..a957cff9a1c 100644 --- a/adapters/unicorn/unicorn.go +++ b/adapters/unicorn/unicorn.go @@ -8,10 +8,11 @@ import ( "github.com/buger/jsonparser" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -51,7 +52,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte Message: "COPPA is not supported", }} } - if err := json.Unmarshal(request.Regs.Ext, &extRegs); err == nil { + if err := jsonutil.Unmarshal(request.Regs.Ext, &extRegs); err == nil { if extRegs.GDPR != nil && (*extRegs.GDPR == 1) { return nil, []error{&errortypes.BadInput{ Message: "GDPR is not supported", @@ -132,7 +133,7 @@ func modifyImps(request *openrtb2.BidRequest) error { imp := &request.Imp[i] var ext unicornImpExt - err := json.Unmarshal(imp.Ext, &ext) + err := jsonutil.Unmarshal(imp.Ext, &ext) if err != nil { return &errortypes.BadInput{ @@ -214,7 +215,7 @@ func setExt(request *openrtb2.BidRequest) (json.RawMessage, error) { } var decodedExt *unicornExt - err = json.Unmarshal(request.Ext, &decodedExt) + err = jsonutil.Unmarshal(request.Ext, &decodedExt) if err != nil { decodedExt = &unicornExt{ Prebid: nil, @@ -253,7 +254,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } diff --git a/adapters/unicorn/unicorn_test.go b/adapters/unicorn/unicorn_test.go index 6c1e5aa73f2..a83951277fa 100644 --- a/adapters/unicorn/unicorn_test.go +++ b/adapters/unicorn/unicorn_test.go @@ -3,9 +3,9 @@ package unicorn import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/unicorn/unicorntest/supplemental/cannot-parse-accountid.json b/adapters/unicorn/unicorntest/supplemental/cannot-parse-accountid.json index 9ece314b485..93f038e2a0e 100644 --- a/adapters/unicorn/unicorntest/supplemental/cannot-parse-accountid.json +++ b/adapters/unicorn/unicorntest/supplemental/cannot-parse-accountid.json @@ -68,8 +68,8 @@ }, "expectedMakeRequestsErrors": [ { - "value": "Error while decoding imp[0].ext: json: cannot unmarshal string into Go struct field ExtImpUnicorn.bidder.accountId of type int", - "comparison": "literal" + "value": "Error while decoding imp[0].ext: cannot unmarshal openrtb_ext.ExtImpUnicorn.AccountID: unexpected character", + "comparison": "startswith" } ] } diff --git a/adapters/unicorn/unicorntest/supplemental/no-imp-ext.json b/adapters/unicorn/unicorntest/supplemental/no-imp-ext.json index bab6e8d9603..4acfc734f97 100644 --- a/adapters/unicorn/unicorntest/supplemental/no-imp-ext.json +++ b/adapters/unicorn/unicorntest/supplemental/no-imp-ext.json @@ -55,8 +55,8 @@ }, "expectedMakeRequestsErrors": [ { - "value": "Error while decoding imp[0].ext: unexpected end of JSON input", - "comparison": "literal" + "value": "Error while decoding imp[0].ext: expect { or n, but found", + "comparison": "startswith" } ] } diff --git a/adapters/unruly/params_test.go b/adapters/unruly/params_test.go index f8feea872c8..132afee8e1f 100644 --- a/adapters/unruly/params_test.go +++ b/adapters/unruly/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/unruly/unruly.go b/adapters/unruly/unruly.go index 97fc2b64a94..c8e73de99bf 100644 --- a/adapters/unruly/unruly.go +++ b/adapters/unruly/unruly.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -55,7 +56,7 @@ func (a *adapter) preProcess(req *openrtb2.BidRequest, errors []error) (*openrtb for i := 0; i < numRequests; i++ { imp := req.Imp[i] var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { err = &errortypes.BadInput{ Message: fmt.Sprintf("ext data not provided in imp id=%s. Abort all Request", imp.ID), } @@ -63,7 +64,7 @@ func (a *adapter) preProcess(req *openrtb2.BidRequest, errors []error) (*openrtb return nil, errors } var unrulyExt openrtb_ext.ExtImpUnruly - if err := json.Unmarshal(bidderExt.Bidder, &unrulyExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &unrulyExt); err != nil { err = &errortypes.BadInput{ Message: fmt.Sprintf("siteid not provided in imp id=%s. Abort all Request", imp.ID), } @@ -107,7 +108,7 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest }} } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: fmt.Sprintf("bad server response: %d. ", err), }} diff --git a/adapters/unruly/unruly_test.go b/adapters/unruly/unruly_test.go index 8407ba15212..e3df3d88818 100644 --- a/adapters/unruly/unruly_test.go +++ b/adapters/unruly/unruly_test.go @@ -3,9 +3,9 @@ package unruly import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/vidazoo/params_test.go b/adapters/vidazoo/params_test.go new file mode 100644 index 00000000000..cfd3e9b5d40 --- /dev/null +++ b/adapters/vidazoo/params_test.go @@ -0,0 +1,42 @@ +package vidazoo + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v3/openrtb_ext" +) + +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json schema. %v", err) + } + + for _, validParam := range validParams { + if err := validator.Validate(openrtb_ext.BidderVidazoo, json.RawMessage(validParam)); err != nil { + t.Errorf("Schema rejected valid params: %s", validParam) + } + } +} + +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json schema. %v", err) + } + + for _, p := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderVidazoo, json.RawMessage(p)); err == nil { + t.Errorf("Schema allowed invalid params: %s", p) + } + } +} + +var validParams = []string{ + `{"cId": "provided_cid_123"}`, +} + +var invalidParams = []string{ + `{"cId": 3898334}`, +} diff --git a/adapters/vidazoo/vidazoo.go b/adapters/vidazoo/vidazoo.go new file mode 100644 index 00000000000..be0cf66d9d4 --- /dev/null +++ b/adapters/vidazoo/vidazoo.go @@ -0,0 +1,134 @@ +package vidazoo + +import ( + "encoding/json" + "fmt" + "net/http" + "net/url" + "strings" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" +) + +type adapter struct { + endpoint string +} + +// Builder builds a new instance of the Vidazoo for the given bidder with the given config. +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + bidder := &adapter{ + endpoint: config.Endpoint, + } + return bidder, nil +} + +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + var requests []*adapters.RequestData + var errors []error + + requestCopy := *request + + for _, imp := range request.Imp { + requestCopy.Imp = []openrtb2.Imp{imp} + + requestJSON, err := json.Marshal(&requestCopy) + if err != nil { + errors = append(errors, fmt.Errorf("marshal bidRequest: %w", err)) + continue + } + + cId, err := extractCid(&imp) + if err != nil { + errors = append(errors, fmt.Errorf("extract cId: %w", err)) + continue + } + + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + + requestData := &adapters.RequestData{ + Method: "POST", + Uri: fmt.Sprintf("%s%s", a.endpoint, url.QueryEscape(cId)), + Body: requestJSON, + Headers: headers, + ImpIDs: []string{imp.ID}, + } + + requests = append(requests, requestData) + } + + return requests, errors +} + +func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) { + switch bid.MType { + case openrtb2.MarkupBanner: + return openrtb_ext.BidTypeBanner, nil + case openrtb2.MarkupVideo: + return openrtb_ext.BidTypeVideo, nil + } + return "", &errortypes.BadInput{ + Message: fmt.Sprintf("Could not define bid type for imp: %s", bid.ImpID), + } +} + +func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { + var errs []error + + if adapters.IsResponseStatusCodeNoContent(responseData) { + return nil, nil + } + + if err := adapters.CheckResponseStatusCodeForErrors(responseData); err != nil { + return nil, []error{&errortypes.BadInput{ + Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info", responseData.StatusCode), + }} + } + + var response openrtb2.BidResponse + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { + return nil, []error{&errortypes.BadServerResponse{ + Message: fmt.Sprintf("bad server response: %d. ", err), + }} + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(response.SeatBid)) + + if response.Cur != "" { + bidResponse.Currency = response.Cur + } + + for _, seatBid := range response.SeatBid { + for i, bid := range seatBid.Bid { + bidType, err := getMediaTypeForBid(bid) + if err != nil { + errs = append(errs, err) + continue + } + bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ + Bid: &seatBid.Bid[i], + BidType: bidType, + }) + } + } + + return bidResponse, errs +} + +func extractCid(imp *openrtb2.Imp) (string, error) { + var bidderExt adapters.ExtImpBidder + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { + return "", fmt.Errorf("unmarshal bidderExt: %w", err) + } + + var impExt openrtb_ext.ImpExtVidazoo + if err := jsonutil.Unmarshal(bidderExt.Bidder, &impExt); err != nil { + return "", fmt.Errorf("unmarshal ImpExtVidazoo: %w", err) + } + return strings.TrimSpace(impExt.ConnectionId), nil +} diff --git a/adapters/vidazoo/vidazoo_test.go b/adapters/vidazoo/vidazoo_test.go new file mode 100644 index 00000000000..5d6090de95c --- /dev/null +++ b/adapters/vidazoo/vidazoo_test.go @@ -0,0 +1,24 @@ +package vidazoo + +import ( + "testing" + + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderVidazoo, config.Adapter{ + Endpoint: "http://prebid-server.cootlogix.com/openrtb/", + }, + config.Server{ + ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2", + }) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "vidazootest", bidder) +} diff --git a/adapters/vidazoo/vidazootest/exemplary/banner.json b/adapters/vidazoo/vidazootest/exemplary/banner.json new file mode 100644 index 00000000000..98b145181f4 --- /dev/null +++ b/adapters/vidazoo/vidazootest/exemplary/banner.json @@ -0,0 +1,127 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "site": { + "page": "prebid.org" + }, + "imp": [ + { + "id": "some-impression-id", + "banner": { + "w": 240, + "h": 400 + }, + "ext": { + "bidder": { + "cId": "test_cid_123" + } + } + } + ], + "tmax": 5000 + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://prebid-server.cootlogix.com/openrtb/test_cid_123", + "body": { + "id": "some-request-id", + "site": { + "page": "prebid.org" + }, + "imp": [ + { + "id": "some-impression-id", + "banner": { + "w": 240, + "h": 400 + }, + "ext": { + "bidder": { + "cId": "test_cid_123" + } + } + } + ], + "tmax": 5000 + }, + "impIDs": [ + "some-impression-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "some-request-id", + "cur": "", + "bidid": "some-bid-id", + "seatbid": [ + { + "bid": [ + { + "exp": 60, + "adm": "
Some creative
", + "burl": "", + "iurl": "http://prebid-server.cootlogix.com/creative.jpg", + "lurl": "", + "nurl": "", + "id": "some-bid-id", + "impid": "some-impression-id", + "h": 400, + "w": 240, + "price": 1, + "dealid": "deal123", + "adomain": [ + "test.com" + ], + "adid": "some-ad-id", + "cid": "test", + "attr": [], + "cat": [], + "crid": "some-creative-id", + "ext": {}, + "hratio": 0, + "language": "", + "protocol": 0, + "qagmediarating": 0, + "tactic": "", + "wratio": 0, + "mtype": 1 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "some-bid-id", + "impid": "some-impression-id", + "price": 1, + "adm": "
Some creative
", + "adid": "some-ad-id", + "cid": "test", + "iurl": "http://prebid-server.cootlogix.com/creative.jpg", + "crid": "some-creative-id", + "adomain": [ + "test.com" + ], + "dealid": "deal123", + "w": 240, + "h": 400, + "exp": 60, + "ext": {}, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ], + "expectedMakeBidsErrors": [] +} \ No newline at end of file diff --git a/adapters/vidazoo/vidazootest/exemplary/multi-imp.json b/adapters/vidazoo/vidazootest/exemplary/multi-imp.json new file mode 100644 index 00000000000..7c0f288f3c8 --- /dev/null +++ b/adapters/vidazoo/vidazootest/exemplary/multi-imp.json @@ -0,0 +1,265 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "site": { + "page": "prebid.org" + }, + "imp": [ + { + "id": "some-impression-id", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 1, + "maxduration": 2, + "protocols": [ + 1, + 2, + 5 + ], + "w": 300, + "h": 250, + "startdelay": 1, + "placement": 1, + "playbackmethod": [ + 2 + ], + "api": [ + 1, + 2, + 3, + 4 + ] + }, + "ext": { + "bidder": { + "cId": "test_cid_123" + } + } + }, + { + "id": "some-impression-id", + "banner": { + "w": 240, + "h": 400 + }, + "ext": { + "bidder": { + "cId": "test_cid_123" + } + } + } + ], + "tmax": 5000 + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://prebid-server.cootlogix.com/openrtb/test_cid_123", + "body": { + "id": "some-request-id", + "site": { + "page": "prebid.org" + }, + "imp": [ + { + "id": "some-impression-id", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 1, + "maxduration": 2, + "protocols": [ + 1, + 2, + 5 + ], + "w": 300, + "h": 250, + "startdelay": 1, + "placement": 1, + "playbackmethod": [ + 2 + ], + "api": [ + 1, + 2, + 3, + 4 + ] + }, + "ext": { + "bidder": { + "cId": "test_cid_123" + } + } + } + ], + "tmax": 5000 + }, + "impIDs": [ + "some-impression-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "some-request-id", + "cur": "", + "bidid": "some-bid-id", + "seatbid": [ + { + "bid": [ + { + "exp": 60, + "adm": "Some Ad SystemSome Ad Title00:00:02", + "id": "some-bid-id", + "impid": "some-impression-id", + "h": 250, + "w": 300, + "price": 1, + "dealid": "deal123", + "adomain": [ + "test.com" + ], + "adid": "some-ad-id", + "cid": "test", + "crid": "some-creative-id", + "mtype": 2 + } + ] + } + ] + } + } + }, + { + "expectedRequest": { + "uri": "http://prebid-server.cootlogix.com/openrtb/test_cid_123", + "body": { + "id": "some-request-id", + "site": { + "page": "prebid.org" + }, + "imp": [ + { + "id": "some-impression-id", + "banner": { + "w": 240, + "h": 400 + }, + "ext": { + "bidder": { + "cId": "test_cid_123" + } + } + } + ], + "tmax": 5000 + }, + "impIDs": [ + "some-impression-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "some-request-id", + "cur": "", + "bidid": "some-bid-id", + "seatbid": [ + { + "bid": [ + { + "exp": 60, + "adm": "
Some creative
", + "burl": "", + "iurl": "http://prebid-server.cootlogix.com/creative.jpg", + "lurl": "", + "nurl": "", + "id": "some-bid-id", + "impid": "some-impression-id", + "h": 400, + "w": 240, + "price": 1, + "dealid": "deal123", + "adomain": [ + "test.com" + ], + "adid": "some-ad-id", + "cid": "test", + "attr": [], + "cat": [], + "crid": "some-creative-id", + "ext": {}, + "hratio": 0, + "language": "", + "protocol": 0, + "qagmediarating": 0, + "tactic": "", + "wratio": 0, + "mtype": 1 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "exp": 60, + "adm": "Some Ad SystemSome Ad Title00:00:02", + "id": "some-bid-id", + "impid": "some-impression-id", + "h": 250, + "w": 300, + "price": 1, + "dealid": "deal123", + "adomain": [ + "test.com" + ], + "adid": "some-ad-id", + "cid": "test", + "crid": "some-creative-id", + "mtype": 2 + }, + "type": "video" + } + ] + }, + { + "bids": [ + { + "bid": { + "id": "some-bid-id", + "impid": "some-impression-id", + "price": 1, + "adm": "
Some creative
", + "adid": "some-ad-id", + "cid": "test", + "iurl": "http://prebid-server.cootlogix.com/creative.jpg", + "crid": "some-creative-id", + "adomain": [ + "test.com" + ], + "dealid": "deal123", + "w": 240, + "h": 400, + "exp": 60, + "ext": {}, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ], + "expectedMakeBidsErrors": [] +} \ No newline at end of file diff --git a/adapters/vidazoo/vidazootest/exemplary/video.json b/adapters/vidazoo/vidazootest/exemplary/video.json new file mode 100644 index 00000000000..2a414476382 --- /dev/null +++ b/adapters/vidazoo/vidazootest/exemplary/video.json @@ -0,0 +1,154 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "site": { + "page": "prebid.org" + }, + "imp": [ + { + "id": "some-impression-id", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 1, + "maxduration": 2, + "protocols": [ + 1, + 2, + 5 + ], + "w": 300, + "h": 250, + "startdelay": 1, + "placement": 1, + "playbackmethod": [ + 2 + ], + "api": [ + 1, + 2, + 3, + 4 + ] + }, + "ext": { + "bidder": { + "cId": "test_cid_123" + } + } + } + ], + "tmax": 5000 + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://prebid-server.cootlogix.com/openrtb/test_cid_123", + "body": { + "id": "some-request-id", + "site": { + "page": "prebid.org" + }, + "imp": [ + { + "id": "some-impression-id", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 1, + "maxduration": 2, + "protocols": [ + 1, + 2, + 5 + ], + "w": 300, + "h": 250, + "startdelay": 1, + "placement": 1, + "playbackmethod": [ + 2 + ], + "api": [ + 1, + 2, + 3, + 4 + ] + }, + "ext": { + "bidder": { + "cId": "test_cid_123" + } + } + } + ], + "tmax": 5000 + }, + "impIDs": [ + "some-impression-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "some-request-id", + "cur": "", + "bidid": "some-bid-id", + "seatbid": [ + { + "bid": [ + { + "exp": 60, + "adm": "Some Ad SystemSome Ad Title00:00:02", + "id": "some-bid-id", + "impid": "some-impression-id", + "h": 250, + "w": 300, + "price": 1, + "dealid": "deal123", + "adomain": [ + "test.com" + ], + "adid": "some-ad-id", + "cid": "test", + "crid": "some-creative-id", + "mtype": 2 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "exp": 60, + "adm": "Some Ad SystemSome Ad Title00:00:02", + "id": "some-bid-id", + "impid": "some-impression-id", + "h": 250, + "w": 300, + "price": 1, + "dealid": "deal123", + "adomain": [ + "test.com" + ], + "adid": "some-ad-id", + "cid": "test", + "crid": "some-creative-id", + "mtype": 2 + }, + "type": "video" + } + ] + } + ], + "expectedMakeBidsErrors": [] +} \ No newline at end of file diff --git a/adapters/vidazoo/vidazootest/supplemental/bad-request.json b/adapters/vidazoo/vidazootest/supplemental/bad-request.json new file mode 100644 index 00000000000..864fe64c619 --- /dev/null +++ b/adapters/vidazoo/vidazootest/supplemental/bad-request.json @@ -0,0 +1,65 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "site": { + "page": "prebid.org" + }, + "imp": [ + { + "id": "some-impression-id", + "banner": { + "w": 240, + "h": 400 + }, + "ext": { + "bidder": { + "cid": "test_cid_123" + } + } + } + ], + "tmax": 5000 + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://prebid-server.cootlogix.com/openrtb/test_cid_123", + "body": { + "id": "some-request-id", + "site": { + "page": "prebid.org" + }, + "imp": [ + { + "id": "some-impression-id", + "banner": { + "w": 240, + "h": 400 + }, + "ext": { + "bidder": { + "cid": "test_cid_123" + } + } + } + ], + "tmax": 5000 + }, + "impIDs": [ + "some-impression-id" + ] + }, + "mockResponse": { + "status": 400, + "body": {} + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/vidazoo/vidazootest/supplemental/internal-error.json b/adapters/vidazoo/vidazootest/supplemental/internal-error.json new file mode 100644 index 00000000000..92dc89f08c0 --- /dev/null +++ b/adapters/vidazoo/vidazootest/supplemental/internal-error.json @@ -0,0 +1,65 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "site": { + "page": "prebid.org" + }, + "imp": [ + { + "id": "some-impression-id", + "banner": { + "w": 240, + "h": 400 + }, + "ext": { + "bidder": { + "cid": "test_cid_123" + } + } + } + ], + "tmax": 5000 + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://prebid-server.cootlogix.com/openrtb/test_cid_123", + "body": { + "id": "some-request-id", + "site": { + "page": "prebid.org" + }, + "imp": [ + { + "id": "some-impression-id", + "banner": { + "w": 240, + "h": 400 + }, + "ext": { + "bidder": { + "cid": "test_cid_123" + } + } + } + ], + "tmax": 5000 + }, + "impIDs": [ + "some-impression-id" + ] + }, + "mockResponse": { + "status": 500, + "body": {} + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 500. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/vidazoo/vidazootest/supplemental/no-content.json b/adapters/vidazoo/vidazootest/supplemental/no-content.json new file mode 100644 index 00000000000..6d8e7e9bec1 --- /dev/null +++ b/adapters/vidazoo/vidazootest/supplemental/no-content.json @@ -0,0 +1,60 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "site": { + "page": "prebid.org" + }, + "imp": [ + { + "id": "some-impression-id", + "banner": { + "w": 240, + "h": 400 + }, + "ext": { + "bidder": { + "cid": "test_cid_123" + } + } + } + ], + "tmax": 5000 + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://prebid-server.cootlogix.com/openrtb/test_cid_123", + "body": { + "id": "some-request-id", + "site": { + "page": "prebid.org" + }, + "imp": [ + { + "id": "some-impression-id", + "banner": { + "w": 240, + "h": 400 + }, + "ext": { + "bidder": { + "cid": "test_cid_123" + } + } + } + ], + "tmax": 5000 + }, + "impIDs": [ + "some-impression-id" + ] + }, + "mockResponse": { + "status": 204, + "body": {} + } + } + ], + "expectedBidResponses": [], + "expectedMakeBidsErrors": [] +} \ No newline at end of file diff --git a/adapters/vidazoo/vidazootest/supplemental/unknown-bid-type.json b/adapters/vidazoo/vidazootest/supplemental/unknown-bid-type.json new file mode 100644 index 00000000000..5f3ec80799e --- /dev/null +++ b/adapters/vidazoo/vidazootest/supplemental/unknown-bid-type.json @@ -0,0 +1,109 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "site": { + "page": "prebid.org" + }, + "imp": [ + { + "id": "some-impression-id", + "banner": { + "w": 240, + "h": 400 + }, + "ext": { + "bidder": { + "cId": "test_cid_123" + } + } + } + ], + "tmax": 5000 + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://prebid-server.cootlogix.com/openrtb/test_cid_123", + "body": { + "id": "some-request-id", + "site": { + "page": "prebid.org" + }, + "imp": [ + { + "id": "some-impression-id", + "banner": { + "w": 240, + "h": 400 + }, + "ext": { + "bidder": { + "cId": "test_cid_123" + } + } + } + ], + "tmax": 5000 + }, + "impIDs": [ + "some-impression-id" + ] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "some-request-id", + "cur": "", + "bidid": "some-bid-id", + "seatbid": [ + { + "bid": [ + { + "exp": 60, + "adm": "
Some creative
", + "burl": "", + "iurl": "http://prebid-server.cootlogix.com/creative.jpg", + "lurl": "", + "nurl": "", + "id": "some-bid-id", + "impid": "some-impression-id", + "h": 400, + "w": 240, + "price": 1, + "dealid": "deal123", + "adomain": [ + "test.com" + ], + "adid": "some-ad-id", + "cid": "test", + "attr": [], + "cat": [], + "crid": "some-creative-id", + "ext": {}, + "hratio": 0, + "language": "", + "protocol": 0, + "qagmediarating": 0, + "tactic": "", + "wratio": 0, + "mtype": 8 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [] + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Could not define bid type for imp: some-impression-id", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/videobyte/params_test.go b/adapters/videobyte/params_test.go index dbc815fd76d..ffb37f88d97 100644 --- a/adapters/videobyte/params_test.go +++ b/adapters/videobyte/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/videobyte.json diff --git a/adapters/videobyte/videobyte.go b/adapters/videobyte/videobyte.go index d9e2d4e4be2..ed79c6525bd 100644 --- a/adapters/videobyte/videobyte.go +++ b/adapters/videobyte/videobyte.go @@ -6,10 +6,11 @@ import ( "net/http" "net/url" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" "github.com/prebid/openrtb/v20/openrtb2" ) @@ -75,7 +76,7 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest } var ortbResponse openrtb2.BidResponse - err := json.Unmarshal(response.Body, &ortbResponse) + err := jsonutil.Unmarshal(response.Body, &ortbResponse) if err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: "Bad Server Response", @@ -141,14 +142,14 @@ func getHeaders(request *openrtb2.BidRequest) http.Header { func parseExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpVideoByte, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: fmt.Sprintf("Ignoring imp id=%s, error while decoding extImpBidder, err: %s", imp.ID, err), } } impExt := openrtb_ext.ExtImpVideoByte{} - err := json.Unmarshal(bidderExt.Bidder, &impExt) + err := jsonutil.Unmarshal(bidderExt.Bidder, &impExt) if err != nil { return nil, &errortypes.BadInput{ Message: fmt.Sprintf("Ignoring imp id=%s, error while decoding impExt, err: %s", imp.ID, err), diff --git a/adapters/videobyte/videobyte_test.go b/adapters/videobyte/videobyte_test.go index 9e566a20ef2..2d1d2a07fda 100644 --- a/adapters/videobyte/videobyte_test.go +++ b/adapters/videobyte/videobyte_test.go @@ -3,9 +3,9 @@ package videobyte import ( "testing" - "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v3/config" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/videobyte/videobytetest/supplemental/invalid-imp-ext-bidder.json b/adapters/videobyte/videobytetest/supplemental/invalid-imp-ext-bidder.json index 1b806ed57ab..d7d8460bb1b 100644 --- a/adapters/videobyte/videobytetest/supplemental/invalid-imp-ext-bidder.json +++ b/adapters/videobyte/videobytetest/supplemental/invalid-imp-ext-bidder.json @@ -38,7 +38,7 @@ }, "expectedMakeRequestsErrors": [ { - "value": "Ignoring imp id=test-imp-id, error while decoding impExt, err: json: cannot unmarshal string into Go value of type openrtb_ext.ExtImpVideoByte", + "value": "Ignoring imp id=test-imp-id, error while decoding impExt, err: expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/videobyte/videobytetest/supplemental/invalid-imp-ext.json b/adapters/videobyte/videobytetest/supplemental/invalid-imp-ext.json index 199f4c5570c..a24ea9b924f 100644 --- a/adapters/videobyte/videobytetest/supplemental/invalid-imp-ext.json +++ b/adapters/videobyte/videobytetest/supplemental/invalid-imp-ext.json @@ -36,7 +36,7 @@ }, "expectedMakeRequestsErrors": [ { - "value": "Ignoring imp id=test-imp-id, error while decoding extImpBidder, err: json: cannot unmarshal string into Go value of type adapters.ExtImpBidder", + "value": "Ignoring imp id=test-imp-id, error while decoding extImpBidder, err: expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/videoheroes/params_test.go b/adapters/videoheroes/params_test.go index 66e1e6a2788..e8af1f1fcf5 100644 --- a/adapters/videoheroes/params_test.go +++ b/adapters/videoheroes/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/videoheroes/videoheroes.go b/adapters/videoheroes/videoheroes.go index 89bbb9c8162..8d1d7450cb3 100755 --- a/adapters/videoheroes/videoheroes.go +++ b/adapters/videoheroes/videoheroes.go @@ -7,11 +7,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -67,13 +68,13 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte func (a *adapter) getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpVideoHeroes, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: "ext.bidder not provided", } } var videoHeroesExt openrtb_ext.ExtImpVideoHeroes - if err := json.Unmarshal(bidderExt.Bidder, &videoHeroesExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &videoHeroesExt); err != nil { return nil, &errortypes.BadInput{ Message: "ext.bidder not provided", } @@ -118,7 +119,7 @@ func (a *adapter) MakeBids( } var bidResponse openrtb2.BidResponse - if err := json.Unmarshal(bidderResponse.Body, &bidResponse); err != nil { + if err := jsonutil.Unmarshal(bidderResponse.Body, &bidResponse); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: "Bad Server Response", }} diff --git a/adapters/videoheroes/videoheroes_test.go b/adapters/videoheroes/videoheroes_test.go index 7c0b2268f51..3545b601dc6 100644 --- a/adapters/videoheroes/videoheroes_test.go +++ b/adapters/videoheroes/videoheroes_test.go @@ -3,9 +3,9 @@ package videoheroes import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/vidoomy/params_test.go b/adapters/vidoomy/params_test.go index 40c17029f9e..b3801c637c8 100644 --- a/adapters/vidoomy/params_test.go +++ b/adapters/vidoomy/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/vidoomy.json diff --git a/adapters/vidoomy/vidoomy.go b/adapters/vidoomy/vidoomy.go index d5538019a3e..b39448a4143 100644 --- a/adapters/vidoomy/vidoomy.go +++ b/adapters/vidoomy/vidoomy.go @@ -7,11 +7,12 @@ import ( "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/ptrutil" ) type adapter struct { @@ -117,7 +118,7 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: fmt.Sprintf("Bad server response: %d.", err), }} diff --git a/adapters/vidoomy/vidoomy_test.go b/adapters/vidoomy/vidoomy_test.go index 7acc477ae1c..ef561b596b6 100644 --- a/adapters/vidoomy/vidoomy_test.go +++ b/adapters/vidoomy/vidoomy_test.go @@ -5,9 +5,9 @@ import ( "github.com/stretchr/testify/assert" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestVidoomyBidderEndpointConfig(t *testing.T) { diff --git a/adapters/visiblemeasures/params_test.go b/adapters/visiblemeasures/params_test.go index ed74ef1ad35..b4e5bb66c1d 100644 --- a/adapters/visiblemeasures/params_test.go +++ b/adapters/visiblemeasures/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/visiblemeasures/visiblemeasures.go b/adapters/visiblemeasures/visiblemeasures.go index 4a461d2d8f7..100ba03e59b 100644 --- a/adapters/visiblemeasures/visiblemeasures.go +++ b/adapters/visiblemeasures/visiblemeasures.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -44,10 +45,10 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E var bidderExt adapters.ExtImpBidder var visiblemeasuresExt openrtb_ext.ImpExtVisibleMeasures - if err = json.Unmarshal(reqCopy.Imp[0].Ext, &bidderExt); err != nil { + if err = jsonutil.Unmarshal(reqCopy.Imp[0].Ext, &bidderExt); err != nil { return nil, []error{err} } - if err = json.Unmarshal(bidderExt.Bidder, &visiblemeasuresExt); err != nil { + if err = jsonutil.Unmarshal(bidderExt.Bidder, &visiblemeasuresExt); err != nil { return nil, []error{err} } @@ -111,7 +112,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } diff --git a/adapters/visiblemeasures/visiblemeasures_test.go b/adapters/visiblemeasures/visiblemeasures_test.go index 8970ccb1e43..82038938358 100644 --- a/adapters/visiblemeasures/visiblemeasures_test.go +++ b/adapters/visiblemeasures/visiblemeasures_test.go @@ -3,9 +3,9 @@ package visiblemeasures import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/visiblemeasures/visiblemeasurestest/supplemental/bad_response.json b/adapters/visiblemeasures/visiblemeasurestest/supplemental/bad_response.json index c732ba92c67..5cc4a338ac3 100644 --- a/adapters/visiblemeasures/visiblemeasurestest/supplemental/bad_response.json +++ b/adapters/visiblemeasures/visiblemeasurestest/supplemental/bad_response.json @@ -78,7 +78,7 @@ }], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/visx/params_test.go b/adapters/visx/params_test.go index 0646d221e27..1355d6f8d93 100644 --- a/adapters/visx/params_test.go +++ b/adapters/visx/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/visx/visx.go b/adapters/visx/visx.go index 2cd3dfc5370..85f3c300a2d 100644 --- a/adapters/visx/visx.go +++ b/adapters/visx/visx.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type VisxAdapter struct { @@ -107,7 +108,7 @@ func (a *VisxAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalReq } var bidResp visxResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } @@ -146,7 +147,7 @@ func getMediaTypeForImp(impID string, imps []openrtb2.Imp, bid visxBid) (openrtb for _, imp := range imps { if imp.ID == impID { var ext visxBidExt - if err := json.Unmarshal(bid.Ext, &ext); err == nil { + if err := jsonutil.Unmarshal(bid.Ext, &ext); err == nil { if ext.Prebid.Meta.MediaType == openrtb_ext.BidTypeBanner { return openrtb_ext.BidTypeBanner, nil } diff --git a/adapters/visx/visx_test.go b/adapters/visx/visx_test.go index 8cdccc2e653..d2adffddcea 100644 --- a/adapters/visx/visx_test.go +++ b/adapters/visx/visx_test.go @@ -3,9 +3,9 @@ package visx import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/visx/visxtest/supplemental/bad_response.json b/adapters/visx/visxtest/supplemental/bad_response.json index e905068b7ea..21da96d8783 100644 --- a/adapters/visx/visxtest/supplemental/bad_response.json +++ b/adapters/visx/visxtest/supplemental/bad_response.json @@ -56,7 +56,7 @@ "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type visx.visxResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/vox/params_test.go b/adapters/vox/params_test.go index e23a57d9b30..536503555e8 100644 --- a/adapters/vox/params_test.go +++ b/adapters/vox/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/vox/vox.go b/adapters/vox/vox.go index 1a04d1fbf72..3e5f03aa6ee 100644 --- a/adapters/vox/vox.go +++ b/adapters/vox/vox.go @@ -5,9 +5,10 @@ import ( "fmt" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -47,7 +48,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } diff --git a/adapters/vox/vox_test.go b/adapters/vox/vox_test.go index dfb345b2e02..dce89de3afb 100644 --- a/adapters/vox/vox_test.go +++ b/adapters/vox/vox_test.go @@ -3,9 +3,9 @@ package vox import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/vrtcal/params_test.go b/adapters/vrtcal/params_test.go index 0e30dd6fcc9..8ba180db2b8 100644 --- a/adapters/vrtcal/params_test.go +++ b/adapters/vrtcal/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) //Vrtcal doesn't currently require any custom fields. This file is included for conformity only diff --git a/adapters/vrtcal/vrtcal.go b/adapters/vrtcal/vrtcal.go index 0f6f27eb23b..e0df0bca954 100644 --- a/adapters/vrtcal/vrtcal.go +++ b/adapters/vrtcal/vrtcal.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type VrtcalAdapter struct { @@ -63,7 +64,7 @@ func (a *VrtcalAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalR var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } diff --git a/adapters/vrtcal/vrtcal_test.go b/adapters/vrtcal/vrtcal_test.go index a4ba917922f..59d29aaee31 100644 --- a/adapters/vrtcal/vrtcal_test.go +++ b/adapters/vrtcal/vrtcal_test.go @@ -3,9 +3,9 @@ package vrtcal import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/vungle/param_test.go b/adapters/vungle/param_test.go index ff73b5ef960..7053669edf4 100644 --- a/adapters/vungle/param_test.go +++ b/adapters/vungle/param_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/vungle/vungle.go b/adapters/vungle/vungle.go index 9d479b81e31..6e6967fc227 100644 --- a/adapters/vungle/vungle.go +++ b/adapters/vungle/vungle.go @@ -8,9 +8,10 @@ import ( "strings" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) const SupportedCurrency = "USD" @@ -52,14 +53,14 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte } var impExt vungleImpressionExt - if err := json.Unmarshal(imp.Ext, &impExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &impExt); err != nil { errs = append(errs, fmt.Errorf("failed unmarshalling imp ext (err)%s", err.Error())) continue } // get placement_reference_id & pub_app_store_id var bidderImpExt openrtb_ext.ImpExtVungle - if err := json.Unmarshal(impExt.Bidder, &bidderImpExt); err != nil { + if err := jsonutil.Unmarshal(impExt.Bidder, &bidderImpExt); err != nil { errs = append(errs, fmt.Errorf("failed unmarshalling bidder imp ext (err)%s", err.Error())) continue } @@ -127,7 +128,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } diff --git a/adapters/vungle/vungle_test.go b/adapters/vungle/vungle_test.go index 6200924eea3..740208dbe0c 100644 --- a/adapters/vungle/vungle_test.go +++ b/adapters/vungle/vungle_test.go @@ -3,9 +3,9 @@ package vungle import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/xeworks/params_test.go b/adapters/xeworks/params_test.go index 1c14b3a0989..0ce8d99f48f 100644 --- a/adapters/xeworks/params_test.go +++ b/adapters/xeworks/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) var validParams = []string{ diff --git a/adapters/xeworks/xeworks.go b/adapters/xeworks/xeworks.go index 458087ece23..bd9d1795283 100644 --- a/adapters/xeworks/xeworks.go +++ b/adapters/xeworks/xeworks.go @@ -7,11 +7,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type bidType struct { @@ -41,14 +42,14 @@ func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server co func (a *adapter) buildEndpointFromRequest(imp *openrtb2.Imp) (string, error) { var impExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &impExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &impExt); err != nil { return "", &errortypes.BadInput{ Message: fmt.Sprintf("Failed to deserialize bidder impression extension: %v", err), } } var xeworksExt openrtb_ext.ExtXeworks - if err := json.Unmarshal(impExt.Bidder, &xeworksExt); err != nil { + if err := jsonutil.Unmarshal(impExt.Bidder, &xeworksExt); err != nil { return "", &errortypes.BadInput{ Message: fmt.Sprintf("Failed to deserialize Xeworks extension: %v", err), } @@ -116,7 +117,7 @@ func (a *adapter) MakeBids(openRTBRequest *openrtb2.BidRequest, requestToBidder } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(bidderRawResponse.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(bidderRawResponse.Body, &bidResp); err != nil { return nil, []error{err} } @@ -136,7 +137,7 @@ func prepareBidResponse(seats []openrtb2.SeatBid) (*adapters.BidderResponse, []e for _, seatBid := range seats { for bidId, bid := range seatBid.Bid { var bidExt bidExt - if err := json.Unmarshal(bid.Ext, &bidExt); err != nil { + if err := jsonutil.Unmarshal(bid.Ext, &bidExt); err != nil { errs = append(errs, &errortypes.BadServerResponse{ Message: fmt.Sprintf("Failed to parse Bid[%d].Ext: %s", bidId, err.Error()), }) diff --git a/adapters/xeworks/xeworks_test.go b/adapters/xeworks/xeworks_test.go index db7e26c9bae..842045af1d9 100644 --- a/adapters/xeworks/xeworks_test.go +++ b/adapters/xeworks/xeworks_test.go @@ -3,9 +3,9 @@ package xeworks import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/xeworks/xeworkstest/supplemental/bad-response.json b/adapters/xeworks/xeworkstest/supplemental/bad-response.json index e91040e9799..ecfa343be36 100644 --- a/adapters/xeworks/xeworkstest/supplemental/bad-response.json +++ b/adapters/xeworks/xeworkstest/supplemental/bad-response.json @@ -99,7 +99,7 @@ ], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ], diff --git a/adapters/xeworks/xeworkstest/supplemental/invalid-ext-bidder-object.json b/adapters/xeworks/xeworkstest/supplemental/invalid-ext-bidder-object.json index fe7fd9c8b19..77347bfd3d7 100644 --- a/adapters/xeworks/xeworkstest/supplemental/invalid-ext-bidder-object.json +++ b/adapters/xeworks/xeworkstest/supplemental/invalid-ext-bidder-object.json @@ -42,7 +42,7 @@ "httpCalls": [], "expectedMakeRequestsErrors": [ { - "value": "Failed to deserialize Xeworks extension: json: cannot unmarshal array into Go value of type openrtb_ext.ExtXeworks", + "value": "Failed to deserialize Xeworks extension: expect { or n, but found [", "comparison": "literal" } ] diff --git a/adapters/xeworks/xeworkstest/supplemental/invalid-ext-object.json b/adapters/xeworks/xeworkstest/supplemental/invalid-ext-object.json index aa215eb3e34..16cf58bbe54 100644 --- a/adapters/xeworks/xeworkstest/supplemental/invalid-ext-object.json +++ b/adapters/xeworks/xeworkstest/supplemental/invalid-ext-object.json @@ -40,7 +40,7 @@ "httpCalls": [], "expectedMakeRequestsErrors": [ { - "value": "Failed to deserialize bidder impression extension: json: cannot unmarshal string into Go value of type adapters.ExtImpBidder", + "value": "Failed to deserialize bidder impression extension: expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/yahooAds/params_test.go b/adapters/yahooAds/params_test.go index dbbc2c84adb..42a5c16ae75 100644 --- a/adapters/yahooAds/params_test.go +++ b/adapters/yahooAds/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/yahooAds.json diff --git a/adapters/yahooAds/yahooAds.go b/adapters/yahooAds/yahooAds.go index dddeddcce21..4a03bc3e7fc 100644 --- a/adapters/yahooAds/yahooAds.go +++ b/adapters/yahooAds/yahooAds.go @@ -6,11 +6,12 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/ptrutil" ) type adapter struct { @@ -33,7 +34,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E for idx, imp := range request.Imp { var bidderExt adapters.ExtImpBidder - err := json.Unmarshal(imp.Ext, &bidderExt) + err := jsonutil.Unmarshal(imp.Ext, &bidderExt) if err != nil { err = &errortypes.BadInput{ Message: fmt.Sprintf("imp #%d: ext.bidder not provided", idx), @@ -43,7 +44,7 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.E } var yahooAdsExt openrtb_ext.ExtImpYahooAds - err = json.Unmarshal(bidderExt.Bidder, &yahooAdsExt) + err = jsonutil.Unmarshal(bidderExt.Bidder, &yahooAdsExt) if err != nil { err = &errortypes.BadInput{ Message: fmt.Sprintf("imp #%d: %s", idx, err.Error()), @@ -101,7 +102,7 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: fmt.Sprintf("Bad server response: %d.", err), }} @@ -177,7 +178,7 @@ func changeRequestForBidService(request *openrtb2.BidRequest, extension *openrtb requestRegs.Ext = json.RawMessage("{}") } var regsExt map[string]json.RawMessage - err := json.Unmarshal(requestRegs.Ext, ®sExt) + err := jsonutil.Unmarshal(requestRegs.Ext, ®sExt) if err != nil { return err } diff --git a/adapters/yahooAds/yahooAds_test.go b/adapters/yahooAds/yahooAds_test.go index ae9103d141e..0eaf711faf3 100644 --- a/adapters/yahooAds/yahooAds_test.go +++ b/adapters/yahooAds/yahooAds_test.go @@ -5,9 +5,9 @@ import ( "github.com/stretchr/testify/assert" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestYahooAdsBidderEndpointConfig(t *testing.T) { diff --git a/adapters/yandex/params_test.go b/adapters/yandex/params_test.go index e65c82ff159..0805be19889 100644 --- a/adapters/yandex/params_test.go +++ b/adapters/yandex/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/yandex/yandex.go b/adapters/yandex/yandex.go index 7d40dc85a7a..5a017c2bd65 100644 --- a/adapters/yandex/yandex.go +++ b/adapters/yandex/yandex.go @@ -10,11 +10,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) const ( @@ -131,14 +132,14 @@ func splitRequestDataByImp(request *openrtb2.BidRequest, imp openrtb2.Imp) openr func getYandexPlacementId(imp openrtb2.Imp) (*yandexPlacementID, error) { var ext adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &ext); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &ext); err != nil { return nil, &errortypes.BadInput{ Message: fmt.Sprintf("imp %s: unable to unmarshal ext", imp.ID), } } var yandexExt openrtb_ext.ExtImpYandex - if err := json.Unmarshal(ext.Bidder, &yandexExt); err != nil { + if err := jsonutil.Unmarshal(ext.Bidder, &yandexExt); err != nil { return nil, &errortypes.BadInput{ Message: fmt.Sprintf("imp %s: unable to unmarshal ext.bidder: %v", imp.ID, err), } @@ -280,7 +281,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, _ *adapters.RequestData } var bidResponse openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &bidResponse); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &bidResponse); err != nil { return nil, []error{&errortypes.BadServerResponse{ Message: fmt.Sprintf("Bad server response: %d", err), }} diff --git a/adapters/yandex/yandex_test.go b/adapters/yandex/yandex_test.go index 6978cd8bb54..7635b1a1b93 100644 --- a/adapters/yandex/yandex_test.go +++ b/adapters/yandex/yandex_test.go @@ -3,9 +3,9 @@ package yandex import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/yeahmobi/params_test.go b/adapters/yeahmobi/params_test.go index 805be75da30..2b47316df2d 100644 --- a/adapters/yeahmobi/params_test.go +++ b/adapters/yeahmobi/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/yeahmobi/yeahmobi.go b/adapters/yeahmobi/yeahmobi.go index b533e76b19a..934cee5c27b 100644 --- a/adapters/yeahmobi/yeahmobi.go +++ b/adapters/yeahmobi/yeahmobi.go @@ -8,11 +8,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -85,7 +86,7 @@ func transform(request *openrtb2.BidRequest) { if imp.Native != nil { var nativeRequest map[string]interface{} nativeCopyRequest := make(map[string]interface{}) - err := json.Unmarshal([]byte(request.Imp[i].Native.Request), &nativeRequest) + err := jsonutil.Unmarshal([]byte(request.Imp[i].Native.Request), &nativeRequest) //just ignore the bad native request if err == nil { _, exists := nativeRequest["native"] @@ -114,12 +115,12 @@ func getYeahmobiExt(request *openrtb2.BidRequest) (*openrtb_ext.ExtImpYeahmobi, for _, imp := range request.Imp { var extBidder adapters.ExtImpBidder - err := json.Unmarshal(imp.Ext, &extBidder) + err := jsonutil.Unmarshal(imp.Ext, &extBidder) if err != nil { errs = append(errs, err) continue } - err = json.Unmarshal(extBidder.Bidder, &extImpYeahmobi) + err = jsonutil.Unmarshal(extBidder.Bidder, &extImpYeahmobi) if err != nil { errs = append(errs, err) continue @@ -151,7 +152,7 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest }} } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } bidResponse := adapters.NewBidderResponseWithBidsCapacity(1) @@ -166,7 +167,7 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest } if bid.Ext != nil { var bidExt *yeahmobiBidExt - err := json.Unmarshal(bid.Ext, &bidExt) + err := jsonutil.Unmarshal(bid.Ext, &bidExt) if err != nil { return nil, []error{fmt.Errorf("bid.ext json unmarshal error")} } else if bidExt != nil { diff --git a/adapters/yeahmobi/yeahmobi_test.go b/adapters/yeahmobi/yeahmobi_test.go index c1c7be35105..d822b32d675 100644 --- a/adapters/yeahmobi/yeahmobi_test.go +++ b/adapters/yeahmobi/yeahmobi_test.go @@ -3,9 +3,9 @@ package yeahmobi import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/yeahmobi/yeahmobitest/exemplary/simple-video.json b/adapters/yeahmobi/yeahmobitest/exemplary/simple-video.json index af07de8f8bb..5538150f450 100644 --- a/adapters/yeahmobi/yeahmobitest/exemplary/simple-video.json +++ b/adapters/yeahmobi/yeahmobitest/exemplary/simple-video.json @@ -96,7 +96,8 @@ }, "type": "video", "video": { - "duration": 300 + "duration": 300, + "primary_category": "" } } ] diff --git a/adapters/yeahmobi/yeahmobitest/supplemental/bad_imp_ext.json b/adapters/yeahmobi/yeahmobitest/supplemental/bad_imp_ext.json index 444e1e7a8d8..782f7a0c3b4 100644 --- a/adapters/yeahmobi/yeahmobitest/supplemental/bad_imp_ext.json +++ b/adapters/yeahmobi/yeahmobitest/supplemental/bad_imp_ext.json @@ -14,7 +14,7 @@ "expectedMakeRequestsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type adapters.ExtImpBidder", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/yeahmobi/yeahmobitest/supplemental/bad_imp_ext_bidder.json b/adapters/yeahmobi/yeahmobitest/supplemental/bad_imp_ext_bidder.json index 89697d37141..da9dce00905 100644 --- a/adapters/yeahmobi/yeahmobitest/supplemental/bad_imp_ext_bidder.json +++ b/adapters/yeahmobi/yeahmobitest/supplemental/bad_imp_ext_bidder.json @@ -16,7 +16,7 @@ "expectedMakeRequestsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb_ext.ExtImpYeahmobi", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/yeahmobi/yeahmobitest/supplemental/bad_response.json b/adapters/yeahmobi/yeahmobitest/supplemental/bad_response.json index 2fc375532de..43e16117887 100644 --- a/adapters/yeahmobi/yeahmobitest/supplemental/bad_response.json +++ b/adapters/yeahmobi/yeahmobitest/supplemental/bad_response.json @@ -50,7 +50,7 @@ "expectedMakeBidsErrors": [ { "comparison": "literal", - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse" + "value": "expect { or n, but found \"" } ] } diff --git a/adapters/yieldlab/params_test.go b/adapters/yieldlab/params_test.go index 74a91ac3bf7..ac65adc0fe7 100644 --- a/adapters/yieldlab/params_test.go +++ b/adapters/yieldlab/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/yieldlab.json diff --git a/adapters/yieldlab/types.go b/adapters/yieldlab/types.go index 9d3bc6a2fa6..57ee15c923b 100644 --- a/adapters/yieldlab/types.go +++ b/adapters/yieldlab/types.go @@ -1,9 +1,10 @@ package yieldlab import ( - "github.com/prebid/prebid-server/v2/openrtb_ext" "strconv" "time" + + "github.com/prebid/prebid-server/v3/openrtb_ext" ) type bidResponse struct { diff --git a/adapters/yieldlab/yieldlab.go b/adapters/yieldlab/yieldlab.go index c92abe7597d..7ffafc25d50 100644 --- a/adapters/yieldlab/yieldlab.go +++ b/adapters/yieldlab/yieldlab.go @@ -12,11 +12,12 @@ import ( "golang.org/x/text/currency" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/ptrutil" ) // YieldlabAdapter connects the Yieldlab API to prebid server @@ -130,7 +131,7 @@ func getDSA(req *openrtb2.BidRequest) (*dsaRequest, error) { } var extRegs openRTBExtRegsWithDSA - err := json.Unmarshal(req.Regs.Ext, &extRegs) + err := jsonutil.Unmarshal(req.Regs.Ext, &extRegs) if err != nil { return nil, fmt.Errorf("failed to parse Regs.Ext object from Yieldlab response: %v", err) } @@ -207,7 +208,7 @@ func (a *YieldlabAdapter) getGDPR(request *openrtb2.BidRequest) (string, string, consent := "" if request.User != nil && request.User.Ext != nil { var extUser openrtb_ext.ExtUser - if err := json.Unmarshal(request.User.Ext, &extUser); err != nil { + if err := jsonutil.Unmarshal(request.User.Ext, &extUser); err != nil { return "", "", fmt.Errorf("failed to parse ExtUser in Yieldlab GDPR check: %v", err) } consent = extUser.Consent @@ -216,7 +217,7 @@ func (a *YieldlabAdapter) getGDPR(request *openrtb2.BidRequest) (string, string, gdpr := "" var extRegs openrtb_ext.ExtRegs if request.Regs != nil { - if err := json.Unmarshal(request.Regs.Ext, &extRegs); err == nil { + if err := jsonutil.Unmarshal(request.Regs.Ext, &extRegs); err == nil { if extRegs.GDPR != nil && (*extRegs.GDPR == 0 || *extRegs.GDPR == 1) { gdpr = strconv.Itoa(int(*extRegs.GDPR)) } @@ -271,12 +272,12 @@ func (a *YieldlabAdapter) parseRequest(request *openrtb2.BidRequest) []*openrtb_ for i := 0; i < len(request.Imp); i++ { bidderExt := new(adapters.ExtImpBidder) - if err := json.Unmarshal(request.Imp[i].Ext, bidderExt); err != nil { + if err := jsonutil.Unmarshal(request.Imp[i].Ext, bidderExt); err != nil { continue } yieldlabExt := new(openrtb_ext.ExtImpYieldlab) - if err := json.Unmarshal(bidderExt.Bidder, yieldlabExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, yieldlabExt); err != nil { continue } @@ -314,7 +315,7 @@ func (a *YieldlabAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externa } bids := make([]*bidResponse, 0) - if err := json.Unmarshal(response.Body, &bids); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bids); err != nil { return nil, []error{ &errortypes.BadServerResponse{ Message: fmt.Sprintf("failed to parse bids response from yieldlab: %v", err), @@ -420,9 +421,9 @@ func (a *YieldlabAdapter) findBidReq(adslotID uint64, params []*openrtb_ext.ExtI func (a *YieldlabAdapter) extractAdslotID(internalRequestImp openrtb2.Imp) string { bidderExt := new(adapters.ExtImpBidder) - json.Unmarshal(internalRequestImp.Ext, bidderExt) + jsonutil.Unmarshal(internalRequestImp.Ext, bidderExt) yieldlabExt := new(openrtb_ext.ExtImpYieldlab) - json.Unmarshal(bidderExt.Bidder, yieldlabExt) + jsonutil.Unmarshal(bidderExt.Bidder, yieldlabExt) return yieldlabExt.AdslotID } @@ -460,7 +461,7 @@ func (a *YieldlabAdapter) makeCreativeID(req *openrtb_ext.ExtImpYieldlab, bid *b // unmarshalSupplyChain makes the value for the schain URL parameter from the openRTB schain object. func unmarshalSupplyChain(req *openrtb2.BidRequest) *openrtb2.SupplyChain { var extSChain openrtb_ext.ExtRequestPrebidSChain - err := json.Unmarshal(req.Source.Ext, &extSChain) + err := jsonutil.Unmarshal(req.Source.Ext, &extSChain) if err != nil { // req.Source.Ext could be anything so don't handle any errors return nil diff --git a/adapters/yieldlab/yieldlab_test.go b/adapters/yieldlab/yieldlab_test.go index 49dcc31e598..1bea9b12ea9 100644 --- a/adapters/yieldlab/yieldlab_test.go +++ b/adapters/yieldlab/yieldlab_test.go @@ -8,9 +8,9 @@ import ( "github.com/prebid/openrtb/v20/openrtb2" "github.com/stretchr/testify/assert" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) const testURL = "https://ad.yieldlab.net/testing/" diff --git a/adapters/yieldlab/yieldlabtest/supplemental/invalid_reg_ext.json b/adapters/yieldlab/yieldlabtest/supplemental/invalid_reg_ext.json index 1723b8fbe80..51e8e87d540 100644 --- a/adapters/yieldlab/yieldlabtest/supplemental/invalid_reg_ext.json +++ b/adapters/yieldlab/yieldlabtest/supplemental/invalid_reg_ext.json @@ -60,7 +60,7 @@ }, "expectedMakeRequestsErrors": [ { - "value": "failed to parse Regs.Ext object from Yieldlab response: json: cannot unmarshal string into Go struct field openRTBExtRegsWithDSA.dsa of type yieldlab.dsaRequest", + "value": "failed to parse Regs.Ext object from Yieldlab response: cannot unmarshal yieldlab.openRTBExtRegsWithDSA.DSA: expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/yieldmo/params_test.go b/adapters/yieldmo/params_test.go index 647c21abb90..baa566cf713 100644 --- a/adapters/yieldmo/params_test.go +++ b/adapters/yieldmo/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // This file actually intends to test static/bidder-params/yieldmo.json diff --git a/adapters/yieldmo/yieldmo.go b/adapters/yieldmo/yieldmo.go index 107622e9304..0725f7920c3 100644 --- a/adapters/yieldmo/yieldmo.go +++ b/adapters/yieldmo/yieldmo.go @@ -7,10 +7,11 @@ import ( "strings" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type YieldmoAdapter struct { @@ -81,7 +82,7 @@ func preprocess(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo } } - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { errs = append(errs, &errortypes.BadInput{ Message: err.Error(), }) @@ -89,7 +90,7 @@ func preprocess(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo var yieldmoExt openrtb_ext.ExtImpYieldmo - if err := json.Unmarshal(bidderExt.Bidder, &yieldmoExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &yieldmoExt); err != nil { errs = append(errs, &errortypes.BadInput{ Message: err.Error(), }) @@ -137,7 +138,7 @@ func (a *YieldmoAdapter) MakeBids(internalRequest *openrtb2.BidRequest, external var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } @@ -170,7 +171,7 @@ func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server co // 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 { + if err := jsonutil.Unmarshal(bid.Ext, &bidExt); err != nil { return "", &errortypes.BadInput{Message: err.Error()} } diff --git a/adapters/yieldmo/yieldmo_test.go b/adapters/yieldmo/yieldmo_test.go index f89d4849a2c..668e0a375ea 100644 --- a/adapters/yieldmo/yieldmo_test.go +++ b/adapters/yieldmo/yieldmo_test.go @@ -3,9 +3,9 @@ package yieldmo import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/yieldone/params_test.go b/adapters/yieldone/params_test.go index 623928839ef..5632546ac31 100644 --- a/adapters/yieldone/params_test.go +++ b/adapters/yieldone/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/yieldone/yieldone.go b/adapters/yieldone/yieldone.go index 8cd7dbd6021..b1aa6465386 100644 --- a/adapters/yieldone/yieldone.go +++ b/adapters/yieldone/yieldone.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type YieldoneAdapter struct { @@ -68,7 +69,7 @@ func (a *YieldoneAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externa } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } @@ -105,11 +106,11 @@ func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server co func preprocess(imp *openrtb2.Imp) error { var ext adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &ext); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &ext); err != nil { return err } var impressionExt openrtb_ext.ExtImpYieldone - if err := json.Unmarshal(ext.Bidder, &impressionExt); err != nil { + if err := jsonutil.Unmarshal(ext.Bidder, &impressionExt); err != nil { return err } diff --git a/adapters/yieldone/yieldone_test.go b/adapters/yieldone/yieldone_test.go index 1847ef9bf06..a9831561d43 100644 --- a/adapters/yieldone/yieldone_test.go +++ b/adapters/yieldone/yieldone_test.go @@ -3,9 +3,9 @@ package yieldone import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/yieldone/yieldonetest/supplemental/bad_response.json b/adapters/yieldone/yieldonetest/supplemental/bad_response.json index ac4bfd7da23..c3ce0ed0c65 100644 --- a/adapters/yieldone/yieldonetest/supplemental/bad_response.json +++ b/adapters/yieldone/yieldonetest/supplemental/bad_response.json @@ -59,7 +59,7 @@ "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/zeroclickfraud/zeroclickfraud.go b/adapters/zeroclickfraud/zeroclickfraud.go index 0b5c74771ba..eecd1dd8589 100644 --- a/adapters/zeroclickfraud/zeroclickfraud.go +++ b/adapters/zeroclickfraud/zeroclickfraud.go @@ -8,11 +8,12 @@ import ( "text/template" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type ZeroClickFraudAdapter struct { @@ -92,7 +93,7 @@ func (a *ZeroClickFraudAdapter) MakeBids( var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } @@ -130,13 +131,13 @@ func splitImpressions(imps []openrtb2.Imp) (map[openrtb_ext.ExtImpZeroClickFraud func getBidderParams(imp *openrtb2.Imp) (*openrtb_ext.ExtImpZeroClickFraud, error) { var bidderExt adapters.ExtImpBidder - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { return nil, &errortypes.BadInput{ Message: fmt.Sprintf("Missing bidder ext: %s", err.Error()), } } var zeroclickfraudExt openrtb_ext.ExtImpZeroClickFraud - if err := json.Unmarshal(bidderExt.Bidder, &zeroclickfraudExt); err != nil { + if err := jsonutil.Unmarshal(bidderExt.Bidder, &zeroclickfraudExt); err != nil { return nil, &errortypes.BadInput{ Message: fmt.Sprintf("Cannot Resolve host or sourceId: %s", err.Error()), } diff --git a/adapters/zeroclickfraud/zeroclickfraud_test.go b/adapters/zeroclickfraud/zeroclickfraud_test.go index 6e2a7e23b4c..363f37c0e17 100644 --- a/adapters/zeroclickfraud/zeroclickfraud_test.go +++ b/adapters/zeroclickfraud/zeroclickfraud_test.go @@ -3,9 +3,9 @@ package zeroclickfraud import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adapters/zeroclickfraud/zeroclickfraudtest/supplemental/bad-response-body.json b/adapters/zeroclickfraud/zeroclickfraudtest/supplemental/bad-response-body.json index 8dc9ffd6469..9e1483c79ec 100644 --- a/adapters/zeroclickfraud/zeroclickfraudtest/supplemental/bad-response-body.json +++ b/adapters/zeroclickfraud/zeroclickfraudtest/supplemental/bad-response-body.json @@ -82,7 +82,7 @@ }], "expectedMakeBidsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/zeroclickfraud/zeroclickfraudtest/supplemental/missing-ext.json b/adapters/zeroclickfraud/zeroclickfraudtest/supplemental/missing-ext.json index 68d29e880b9..9e72e3cb6e5 100644 --- a/adapters/zeroclickfraud/zeroclickfraudtest/supplemental/missing-ext.json +++ b/adapters/zeroclickfraud/zeroclickfraudtest/supplemental/missing-ext.json @@ -18,8 +18,8 @@ "expectedMakeRequestsErrors": [ { - "value": "Missing bidder ext: unexpected end of JSON input", - "comparison": "literal" + "value": "Missing bidder ext: expect { or n, but found", + "comparison": "startswith" } ] diff --git a/adapters/zeroclickfraud/zeroclickfraudtest/supplemental/missing-extparam.json b/adapters/zeroclickfraud/zeroclickfraudtest/supplemental/missing-extparam.json index d272cd5347c..7755ef80ec2 100644 --- a/adapters/zeroclickfraud/zeroclickfraudtest/supplemental/missing-extparam.json +++ b/adapters/zeroclickfraud/zeroclickfraudtest/supplemental/missing-extparam.json @@ -21,8 +21,8 @@ "expectedMakeRequestsErrors": [ { - "value": "Cannot Resolve host or sourceId: unexpected end of JSON input", - "comparison": "literal" + "value": "Cannot Resolve host or sourceId: expect { or n, but found", + "comparison": "startswith" } ] diff --git a/adapters/zeta_global_ssp/zeta_global_ssp.go b/adapters/zeta_global_ssp/zeta_global_ssp.go index cf78b91ac8a..e06c6f05eff 100644 --- a/adapters/zeta_global_ssp/zeta_global_ssp.go +++ b/adapters/zeta_global_ssp/zeta_global_ssp.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -54,7 +55,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } var response openrtb2.BidResponse - if err := json.Unmarshal(responseData.Body, &response); err != nil { + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { return nil, []error{err} } @@ -81,7 +82,7 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) { if bid.Ext != nil { var bidExt openrtb_ext.ExtBid - err := json.Unmarshal(bid.Ext, &bidExt) + err := jsonutil.Unmarshal(bid.Ext, &bidExt) if err == nil && bidExt.Prebid != nil { return openrtb_ext.ParseBidType(string(bidExt.Prebid.Type)) } diff --git a/adapters/zeta_global_ssp/zeta_global_ssp_test.go b/adapters/zeta_global_ssp/zeta_global_ssp_test.go index fabfa5efed8..f2b51409165 100644 --- a/adapters/zeta_global_ssp/zeta_global_ssp_test.go +++ b/adapters/zeta_global_ssp/zeta_global_ssp_test.go @@ -3,9 +3,9 @@ package zeta_global_ssp import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/zmaticoo/params_test.go b/adapters/zmaticoo/params_test.go index 23c599e81b5..c6c462155aa 100644 --- a/adapters/zmaticoo/params_test.go +++ b/adapters/zmaticoo/params_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestValidParams(t *testing.T) { diff --git a/adapters/zmaticoo/zmaticoo.go b/adapters/zmaticoo/zmaticoo.go index 61860df5b22..9e0da9e449a 100644 --- a/adapters/zmaticoo/zmaticoo.go +++ b/adapters/zmaticoo/zmaticoo.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type adapter struct { @@ -61,7 +62,7 @@ func transform(request *openrtb2.BidRequest) error { if imp.Native != nil { var nativeRequest map[string]interface{} nativeCopyRequest := make(map[string]interface{}) - if err := json.Unmarshal([]byte(request.Imp[i].Native.Request), &nativeRequest); err != nil { + if err := jsonutil.Unmarshal([]byte(request.Imp[i].Native.Request), &nativeRequest); err != nil { return err } _, exists := nativeRequest["native"] @@ -86,12 +87,12 @@ func validateZmaticooExt(request *openrtb2.BidRequest) []error { var errs []error for _, imp := range request.Imp { var extBidder adapters.ExtImpBidder - err := json.Unmarshal(imp.Ext, &extBidder) + err := jsonutil.Unmarshal(imp.Ext, &extBidder) if err != nil { errs = append(errs, err) continue } - err = json.Unmarshal(extBidder.Bidder, &extImpZmaticoo) + err = jsonutil.Unmarshal(extBidder.Bidder, &extImpZmaticoo) if err != nil { errs = append(errs, err) continue @@ -116,7 +117,7 @@ func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest }} } var bidResp openrtb2.BidResponse - if err := json.Unmarshal(response.Body, &bidResp); err != nil { + if err := jsonutil.Unmarshal(response.Body, &bidResp); err != nil { return nil, []error{err} } var errs []error diff --git a/adapters/zmaticoo/zmaticoo_test.go b/adapters/zmaticoo/zmaticoo_test.go index 1effdd2afa7..df12c1e1b6f 100644 --- a/adapters/zmaticoo/zmaticoo_test.go +++ b/adapters/zmaticoo/zmaticoo_test.go @@ -3,9 +3,9 @@ package zmaticoo import ( "testing" - "github.com/prebid/prebid-server/v2/adapters/adapterstest" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func TestJsonSamples(t *testing.T) { diff --git a/adapters/zmaticoo/zmaticootest/supplemental/bad_imp_ext.json b/adapters/zmaticoo/zmaticootest/supplemental/bad_imp_ext.json index 444e1e7a8d8..782f7a0c3b4 100644 --- a/adapters/zmaticoo/zmaticootest/supplemental/bad_imp_ext.json +++ b/adapters/zmaticoo/zmaticootest/supplemental/bad_imp_ext.json @@ -14,7 +14,7 @@ "expectedMakeRequestsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type adapters.ExtImpBidder", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/zmaticoo/zmaticootest/supplemental/bad_imp_ext_bidder.json b/adapters/zmaticoo/zmaticootest/supplemental/bad_imp_ext_bidder.json index 433bac5e564..b9a32be2ce6 100644 --- a/adapters/zmaticoo/zmaticootest/supplemental/bad_imp_ext_bidder.json +++ b/adapters/zmaticoo/zmaticootest/supplemental/bad_imp_ext_bidder.json @@ -20,7 +20,7 @@ }, "expectedMakeRequestsErrors": [ { - "value": "json: cannot unmarshal string into Go value of type openrtb_ext.ExtImpZmaticoo", + "value": "expect { or n, but found \"", "comparison": "literal" } ] diff --git a/adapters/zmaticoo/zmaticootest/supplemental/bad_response.json b/adapters/zmaticoo/zmaticootest/supplemental/bad_response.json index e129e3ce4a7..3d053597a20 100644 --- a/adapters/zmaticoo/zmaticootest/supplemental/bad_response.json +++ b/adapters/zmaticoo/zmaticootest/supplemental/bad_response.json @@ -58,7 +58,7 @@ "expectedMakeBidsErrors": [ { "comparison": "literal", - "value": "json: cannot unmarshal string into Go value of type openrtb2.BidResponse" + "value": "expect { or n, but found \"" } ] } diff --git a/adservertargeting/adservertargeting.go b/adservertargeting/adservertargeting.go index d53af49f36c..3ab7cefe6c4 100644 --- a/adservertargeting/adservertargeting.go +++ b/adservertargeting/adservertargeting.go @@ -7,7 +7,7 @@ import ( "github.com/buger/jsonparser" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) type DataSource string diff --git a/adservertargeting/adservertargeting_test.go b/adservertargeting/adservertargeting_test.go index 14daa0beb26..8ba3c256b3d 100644 --- a/adservertargeting/adservertargeting_test.go +++ b/adservertargeting/adservertargeting_test.go @@ -7,8 +7,8 @@ import ( "github.com/prebid/openrtb/v20/openrtb2" "github.com/prebid/openrtb/v20/openrtb3" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" "github.com/stretchr/testify/assert" ) diff --git a/adservertargeting/reqcache.go b/adservertargeting/reqcache.go index dfe429d5056..03c87f024cb 100644 --- a/adservertargeting/reqcache.go +++ b/adservertargeting/reqcache.go @@ -5,7 +5,7 @@ import ( "github.com/buger/jsonparser" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type requestCache struct { diff --git a/adservertargeting/requestlookup.go b/adservertargeting/requestlookup.go index d3284525b50..31c1a9d939e 100644 --- a/adservertargeting/requestlookup.go +++ b/adservertargeting/requestlookup.go @@ -8,7 +8,7 @@ import ( "github.com/buger/jsonparser" "github.com/pkg/errors" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func getAdServerTargeting(reqWrapper *openrtb_ext.RequestWrapper) ([]openrtb_ext.AdServerTarget, error) { diff --git a/adservertargeting/requestlookup_test.go b/adservertargeting/requestlookup_test.go index 3de9bd72322..22f914ac793 100644 --- a/adservertargeting/requestlookup_test.go +++ b/adservertargeting/requestlookup_test.go @@ -6,7 +6,7 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adservertargeting/respdataprocessor.go b/adservertargeting/respdataprocessor.go index 51bad207337..4b18d64b44b 100644 --- a/adservertargeting/respdataprocessor.go +++ b/adservertargeting/respdataprocessor.go @@ -7,8 +7,8 @@ import ( "github.com/pkg/errors" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" jsonpatch "gopkg.in/evanphx/json-patch.v4" ) diff --git a/adservertargeting/respdataprocessor_test.go b/adservertargeting/respdataprocessor_test.go index 6970cfaceac..973f9b801e5 100644 --- a/adservertargeting/respdataprocessor_test.go +++ b/adservertargeting/respdataprocessor_test.go @@ -8,7 +8,7 @@ import ( "github.com/prebid/openrtb/v20/openrtb2" "github.com/prebid/openrtb/v20/openrtb3" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/adservertargeting/utils.go b/adservertargeting/utils.go index 136f7900e24..dd70bf1b667 100644 --- a/adservertargeting/utils.go +++ b/adservertargeting/utils.go @@ -5,8 +5,8 @@ import ( "github.com/buger/jsonparser" "github.com/pkg/errors" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func splitAndGet(path string, data []byte, delimiter string) (string, error) { diff --git a/amp/parse.go b/amp/parse.go index 12663ee93bd..2a86bc7b6b7 100644 --- a/amp/parse.go +++ b/amp/parse.go @@ -10,10 +10,10 @@ import ( tcf2 "github.com/prebid/go-gdpr/vendorconsent/tcf2" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/privacy" - "github.com/prebid/prebid-server/v2/privacy/ccpa" - "github.com/prebid/prebid-server/v2/privacy/gdpr" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/privacy" + "github.com/prebid/prebid-server/v3/privacy/ccpa" + "github.com/prebid/prebid-server/v3/privacy/gdpr" ) // Params defines the parameters of an AMP request. @@ -117,7 +117,7 @@ func buildGdprTCF2ConsentWriter(ampParams Params) gdpr.ConsentWriter { // set regs.ext.gdpr if non-nil gdpr_applies was set to true gdprValue = parseGdprApplies(ampParams.GdprApplies) } - writer.RegExtGDPR = &gdprValue + writer.GDPR = &gdprValue return writer } diff --git a/amp/parse_test.go b/amp/parse_test.go index f2f097284c5..65b69012b45 100644 --- a/amp/parse_test.go +++ b/amp/parse_test.go @@ -5,10 +5,10 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/privacy" - "github.com/prebid/prebid-server/v2/privacy/ccpa" - "github.com/prebid/prebid-server/v2/privacy/gdpr" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/privacy" + "github.com/prebid/prebid-server/v3/privacy/ccpa" + "github.com/prebid/prebid-server/v3/privacy/gdpr" "github.com/stretchr/testify/assert" ) @@ -311,8 +311,8 @@ func TestPrivacyReader(t *testing.T) { }, expected: expectedResults{ policyWriter: gdpr.ConsentWriter{ - Consent: "CPdiPIJPdiPIJACABBENAzCv_____3___wAAAQNd_X9cAAAAAAAA", - RegExtGDPR: &int8One, + Consent: "CPdiPIJPdiPIJACABBENAzCv_____3___wAAAQNd_X9cAAAAAAAA", + GDPR: &int8One, }, warning: nil, }, @@ -378,8 +378,8 @@ func TestPrivacyReader(t *testing.T) { }, expected: expectedResults{ policyWriter: gdpr.ConsentWriter{ - Consent: "CPdiPIJPdiPIJACABBENAzCv_____3___wAAAQNd_X9cAAAAAAAA", - RegExtGDPR: &int8One, + Consent: "CPdiPIJPdiPIJACABBENAzCv_____3___wAAAQNd_X9cAAAAAAAA", + GDPR: &int8One, }, warning: nil, }, @@ -400,8 +400,8 @@ func TestPrivacyReader(t *testing.T) { }, expected: expectedResults{ policyWriter: gdpr.ConsentWriter{ - Consent: "INVALID_GDPR", - RegExtGDPR: &int8One, + Consent: "INVALID_GDPR", + GDPR: &int8One, }, warning: &errortypes.Warning{ Message: "Consent string 'INVALID_GDPR' is not a valid TCF2 consent string.", @@ -420,8 +420,8 @@ func TestPrivacyReader(t *testing.T) { }, expected: expectedResults{ policyWriter: gdpr.ConsentWriter{ - Consent: "INVALID_GDPR", - RegExtGDPR: &int8Zero, + Consent: "INVALID_GDPR", + GDPR: &int8Zero, }, warning: &errortypes.Warning{ Message: "Consent string 'INVALID_GDPR' is not a valid TCF2 consent string.", @@ -440,8 +440,8 @@ func TestPrivacyReader(t *testing.T) { }, expected: expectedResults{ policyWriter: gdpr.ConsentWriter{ - Consent: "CPdiPIJPdiPIJACABBENAzCv_____3___wAAAQNd_X9cAAAAAAAA", - RegExtGDPR: &int8Zero, + Consent: "CPdiPIJPdiPIJACABBENAzCv_____3___wAAAQNd_X9cAAAAAAAA", + GDPR: &int8Zero, }, warning: nil, }, @@ -457,8 +457,8 @@ func TestPrivacyReader(t *testing.T) { }, expected: expectedResults{ policyWriter: gdpr.ConsentWriter{ - Consent: "CPdiPIJPdiPIJACABBENAzCv_____3___wAAAQNd_X9cAAAAAAAA", - RegExtGDPR: &int8One, + Consent: "CPdiPIJPdiPIJACABBENAzCv_____3___wAAAQNd_X9cAAAAAAAA", + GDPR: &int8One, }, warning: nil, }, @@ -473,8 +473,8 @@ func TestPrivacyReader(t *testing.T) { }, expected: expectedResults{ policyWriter: gdpr.ConsentWriter{ - Consent: "CPdiPIJPdiPIJACABBENAzCv_____3___wAAAQNd_X9cAAAAAAAA", - RegExtGDPR: &int8One, + Consent: "CPdiPIJPdiPIJACABBENAzCv_____3___wAAAQNd_X9cAAAAAAAA", + GDPR: &int8One, }, warning: nil, }, @@ -559,8 +559,8 @@ func TestBuildGdprTCF2ConsentWriter(t *testing.T) { desc: "gdpr_applies not set", inParams: Params{Consent: consentString}, expectedWriter: gdpr.ConsentWriter{ - Consent: consentString, - RegExtGDPR: &int8One, + Consent: consentString, + GDPR: &int8One, }, }, { @@ -570,8 +570,8 @@ func TestBuildGdprTCF2ConsentWriter(t *testing.T) { GdprApplies: &boolFalse, }, expectedWriter: gdpr.ConsentWriter{ - Consent: consentString, - RegExtGDPR: &int8Zero, + Consent: consentString, + GDPR: &int8Zero, }, }, { @@ -581,8 +581,8 @@ func TestBuildGdprTCF2ConsentWriter(t *testing.T) { GdprApplies: &boolTrue, }, expectedWriter: gdpr.ConsentWriter{ - Consent: consentString, - RegExtGDPR: &int8One, + Consent: consentString, + GDPR: &int8One, }, }, } diff --git a/analytics/agma/README.md b/analytics/agma/README.md index cc9736feb85..430001863ac 100644 --- a/analytics/agma/README.md +++ b/analytics/agma/README.md @@ -12,8 +12,8 @@ analytics: # Required: set the accounts you want to track accounts: - code: "my-code" # Required: provied by agma - publisher_id: "123" # Required: Exchange specific publisher_id - site_app_id: "openrtb2-site.id-or-app.id" # optional: scope to the publisher with an openrtb2 Site object id or App object id + publisher_id: "123" # Required: Exchange specific publisher_id, can be an empty string accounts are not used + site_app_id: "openrtb2-site.id-or-app.id-or-app.bundle" # optional: scope to the publisher with an openrtb2 Site object id or App object id/bundle # Optional properties (advanced configuration) endpoint: url: "https://go.pbs.agma-analytics.de/v1/prebid-server" # Check with agma if your site needs an extra url diff --git a/analytics/agma/agma_module.go b/analytics/agma/agma_module.go index 534c189d914..6ee16e93b84 100644 --- a/analytics/agma/agma_module.go +++ b/analytics/agma/agma_module.go @@ -14,9 +14,9 @@ import ( "github.com/docker/go-units" "github.com/golang/glog" "github.com/prebid/go-gdpr/vendorconsent" - "github.com/prebid/prebid-server/v2/analytics" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/analytics" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) type httpSender = func(payload []byte) error @@ -169,20 +169,20 @@ func (l *AgmaLogger) extractPublisherAndSite(requestWrapper *openrtb_ext.Request publisherId = requestWrapper.App.Publisher.ID } appSiteId = requestWrapper.App.ID + if appSiteId == "" { + appSiteId = requestWrapper.App.Bundle + } + } return publisherId, appSiteId } func (l *AgmaLogger) shouldTrackEvent(requestWrapper *openrtb_ext.RequestWrapper) (bool, string) { - userExt, err := requestWrapper.GetUserExt() - if err != nil || userExt == nil { - return false, "" - } - consent := userExt.GetConsent() - if consent == nil { + if requestWrapper.User == nil { return false, "" } - consentStr := *consent + consentStr := requestWrapper.User.Consent + parsedConsent, err := vendorconsent.ParseString(consentStr) if err != nil { return false, "" @@ -261,6 +261,11 @@ func (l *AgmaLogger) LogVideoObject(event *analytics.VideoObject) { l.bufferCh <- data } +func (l *AgmaLogger) Shutdown() { + glog.Info("[AgmaAnalytics] Shutdown, trying to flush buffer") + l.flush() // mutex safe +} + func (l *AgmaLogger) LogCookieSyncObject(event *analytics.CookieSyncObject) {} func (l *AgmaLogger) LogNotificationEventObject(event *analytics.NotificationEvent) {} func (l *AgmaLogger) LogSetUIDObject(event *analytics.SetUIDObject) {} diff --git a/analytics/agma/agma_module_test.go b/analytics/agma/agma_module_test.go index 3e4955bd8a5..25f62d6e9e0 100644 --- a/analytics/agma/agma_module_test.go +++ b/analytics/agma/agma_module_test.go @@ -1,7 +1,6 @@ package agma import ( - "encoding/json" "io" "net/http" "net/http/httptest" @@ -12,9 +11,9 @@ import ( "github.com/benbjohnson/clock" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/analytics" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/analytics" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" ) @@ -37,7 +36,7 @@ var mockValidAuctionObject = analytics.AuctionObject{ UA: "ua", }, User: &openrtb2.User{ - Ext: json.RawMessage(`{"consent": "` + agmaConsent + `"}`), + Consent: agmaConsent, }, }, }, @@ -59,7 +58,7 @@ var mockValidVideoObject = analytics.VideoObject{ UA: "ua", }, User: &openrtb2.User{ - Ext: json.RawMessage(`{"consent": "` + agmaConsent + `"}`), + Consent: agmaConsent, }, }, }, @@ -81,7 +80,7 @@ var mockValidAmpObject = analytics.AmpObject{ UA: "ua", }, User: &openrtb2.User{ - Ext: json.RawMessage(`{"consent": "` + agmaConsent + `"}`), + Consent: agmaConsent, }, }, }, @@ -188,6 +187,11 @@ func TestShouldTrackEvent(t *testing.T) { PublisherId: "track-me", Code: "abc", }, + { + PublisherId: "", + SiteAppId: "track-me", + Code: "abc", + }, }, } mockedSender := new(MockedSender) @@ -207,7 +211,7 @@ func TestShouldTrackEvent(t *testing.T) { }, }, User: &openrtb2.User{ - Ext: json.RawMessage(`{"consent": "` + agmaConsent + `"}`), + Consent: agmaConsent, }, }, }) @@ -240,7 +244,7 @@ func TestShouldTrackEvent(t *testing.T) { }, }, User: &openrtb2.User{ - Ext: json.RawMessage(`{"consent": "CP4LywcP4LywcLRAAAENCZCAAAIAAAIAAAAAIxQAQIwgAAAA.II7Nd_X__bX9n-_7_6ft0eY1f9_r37uQzDhfNs-8F3L_W_LwX32E7NF36tq4KmR4ku1bBIQNtHMnUDUmxaolVrzHsak2cpyNKJ_JkknsZe2dYGF9Pn9lD-YKZ7_5_9_f52T_9_9_-39z3_9f___dv_-__-vjf_599n_v9fV_78_Kf9______-____________8A"}`), + Consent: "CP4LywcP4LywcLRAAAENCZCAAAIAAAIAAAAAIxQAQIwgAAAA.II7Nd_X__bX9n-_7_6ft0eY1f9_r37uQzDhfNs-8F3L_W_LwX32E7NF36tq4KmR4ku1bBIQNtHMnUDUmxaolVrzHsak2cpyNKJ_JkknsZe2dYGF9Pn9lD-YKZ7_5_9_f52T_9_9_-39z3_9f___dv_-__-vjf_599n_v9fV_78_Kf9______-____________8A", }, }, }) @@ -258,7 +262,7 @@ func TestShouldTrackEvent(t *testing.T) { }, }, User: &openrtb2.User{ - Ext: json.RawMessage(`{"consent": "CP4LywcP4LywcLRAAAENCZCAAIAAAAAAAAAAIxQAQIxAAAAA.II7Nd_X__bX9n-_7_6ft0eY1f9_r37uQzDhfNs-8F3L_W_LwX32E7NF36tq4KmR4ku1bBIQNtHMnUDUmxaolVrzHsak2cpyNKJ_JkknsZe2dYGF9Pn9lD-YKZ7_5_9_f52T_9_9_-39z3_9f___dv_-__-vjf_599n_v9fV_78_Kf9______-____________8A"}`), + Consent: "CP4LywcP4LywcLRAAAENCZCAAIAAAAAAAAAAIxQAQIxAAAAA.II7Nd_X__bX9n-_7_6ft0eY1f9_r37uQzDhfNs-8F3L_W_LwX32E7NF36tq4KmR4ku1bBIQNtHMnUDUmxaolVrzHsak2cpyNKJ_JkknsZe2dYGF9Pn9lD-YKZ7_5_9_f52T_9_9_-39z3_9f___dv_-__-vjf_599n_v9fV_78_Kf9______-____________8A", }, }, }) @@ -276,13 +280,43 @@ func TestShouldTrackEvent(t *testing.T) { }, }, User: &openrtb2.User{ - Ext: json.RawMessage(`{"consent": "` + agmaConsent + `"}`), + Consent: agmaConsent, }, }, }) assert.False(t, shouldTrack) assert.Equal(t, "", code) + + // should allow empty accounts + shouldTrack, code = logger.shouldTrackEvent(&openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + App: &openrtb2.App{ + ID: "track-me", + }, + User: &openrtb2.User{ + Consent: agmaConsent, + }, + }, + }) + + assert.True(t, shouldTrack) + assert.Equal(t, "abc", code) + + // Bundle ID instead of app.id + shouldTrack, code = logger.shouldTrackEvent(&openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + App: &openrtb2.App{ + Bundle: "track-me", + }, + User: &openrtb2.User{ + Consent: agmaConsent, + }, + }, + }) + + assert.True(t, shouldTrack) + assert.Equal(t, "abc", code) } func TestShouldTrackMultipleAccounts(t *testing.T) { @@ -324,7 +358,7 @@ func TestShouldTrackMultipleAccounts(t *testing.T) { }, }, User: &openrtb2.User{ - Ext: json.RawMessage(`{"consent": "` + agmaConsent + `"}`), + Consent: agmaConsent, }, }, }) @@ -342,7 +376,7 @@ func TestShouldTrackMultipleAccounts(t *testing.T) { }, }, User: &openrtb2.User{ - Ext: json.RawMessage(`{"consent": "` + agmaConsent + `"}`), + Consent: agmaConsent, }, }, }) @@ -656,7 +690,7 @@ func TestRaceEnd2End(t *testing.T) { time.Sleep(250 * time.Millisecond) - expected := "[{\"type\":\"amp\",\"id\":\"some-id\",\"code\":\"abcd\",\"site\":{\"id\":\"track-me-site\",\"publisher\":{\"id\":\"track-me\"}},\"device\":{\"ua\":\"ua\"},\"user\":{\"ext\":{\"consent\": \"" + agmaConsent + "\"}},\"created_at\":\"2023-02-01T00:00:00Z\"},{\"type\":\"amp\",\"id\":\"some-id\",\"code\":\"abcd\",\"site\":{\"id\":\"track-me-site\",\"publisher\":{\"id\":\"track-me\"}},\"device\":{\"ua\":\"ua\"},\"user\":{\"ext\":{\"consent\": \"" + agmaConsent + "\"}},\"created_at\":\"2023-02-01T00:00:00Z\"}]" + expected := "[{\"type\":\"amp\",\"id\":\"some-id\",\"code\":\"abcd\",\"site\":{\"id\":\"track-me-site\",\"publisher\":{\"id\":\"track-me\"}},\"device\":{\"ua\":\"ua\"},\"user\":{\"consent\":\"" + agmaConsent + "\"},\"created_at\":\"2023-02-01T00:00:00Z\"},{\"type\":\"amp\",\"id\":\"some-id\",\"code\":\"abcd\",\"site\":{\"id\":\"track-me-site\",\"publisher\":{\"id\":\"track-me\"}},\"device\":{\"ua\":\"ua\"},\"user\":{\"consent\":\"" + agmaConsent + "\"},\"created_at\":\"2023-02-01T00:00:00Z\"}]" mu.Lock() actual := requestBodyAsString @@ -664,3 +698,38 @@ func TestRaceEnd2End(t *testing.T) { assert.Equal(t, expected, actual) } + +func TestShutdownFlush(t *testing.T) { + cfg := config.AgmaAnalytics{ + Enabled: true, + Endpoint: config.AgmaAnalyticsHttpEndpoint{ + Url: "http://localhost:8000/event", + Timeout: "5s", + }, + Buffers: config.AgmaAnalyticsBuffer{ + EventCount: 1000, + BufferSize: "100mb", + Timeout: "5m", + }, + Accounts: []config.AgmaAnalyticsAccount{ + { + PublisherId: "track-me", + Code: "abc", + }, + }, + } + mockedSender := new(MockedSender) + mockedSender.On("Send", mock.Anything).Return(nil) + clockMock := clock.NewMock() + logger, err := newAgmaLogger(cfg, mockedSender.Send, clockMock) + assert.NoError(t, err) + + go logger.start() + logger.LogAuctionObject(&mockValidAuctionObject) + logger.Shutdown() + + time.Sleep(10 * time.Millisecond) + + mockedSender.AssertCalled(t, "Send", mock.Anything) + mockedSender.AssertNumberOfCalls(t, "Send", 1) +} diff --git a/analytics/agma/model.go b/analytics/agma/model.go index a0f5f55f08f..112ce961a0c 100644 --- a/analytics/agma/model.go +++ b/analytics/agma/model.go @@ -5,8 +5,8 @@ import ( "time" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type EventType string diff --git a/analytics/agma/model_test.go b/analytics/agma/model_test.go index ea1134c2320..925856b87b8 100644 --- a/analytics/agma/model_test.go +++ b/analytics/agma/model_test.go @@ -5,7 +5,7 @@ import ( "time" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/analytics/agma/sender.go b/analytics/agma/sender.go index 6cdc5ea1526..b47b059536e 100644 --- a/analytics/agma/sender.go +++ b/analytics/agma/sender.go @@ -10,8 +10,8 @@ import ( "time" "github.com/golang/glog" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/version" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/version" ) func compressToGZIP(requestBody []byte) ([]byte, error) { diff --git a/analytics/agma/sender_test.go b/analytics/agma/sender_test.go index 05714674fea..1d23e6b6a90 100644 --- a/analytics/agma/sender_test.go +++ b/analytics/agma/sender_test.go @@ -7,7 +7,7 @@ import ( "net/http/httptest" "testing" - "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v3/config" "github.com/stretchr/testify/assert" ) diff --git a/analytics/build/build.go b/analytics/build/build.go index 4cba9a3f1a6..26edaa4f53b 100644 --- a/analytics/build/build.go +++ b/analytics/build/build.go @@ -5,15 +5,15 @@ import ( "github.com/benbjohnson/clock" "github.com/golang/glog" - "github.com/prebid/prebid-server/v2/analytics" - "github.com/prebid/prebid-server/v2/analytics/agma" - "github.com/prebid/prebid-server/v2/analytics/clients" - "github.com/prebid/prebid-server/v2/analytics/filesystem" - "github.com/prebid/prebid-server/v2/analytics/pubstack" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/ortb" - "github.com/prebid/prebid-server/v2/privacy" + "github.com/prebid/prebid-server/v3/analytics" + "github.com/prebid/prebid-server/v3/analytics/agma" + "github.com/prebid/prebid-server/v3/analytics/clients" + "github.com/prebid/prebid-server/v3/analytics/filesystem" + "github.com/prebid/prebid-server/v3/analytics/pubstack" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/ortb" + "github.com/prebid/prebid-server/v3/privacy" ) // Modules that need to be logged to need to be initialized here @@ -129,6 +129,13 @@ func (ea enabledAnalytics) LogNotificationEventObject(ne *analytics.Notification } } +// Shutdown - correctly shutdown all analytics modules and wait for them to finish +func (ea enabledAnalytics) Shutdown() { + for _, module := range ea { + module.Shutdown() + } +} + func evaluateActivities(rw *openrtb_ext.RequestWrapper, ac privacy.ActivityControl, componentName string) (bool, *openrtb_ext.RequestWrapper) { // returned nil request wrapper means that request wrapper was not modified by activities and doesn't have to be changed in analytics object // it is needed in order to use one function for all analytics objects with RequestWrapper diff --git a/analytics/build/build_test.go b/analytics/build/build_test.go index d794c01ab8c..ae16e0f749b 100644 --- a/analytics/build/build_test.go +++ b/analytics/build/build_test.go @@ -1,18 +1,18 @@ package build import ( - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/iputil" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/iputil" "net/http" "os" "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/analytics" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/privacy" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/analytics" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/privacy" + "github.com/prebid/prebid-server/v3/util/ptrutil" "github.com/stretchr/testify/assert" ) @@ -79,6 +79,8 @@ func (m *sampleModule) LogAmpObject(ao *analytics.AmpObject) { *m.count++ } func (m *sampleModule) LogNotificationEventObject(ne *analytics.NotificationEvent) { *m.count++ } +func (m *sampleModule) Shutdown() { *m.count++ } + func initAnalytics(count *int) analytics.Runner { modules := make(enabledAnalytics, 0) modules["sampleModule"] = &sampleModule{count} @@ -92,6 +94,19 @@ func TestNewPBSAnalytics(t *testing.T) { assert.Equal(t, len(instance), 0) } +func TestPBSAnalyticsShutdown(t *testing.T) { + countA := 0 + countB := 0 + modules := make(enabledAnalytics, 0) + modules["sampleModuleA"] = &sampleModule{count: &countA} + modules["sampleModuleB"] = &sampleModule{count: &countB} + + modules.Shutdown() + + assert.Equal(t, 1, countA, "sampleModuleA should have been shutdown") + assert.Equal(t, 1, countB, "sampleModuleB should have been shutdown") +} + func TestNewPBSAnalytics_FileLogger(t *testing.T) { if _, err := os.Stat(TEST_DIR); os.IsNotExist(err) { if err = os.MkdirAll(TEST_DIR, 0755); err != nil { @@ -415,6 +430,8 @@ func (m *mockAnalytics) LogSetUIDObject(ao *analytics.SetUIDObject) {} func (m *mockAnalytics) LogNotificationEventObject(ao *analytics.NotificationEvent) {} +func (m *mockAnalytics) Shutdown() {} + func TestLogObject(t *testing.T) { tests := []struct { description string diff --git a/analytics/core.go b/analytics/core.go index c9e15180f44..25ff46c8247 100644 --- a/analytics/core.go +++ b/analytics/core.go @@ -4,9 +4,9 @@ import ( "time" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/hooks/hookexecution" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/hooks/hookexecution" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // Module must be implemented by analytics modules to extract the required information and logging @@ -19,6 +19,7 @@ type Module interface { LogSetUIDObject(*SetUIDObject) LogAmpObject(*AmpObject) LogNotificationEventObject(*NotificationEvent) + Shutdown() } // Loggable object of a transaction at /openrtb2/auction endpoint diff --git a/analytics/filesystem/file_module.go b/analytics/filesystem/file_module.go index 01f9c27bf43..5555752e461 100644 --- a/analytics/filesystem/file_module.go +++ b/analytics/filesystem/file_module.go @@ -4,10 +4,11 @@ import ( "bytes" "fmt" - "github.com/chasex/glog" + cglog "github.com/chasex/glog" + "github.com/golang/glog" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/analytics" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/analytics" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type RequestType string @@ -21,9 +22,14 @@ const ( NOTIFICATION_EVENT RequestType = "/event" ) +type Logger interface { + Debug(v ...interface{}) + Flush() +} + // Module that can perform transactional logging type FileLogger struct { - Logger *glog.Logger + Logger Logger } // Writes AuctionObject to file @@ -85,15 +91,22 @@ func (f *FileLogger) LogNotificationEventObject(ne *analytics.NotificationEvent) f.Logger.Flush() } +// Shutdown the logger +func (f *FileLogger) Shutdown() { + // clear all pending buffered data in case there is any + glog.Info("[FileLogger] Shutdown, trying to flush buffer") + f.Logger.Flush() +} + // Method to initialize the analytic module func NewFileLogger(filename string) (analytics.Module, error) { - options := glog.LogOptions{ + options := cglog.LogOptions{ File: filename, - Flag: glog.LstdFlags, - Level: glog.Ldebug, - Mode: glog.R_Day, + Flag: cglog.LstdFlags, + Level: cglog.Ldebug, + Mode: cglog.R_Day, } - if logger, err := glog.New(options); err == nil { + if logger, err := cglog.New(options); err == nil { return &FileLogger{ logger, }, nil diff --git a/analytics/filesystem/file_module_test.go b/analytics/filesystem/file_module_test.go index 0e0831d14f1..0e502cfb9e0 100644 --- a/analytics/filesystem/file_module_test.go +++ b/analytics/filesystem/file_module_test.go @@ -6,14 +6,27 @@ import ( "strings" "testing" - "github.com/prebid/prebid-server/v2/analytics" - "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v3/analytics" + "github.com/prebid/prebid-server/v3/config" + "github.com/stretchr/testify/mock" "github.com/prebid/openrtb/v20/openrtb2" ) const TEST_DIR string = "testFiles" +type MockLogger struct { + mock.Mock +} + +func (ml *MockLogger) Debug(v ...interface{}) { + ml.Called(v) +} + +func (ml *MockLogger) Flush() { + ml.Called() +} + func TestAmpObject_ToJson(t *testing.T) { ao := &analytics.AmpObject{ Status: http.StatusOK, @@ -97,3 +110,15 @@ func TestFileLogger_LogObjects(t *testing.T) { t.Fatalf("Couldn't initialize file logger: %v", err) } } + +func TestFileLoggerShutdown(t *testing.T) { + mockLogger := &MockLogger{} + fl := &FileLogger{ + Logger: mockLogger, + } + mockLogger.On("Flush").Return(nil) + + fl.Shutdown() + + mockLogger.AssertNumberOfCalls(t, "Flush", 1) +} diff --git a/analytics/filesystem/model.go b/analytics/filesystem/model.go index 013a92593a4..aed111dd10a 100644 --- a/analytics/filesystem/model.go +++ b/analytics/filesystem/model.go @@ -4,10 +4,10 @@ import ( "time" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/analytics" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/hooks/hookexecution" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/analytics" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/hooks/hookexecution" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) type logAuction struct { diff --git a/analytics/pubstack/configupdate.go b/analytics/pubstack/configupdate.go index 0ecaaef05c3..166e69554d6 100644 --- a/analytics/pubstack/configupdate.go +++ b/analytics/pubstack/configupdate.go @@ -6,7 +6,7 @@ import ( "net/url" "time" - "github.com/prebid/prebid-server/v2/util/task" + "github.com/prebid/prebid-server/v3/util/task" ) // ConfigUpdateTask publishes configurations until the stop channel is signaled. diff --git a/analytics/pubstack/helpers/json.go b/analytics/pubstack/helpers/json.go index c46393cbed8..fbdc173219e 100644 --- a/analytics/pubstack/helpers/json.go +++ b/analytics/pubstack/helpers/json.go @@ -4,8 +4,8 @@ import ( "fmt" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/analytics" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/analytics" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) func JsonifyAuctionObject(ao *analytics.AuctionObject, scope string) ([]byte, error) { diff --git a/analytics/pubstack/helpers/json_test.go b/analytics/pubstack/helpers/json_test.go index 79055d16eb5..1e6282078c0 100644 --- a/analytics/pubstack/helpers/json_test.go +++ b/analytics/pubstack/helpers/json_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/analytics" + "github.com/prebid/prebid-server/v3/analytics" "github.com/stretchr/testify/assert" ) diff --git a/analytics/pubstack/helpers/model.go b/analytics/pubstack/helpers/model.go index 2af6a19e439..7dad2f7dade 100644 --- a/analytics/pubstack/helpers/model.go +++ b/analytics/pubstack/helpers/model.go @@ -4,10 +4,10 @@ import ( "time" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/analytics" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/hooks/hookexecution" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/analytics" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/hooks/hookexecution" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) type logAuction struct { diff --git a/analytics/pubstack/pubstack_module.go b/analytics/pubstack/pubstack_module.go index 535118c0000..c5bb02e2eb7 100644 --- a/analytics/pubstack/pubstack_module.go +++ b/analytics/pubstack/pubstack_module.go @@ -12,9 +12,9 @@ import ( "github.com/benbjohnson/clock" "github.com/golang/glog" - "github.com/prebid/prebid-server/v2/analytics" - "github.com/prebid/prebid-server/v2/analytics/pubstack/eventchannel" - "github.com/prebid/prebid-server/v2/analytics/pubstack/helpers" + "github.com/prebid/prebid-server/v3/analytics" + "github.com/prebid/prebid-server/v3/analytics/pubstack/eventchannel" + "github.com/prebid/prebid-server/v3/analytics/pubstack/helpers" ) type Configuration struct { @@ -200,6 +200,12 @@ func (p *PubstackModule) LogAmpObject(ao *analytics.AmpObject) { p.eventChannels[amp].Push(payload) } +// Shutdown - no op since the analytic module already implements system signal handling +// and trying to close a closed channel will cause panic +func (p *PubstackModule) Shutdown() { + glog.Info("[PubstackModule] Shutdown") +} + func (p *PubstackModule) start(c <-chan *Configuration) { for { select { diff --git a/analytics/pubstack/pubstack_module_test.go b/analytics/pubstack/pubstack_module_test.go index 911de4c6959..e2b4e118c6c 100644 --- a/analytics/pubstack/pubstack_module_test.go +++ b/analytics/pubstack/pubstack_module_test.go @@ -8,8 +8,8 @@ import ( "time" "github.com/benbjohnson/clock" - "github.com/prebid/prebid-server/v2/analytics" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/analytics" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) @@ -99,7 +99,7 @@ func TestNewModuleSuccess(t *testing.T) { { ImpId: "123", StatusCode: 34, - Ext: openrtb_ext.NonBidExt{Prebid: openrtb_ext.ExtResponseNonBidPrebid{Bid: openrtb_ext.NonBidObject{}}}, + Ext: &openrtb_ext.NonBidExt{Prebid: openrtb_ext.ExtResponseNonBidPrebid{Bid: openrtb_ext.NonBidObject{}}}, }, }, }, diff --git a/analytics/runner.go b/analytics/runner.go index 7a2c56f77dd..d10370e4857 100644 --- a/analytics/runner.go +++ b/analytics/runner.go @@ -1,7 +1,7 @@ package analytics import ( - "github.com/prebid/prebid-server/v2/privacy" + "github.com/prebid/prebid-server/v3/privacy" ) type Runner interface { @@ -11,4 +11,5 @@ type Runner interface { LogSetUIDObject(*SetUIDObject) LogAmpObject(*AmpObject, privacy.ActivityControl) LogNotificationEventObject(*NotificationEvent, privacy.ActivityControl) + Shutdown() } diff --git a/bidadjustment/apply.go b/bidadjustment/apply.go index 86bc813dbee..864d6bf6fb5 100644 --- a/bidadjustment/apply.go +++ b/bidadjustment/apply.go @@ -3,8 +3,8 @@ package bidadjustment import ( "math" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) const ( diff --git a/bidadjustment/apply_test.go b/bidadjustment/apply_test.go index 3fa46b6bcb2..1a9bf75a20c 100644 --- a/bidadjustment/apply_test.go +++ b/bidadjustment/apply_test.go @@ -4,8 +4,8 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" ) diff --git a/bidadjustment/build_rules.go b/bidadjustment/build_rules.go index 019ad87e9cf..2d0ac7c4cd8 100644 --- a/bidadjustment/build_rules.go +++ b/bidadjustment/build_rules.go @@ -1,8 +1,8 @@ package bidadjustment import ( - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) const ( diff --git a/bidadjustment/build_rules_test.go b/bidadjustment/build_rules_test.go index 2c19932fec7..29864bcdbc2 100644 --- a/bidadjustment/build_rules_test.go +++ b/bidadjustment/build_rules_test.go @@ -4,8 +4,8 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/bidadjustment/validate.go b/bidadjustment/validate.go index f34ef48ba49..b5383b4d1b5 100644 --- a/bidadjustment/validate.go +++ b/bidadjustment/validate.go @@ -3,7 +3,7 @@ package bidadjustment import ( "math" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // Validate checks whether all provided bid adjustments are valid or not against the requirements defined in the issue diff --git a/bidadjustment/validate_test.go b/bidadjustment/validate_test.go index caf4188bb5e..dedcddc9af8 100644 --- a/bidadjustment/validate_test.go +++ b/bidadjustment/validate_test.go @@ -3,7 +3,7 @@ package bidadjustment import ( "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/config/account.go b/config/account.go index 80ce6d41dea..a54da82d212 100644 --- a/config/account.go +++ b/config/account.go @@ -7,8 +7,8 @@ import ( "strings" "github.com/prebid/go-gdpr/consentconstants" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/iputil" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/iputil" ) // ChannelType enumerates the values of integrations Prebid Server can configure for an account diff --git a/config/account_test.go b/config/account_test.go index c529af09f15..97bb5bd0d3f 100644 --- a/config/account_test.go +++ b/config/account_test.go @@ -6,7 +6,7 @@ import ( "testing" "github.com/prebid/go-gdpr/consentconstants" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/config/bidderinfo.go b/config/bidderinfo.go index 6e38fc0c1db..d553df1f4e5 100644 --- a/config/bidderinfo.go +++ b/config/bidderinfo.go @@ -9,8 +9,8 @@ import ( "strings" "text/template" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" validator "github.com/asaskevich/govalidator" "gopkg.in/yaml.v3" @@ -201,6 +201,21 @@ func (bi BidderInfo) IsEnabled() bool { return !bi.Disabled } +// Defined returns true if at least one field exists, except for the supports field. +func (s *Syncer) Defined() bool { + if s == nil { + return false + } + + return s.Key != "" || + s.IFrame != nil || + s.Redirect != nil || + s.ExternalURL != "" || + s.SupportCORS != nil || + s.FormatOverride != "" || + s.SkipWhen != nil +} + type InfoReader interface { Read() (map[string][]byte, error) } @@ -335,7 +350,7 @@ func processBidderAliases(aliasNillableFieldsByBidder map[string]aliasNillableFi if aliasBidderInfo.PlatformID == "" { aliasBidderInfo.PlatformID = parentBidderInfo.PlatformID } - if aliasBidderInfo.Syncer == nil && parentBidderInfo.Syncer != nil { + if aliasBidderInfo.Syncer == nil && parentBidderInfo.Syncer.Defined() { syncerKey := aliasBidderInfo.AliasOf if parentBidderInfo.Syncer.Key != "" { syncerKey = parentBidderInfo.Syncer.Key diff --git a/config/bidderinfo_test.go b/config/bidderinfo_test.go index 3305e34e88a..9ad64ee213f 100644 --- a/config/bidderinfo_test.go +++ b/config/bidderinfo_test.go @@ -7,7 +7,8 @@ import ( "gopkg.in/yaml.v3" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/ptrutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -401,6 +402,15 @@ func TestProcessAliasBidderInfo(t *testing.T) { Key: "bidderA", } + parentWithSyncerSupports := parentWithoutSyncerKey + parentWithSyncerSupports.Syncer = &Syncer{ + Supports: []string{"iframe"}, + } + + aliasWithoutSyncer := parentWithoutSyncerKey + aliasWithoutSyncer.AliasOf = "bidderA" + aliasWithoutSyncer.Syncer = nil + testCases := []struct { description string aliasInfos map[string]aliasNillableFields @@ -428,6 +438,26 @@ func TestProcessAliasBidderInfo(t *testing.T) { expectedErr: nil, expectedBidderInfos: BidderInfos{"bidderA": parentWithSyncerKey, "bidderB": bidderB}, }, + { + description: "inherit all parent info in alias bidder, except for syncer is parent only defines supports", + aliasInfos: map[string]aliasNillableFields{ + "bidderB": { + Disabled: nil, + ModifyingVastXmlAllowed: nil, + Experiment: nil, + XAPI: nil, + }, + }, + bidderInfos: BidderInfos{ + "bidderA": parentWithSyncerSupports, + "bidderB": BidderInfo{ + AliasOf: "bidderA", + // all other fields should be inherited from parent bidder, except for syncer + }, + }, + expectedErr: nil, + expectedBidderInfos: BidderInfos{"bidderA": parentWithSyncerSupports, "bidderB": aliasWithoutSyncer}, + }, { description: "inherit all parent info in alias bidder, use parent name as syncer alias key", aliasInfos: map[string]aliasNillableFields{ @@ -1522,6 +1552,77 @@ func TestSyncerEndpointOverride(t *testing.T) { } } +func TestSyncerDefined(t *testing.T) { + testCases := []struct { + name string + givenSyncer *Syncer + expected bool + }{ + { + name: "nil", + givenSyncer: nil, + expected: false, + }, + { + name: "empty", + givenSyncer: &Syncer{}, + expected: false, + }, + { + name: "key-only", + givenSyncer: &Syncer{Key: "anyKey"}, + expected: true, + }, + { + name: "iframe-only", + givenSyncer: &Syncer{IFrame: &SyncerEndpoint{}}, + expected: true, + }, + { + name: "redirect-only", + givenSyncer: &Syncer{Redirect: &SyncerEndpoint{}}, + expected: true, + }, + { + name: "externalurl-only", + givenSyncer: &Syncer{ExternalURL: "anyURL"}, + expected: true, + }, + { + name: "supportscors-only", + givenSyncer: &Syncer{SupportCORS: ptrutil.ToPtr(false)}, + expected: true, + }, + { + name: "formatoverride-only", + givenSyncer: &Syncer{FormatOverride: "anyFormat"}, + expected: true, + }, + { + name: "skipwhen-only", + givenSyncer: &Syncer{SkipWhen: &SkipWhen{}}, + expected: true, + }, + { + name: "supports-only", + givenSyncer: &Syncer{Supports: []string{"anySupports"}}, + expected: false, + }, + { + name: "supports-with-other", + givenSyncer: &Syncer{Key: "anyKey", Supports: []string{"anySupports"}}, + expected: true, + }, + } + + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + result := test.givenSyncer.Defined() + assert.Equal(t, test.expected, result) + }) + } +} + func TestApplyBidderInfoConfigSyncerOverrides(t *testing.T) { var ( givenFileSystem = BidderInfos{"a": {Syncer: &Syncer{Key: "original"}}} diff --git a/config/compression.go b/config/compression.go index 2fe8e7b22ac..c838e3390a2 100644 --- a/config/compression.go +++ b/config/compression.go @@ -1,6 +1,6 @@ package config -import "github.com/prebid/prebid-server/v2/util/httputil" +import "github.com/prebid/prebid-server/v3/util/httputil" type Compression struct { Request CompressionInfo `mapstructure:"request"` diff --git a/config/compression_test.go b/config/compression_test.go index 230d1912345..78e7b6468e0 100644 --- a/config/compression_test.go +++ b/config/compression_test.go @@ -3,7 +3,7 @@ package config import ( "testing" - "github.com/prebid/prebid-server/v2/util/httputil" + "github.com/prebid/prebid-server/v3/util/httputil" "github.com/stretchr/testify/assert" ) diff --git a/config/config.go b/config/config.go index bc1e17fbc29..30f8d69adc1 100644 --- a/config/config.go +++ b/config/config.go @@ -12,9 +12,9 @@ import ( "github.com/golang/glog" "github.com/prebid/go-gdpr/consentconstants" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" "github.com/spf13/viper" ) @@ -68,9 +68,9 @@ type Configuration struct { VideoStoredRequestRequired bool `mapstructure:"video_stored_request_required"` - // Array of blacklisted apps that is used to create the hash table BlacklistedAppMap so App.ID's can be instantly accessed. - BlacklistedApps []string `mapstructure:"blacklisted_apps,flow"` - BlacklistedAppMap map[string]bool + // Array of blocked apps that is used to create the hash table BlockedAppsLookup so App.ID's can be instantly accessed. + BlockedApps []string `mapstructure:"blocked_apps,flow"` + BlockedAppsLookup map[string]bool // Is publisher/account ID required to be submitted in the OpenRTB2 request AccountRequired bool `mapstructure:"account_required"` // AccountDefaults defines default settings for valid accounts that are partially defined @@ -796,10 +796,10 @@ func New(v *viper.Viper, bidderInfos BidderInfos, normalizeBidderName openrtb_ex } // To look for a request's app_id in O(1) time, we fill this hash table located in the - // the BlacklistedApps field of the Configuration struct defined in this file - c.BlacklistedAppMap = make(map[string]bool) - for i := 0; i < len(c.BlacklistedApps); i++ { - c.BlacklistedAppMap[c.BlacklistedApps[i]] = true + // the BlockedApps field of the Configuration struct defined in this file + c.BlockedAppsLookup = make(map[string]bool) + for i := 0; i < len(c.BlockedApps); i++ { + c.BlockedAppsLookup[c.BlockedApps[i]] = true } // Migrate combo stored request config to separate stored_reqs and amp stored_reqs configs. @@ -1148,8 +1148,7 @@ func SetupViper(v *viper.Viper, filename string, bidderInfos BidderInfos) { v.SetDefault("default_request.type", "") v.SetDefault("default_request.file.name", "") v.SetDefault("default_request.alias_info", false) - v.SetDefault("blacklisted_apps", []string{""}) - v.SetDefault("blacklisted_accts", []string{""}) + v.SetDefault("blocked_apps", []string{""}) v.SetDefault("account_required", false) v.SetDefault("account_defaults.disabled", false) v.SetDefault("account_defaults.debug_allow", true) diff --git a/config/config_test.go b/config/config_test.go index 414f2635fd5..a68f478a642 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -10,8 +10,8 @@ import ( "time" "github.com/prebid/go-gdpr/consentconstants" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/ptrutil" "github.com/spf13/viper" "github.com/stretchr/testify/assert" ) @@ -451,7 +451,7 @@ metrics: adapter_buyeruid_scrubbed: false adapter_gdpr_request_blocked: true account_modules_metrics: true -blacklisted_apps: ["spamAppID","sketchy-app-id"] +blocked_apps: ["spamAppID","sketchy-app-id"] account_required: true auto_gen_source_tid: false certificates_file: /etc/ssl/cert.pem @@ -714,12 +714,12 @@ func TestFullConfig(t *testing.T) { cmpBools(t, "lmt.enforce", true, cfg.LMT.Enforce) //Assert the NonStandardPublishers was correctly unmarshalled - cmpStrings(t, "blacklisted_apps", "spamAppID", cfg.BlacklistedApps[0]) - cmpStrings(t, "blacklisted_apps", "sketchy-app-id", cfg.BlacklistedApps[1]) + cmpStrings(t, "blocked_apps", "spamAppID", cfg.BlockedApps[0]) + cmpStrings(t, "blocked_apps", "sketchy-app-id", cfg.BlockedApps[1]) - //Assert the BlacklistedAppMap hash table was built correctly - for i := 0; i < len(cfg.BlacklistedApps); i++ { - cmpBools(t, "cfg.BlacklistedAppMap", true, cfg.BlacklistedAppMap[cfg.BlacklistedApps[i]]) + //Assert the BlockedAppsLookup hash table was built correctly + for i := 0; i < len(cfg.BlockedApps); i++ { + cmpBools(t, "cfg.BlockedAppsLookup", true, cfg.BlockedAppsLookup[cfg.BlockedApps[i]]) } //Assert purpose VendorExceptionMap hash tables were built correctly diff --git a/currency/currency.go b/currency/currency.go index 060649f9c11..b4d886274e3 100644 --- a/currency/currency.go +++ b/currency/currency.go @@ -1,7 +1,7 @@ package currency import ( - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func GetAuctionCurrencyRates(currencyConverter *RateConverter, requestRates *openrtb_ext.ExtRequestCurrency) Conversions { diff --git a/currency/currency_test.go b/currency/currency_test.go index d462cc8bdab..e86ee4537fe 100644 --- a/currency/currency_test.go +++ b/currency/currency_test.go @@ -4,9 +4,9 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/jsonutil" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/currency/rate_converter.go b/currency/rate_converter.go index 1dd18fabcb1..2e39b57f403 100644 --- a/currency/rate_converter.go +++ b/currency/rate_converter.go @@ -8,9 +8,9 @@ import ( "time" "github.com/golang/glog" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/util/jsonutil" - "github.com/prebid/prebid-server/v2/util/timeutil" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/timeutil" ) // RateConverter holds the currencies conversion rates dictionary diff --git a/currency/rate_converter_test.go b/currency/rate_converter_test.go index 96003c7d986..95049916194 100644 --- a/currency/rate_converter_test.go +++ b/currency/rate_converter_test.go @@ -9,7 +9,7 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/v2/util/task" + "github.com/prebid/prebid-server/v3/util/task" "github.com/stretchr/testify/assert" ) diff --git a/currency/rates_test.go b/currency/rates_test.go index 254bc282dec..6fb444f32c4 100644 --- a/currency/rates_test.go +++ b/currency/rates_test.go @@ -6,7 +6,7 @@ import ( "github.com/stretchr/testify/assert" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) func TestUnMarshallRates(t *testing.T) { diff --git a/currency/validation.go b/currency/validation.go index d6429c357b6..5e23362e5b1 100644 --- a/currency/validation.go +++ b/currency/validation.go @@ -5,8 +5,8 @@ import ( "golang.org/x/text/currency" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // ValidateCustomRates throws a bad input error if any of the 3-digit currency codes found in diff --git a/currency/validation_test.go b/currency/validation_test.go index 65f93a5f9e9..0edd5c89a34 100644 --- a/currency/validation_test.go +++ b/currency/validation_test.go @@ -3,8 +3,8 @@ package currency import ( "testing" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/docs/build/README.md b/docs/build/README.md new file mode 100644 index 00000000000..0b52671f216 --- /dev/null +++ b/docs/build/README.md @@ -0,0 +1,110 @@ +## Overview + +As of v2.31.0, Prebid Server contains a module that requires CGo which introduces both build and runtime dependencies. To build, you need a C compiler, preferably gcc. To run, you may require one or more runtime dependencies, most notably libatomic. + +## Examples +For a containerized example, see the Dockerfile. +For manual build examples, including some cross-compilation use cases, see below. + +### From darwin amd64 + +#### To darwin amd64 +`GOOS=darwin GOARCH=amd64 CGO_ENABLED=1 go build` + +Running the built binary on mac amd64: +`./prebid-server --stderrthreshold=WARNING -v=2` + +#### To darwin arm64 +`GOOS=darwin GOARCH=arm64 CGO_ENABLED=1 go build` + +Running the built binary on mac arm64: +`./prebid-server --stderrthreshold=WARNING -v=2` + +#### To windows amd64 +Build +Install mingw-w64 which consists of a gcc compiler port you can use to generate windows binaries: +`brew install mingw-w64` + +`GOOS=windows GOARCH=amd64 CGO_ENABLED=1 CC="x86_64-w64-mingw32-gcc" go build` + +Run +Running the built binary on windows: +`.\prebid-server.exe --sderrthreshold=WARNING =v=2` + +You may receive the following errors or something similar: +``` +"The code execution cannot proceed because libatomic-1.dll was not found." +"The code execution cannot proceed because libwinpthread-1.dll was not found." +``` + +To resolve these errors, copy the following files from mingw-64 on your mac to `C:/windows/System32` and re-run: +`/usr/local/Cellar/mingw-w64/12.0.0_1/toolchain-x86_64/x86_64-w64-mingw32/lib/libatomic-1.dll` +`/usr/local/Cellar/mingw-w64/12.0.0_1/toolchain-x86_64/x86_64-w64-mingw32/bin/libwinpthread-1.dll` + +### From windows amd64 +#### To windows amd64 +Build +`set CGO_ENABLED=1` +`set GOOS=windows` +`set GOARCH=amd64` +`go build . && .\prebid-server.exe --stderrthreshold=WARNING -v=2` + +You may receive the following error or something similar: +``` +# runtime/cgo +cgo: C compiler "gcc" not found: exec: "gcc": executable file not found in %PATH% +``` + +To resolve the error, install MSYS2: +1) Download the installer (https://www.msys2.org/) +2) Run the installer and follow the steps of the installation wizard +3) Run MSYS2 which will open an MSYS2 terminal for you +4) In the MSYS2 terminal, install windows/amd64 gcc toolchain: `pacman -S --needed base-devel mingw-w64-x86_64-gcc` +5) Enter `Y` when prompted whether to proceed with the installation +6) Add the path of your MinGW-w64 `bin` folder to the Windows `PATH` environment variable by using the following steps: + - In the Windows search bar, type Settings to open your Windows Settings. + - Search for Edit environment variables for your account. + - In your User variables, select the `Path` variable and then select Edit. + - Select New and add the MinGW-w64 destination folder you recorded during the installation process to the list. If you used the default settings above, then this will be the path: `C:\msys64\ucrt64\bin`. + - Select OK, and then select OK again in the Environment Variables window to update the `PATH` environment variable. You have to reopen any console windows for the updated `PATH` environment variable to be available. +7) Confirm gcc installed: `gcc --version` + +Run +Running the built binary on windows: +`go build . && .\prebid-server.exe --stderrthreshold=WARNING -v=2` + +You may receive the following errors or something similar: +``` +"The code execution cannot proceed because libatomic-1.dll was not found." +"The code execution cannot proceed because libwinpthread-1.dll was not found." +``` +To resolve these errors, copy the following files from MSYS2 installation to `C:/windows/System32` and re-run: +`C:\mysys64\mingw64\bin\libatomic-1.dll` +`C:\mysys64\mingw64\bin\libwinpthread-1.dll` + +### From linux amd64 +#### To linux amd64 +Note +These instructions are for building and running on Debian-based distributions + +Build +`GOOS=linux GOARCH=amd64 CGO_ENABLED=1 go build` + +You may receive the following error or something similar: +``` +# runtime/cgo +cgo: C compiler "gcc" not found: exec: "gcc": executable file not found in $PATH +``` +To resolve the error, install gcc and re-build: +`sudo apt-get install -y gcc` + +Run +Running the built binary on Linux: +`./prebid-server --stderrthreshold=WARNING -v=2` + +You may receive the following error or something similar: +``` +... error while loading shared libraries: libatomic.so.1: cannot open shared object file ... +``` +To resolve the error, install libatomic1 and re-run: +`sudo apt-get install -y libatomic1` \ No newline at end of file diff --git a/dsa/validate.go b/dsa/validate.go index 034dae8b3cf..3dce2fba1c1 100644 --- a/dsa/validate.go +++ b/dsa/validate.go @@ -3,9 +3,9 @@ package dsa import ( "errors" - "github.com/prebid/prebid-server/v2/exchange/entities" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/exchange/entities" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) // Required values representing whether a DSA object is required diff --git a/dsa/validate_test.go b/dsa/validate_test.go index 9dfa32c6efe..e0af9bc80af 100644 --- a/dsa/validate_test.go +++ b/dsa/validate_test.go @@ -6,9 +6,9 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/exchange/entities" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/exchange/entities" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/dsa/writer.go b/dsa/writer.go index 9cf276de216..33d0bda6d39 100644 --- a/dsa/writer.go +++ b/dsa/writer.go @@ -1,8 +1,8 @@ package dsa import ( - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // Writer is used to write the default DSA to the request (req.regs.ext.dsa) diff --git a/dsa/writer_test.go b/dsa/writer_test.go index 7f5305121d6..bbe82e0b693 100644 --- a/dsa/writer_test.go +++ b/dsa/writer_test.go @@ -5,9 +5,9 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/endpoints/cookie_sync.go b/endpoints/cookie_sync.go index d6e0b31a096..51fe8d57514 100644 --- a/endpoints/cookie_sync.go +++ b/endpoints/cookie_sync.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "io" + "math" "net/http" "strconv" "strings" @@ -15,22 +16,22 @@ import ( "github.com/julienschmidt/httprouter" gpplib "github.com/prebid/go-gpp" gppConstants "github.com/prebid/go-gpp/constants" - accountService "github.com/prebid/prebid-server/v2/account" - "github.com/prebid/prebid-server/v2/analytics" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/gdpr" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/metrics" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/privacy" - "github.com/prebid/prebid-server/v2/privacy/ccpa" - gppPrivacy "github.com/prebid/prebid-server/v2/privacy/gpp" - "github.com/prebid/prebid-server/v2/stored_requests" - "github.com/prebid/prebid-server/v2/usersync" - "github.com/prebid/prebid-server/v2/util/jsonutil" - stringutil "github.com/prebid/prebid-server/v2/util/stringutil" - "github.com/prebid/prebid-server/v2/util/timeutil" + accountService "github.com/prebid/prebid-server/v3/account" + "github.com/prebid/prebid-server/v3/analytics" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/gdpr" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/metrics" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/privacy" + "github.com/prebid/prebid-server/v3/privacy/ccpa" + gppPrivacy "github.com/prebid/prebid-server/v3/privacy/gpp" + "github.com/prebid/prebid-server/v3/stored_requests" + "github.com/prebid/prebid-server/v3/usersync" + "github.com/prebid/prebid-server/v3/util/jsonutil" + stringutil "github.com/prebid/prebid-server/v3/util/stringutil" + "github.com/prebid/prebid-server/v3/util/timeutil" ) const receiveCookieDeprecation = "receive-cookie-deprecation" @@ -174,6 +175,11 @@ func (c *cookieSyncEndpoint) parseRequest(r *http.Request) (usersync.Request, ma tcf2Cfg := c.privacyConfig.tcf2ConfigBuilder(c.privacyConfig.gdprConfig.TCF2, account.GDPR) gdprPerms := c.privacyConfig.gdprPermissionsBuilder(tcf2Cfg, gdprRequestInfo) + limit := math.MaxInt + if request.Limit != nil { + limit = *request.Limit + } + rx := usersync.Request{ Bidders: request.Bidders, Cooperative: usersync.Cooperative{ @@ -181,7 +187,7 @@ func (c *cookieSyncEndpoint) parseRequest(r *http.Request) (usersync.Request, ma PriorityGroups: c.config.UserSync.PriorityGroups, }, Debug: request.Debug, - Limit: request.Limit, + Limit: limit, Privacy: usersyncPrivacy{ gdprPermissions: gdprPerms, ccpaParsedPolicy: ccpaParsedPolicy, @@ -285,17 +291,38 @@ func (c *cookieSyncEndpoint) writeParseRequestErrorMetrics(err error) { } func (c *cookieSyncEndpoint) setLimit(request cookieSyncRequest, cookieSyncConfig config.CookieSync) cookieSyncRequest { - if request.Limit <= 0 && cookieSyncConfig.DefaultLimit != nil { - request.Limit = *cookieSyncConfig.DefaultLimit + limit := getEffectiveLimit(request.Limit, cookieSyncConfig.DefaultLimit) + maxLimit := getEffectiveMaxLimit(cookieSyncConfig.MaxLimit) + if maxLimit < limit { + request.Limit = &maxLimit + } else { + request.Limit = &limit } - if cookieSyncConfig.MaxLimit != nil && (request.Limit <= 0 || request.Limit > *cookieSyncConfig.MaxLimit) { - request.Limit = *cookieSyncConfig.MaxLimit + return request +} + +func getEffectiveLimit(reqLimit *int, defaultLimit *int) int { + limit := reqLimit + + if limit == nil { + limit = defaultLimit } - if request.Limit < 0 { - request.Limit = 0 + + if limit != nil && *limit > 0 { + return *limit } - return request + return math.MaxInt +} + +func getEffectiveMaxLimit(maxLimit *int) int { + limit := maxLimit + + if limit != nil && *limit > 0 { + return *limit + } + + return math.MaxInt } func (c *cookieSyncEndpoint) setCooperativeSync(request cookieSyncRequest, cookieSyncConfig config.CookieSync) cookieSyncRequest { @@ -402,8 +429,8 @@ func (c *cookieSyncEndpoint) writeSyncerMetrics(biddersEvaluated []usersync.Bidd c.metrics.RecordSyncerRequest(bidder.SyncerKey, metrics.SyncerCookieSyncPrivacyBlocked) case usersync.StatusAlreadySynced: c.metrics.RecordSyncerRequest(bidder.SyncerKey, metrics.SyncerCookieSyncAlreadySynced) - case usersync.StatusTypeNotSupported: - c.metrics.RecordSyncerRequest(bidder.SyncerKey, metrics.SyncerCookieSyncTypeNotSupported) + case usersync.StatusRejectedByFilter: + c.metrics.RecordSyncerRequest(bidder.SyncerKey, metrics.SyncerCookieSyncRejectedByFilter) } } } @@ -524,8 +551,8 @@ func getDebugMessage(status usersync.Status) string { return "Unsupported bidder" case usersync.StatusUnconfiguredBidder: return "No sync config" - case usersync.StatusTypeNotSupported: - return "Type not supported" + case usersync.StatusRejectedByFilter: + return "Rejected by request filter" case usersync.StatusBlockedByDisabledUsersync: return "Sync disabled by config" } @@ -537,7 +564,7 @@ type cookieSyncRequest struct { GDPR *int `json:"gdpr"` GDPRConsent string `json:"gdpr_consent"` USPrivacy string `json:"us_privacy"` - Limit int `json:"limit"` + Limit *int `json:"limit"` GPP string `json:"gpp"` GPPSID string `json:"gpp_sid"` CooperativeSync *bool `json:"coopSync"` diff --git a/endpoints/cookie_sync_test.go b/endpoints/cookie_sync_test.go index edd1958fcb0..e1a7a1d8e14 100644 --- a/endpoints/cookie_sync_test.go +++ b/endpoints/cookie_sync_test.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "io" + "math" "net/http" "net/http/httptest" "strconv" @@ -14,17 +15,17 @@ import ( "testing/iotest" "time" - "github.com/prebid/prebid-server/v2/analytics" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/gdpr" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/metrics" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/privacy" - "github.com/prebid/prebid-server/v2/privacy/ccpa" - "github.com/prebid/prebid-server/v2/usersync" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/analytics" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/gdpr" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/metrics" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/privacy" + "github.com/prebid/prebid-server/v3/privacy/ccpa" + "github.com/prebid/prebid-server/v3/usersync" + "github.com/prebid/prebid-server/v3/util/ptrutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" ) @@ -692,6 +693,7 @@ func TestCookieSyncParseRequest(t *testing.T) { givenCCPAEnabled: true, expectedPrivacy: macros.UserSyncPrivacy{}, expectedRequest: usersync.Request{ + Limit: math.MaxInt, Privacy: usersyncPrivacy{ gdprPermissions: &fakePermissions{}, activityRequest: emptyActivityPoliciesRequest, @@ -720,6 +722,7 @@ func TestCookieSyncParseRequest(t *testing.T) { Enabled: true, PriorityGroups: [][]string{{"a", "b", "c"}}, }, + Limit: math.MaxInt, Privacy: usersyncPrivacy{ gdprPermissions: &fakePermissions{}, activityRequest: emptyActivityPoliciesRequest, @@ -748,6 +751,7 @@ func TestCookieSyncParseRequest(t *testing.T) { Enabled: false, PriorityGroups: [][]string{{"a", "b", "c"}}, }, + Limit: math.MaxInt, Privacy: usersyncPrivacy{ gdprPermissions: &fakePermissions{}, activityRequest: emptyActivityPoliciesRequest, @@ -776,6 +780,7 @@ func TestCookieSyncParseRequest(t *testing.T) { Enabled: false, PriorityGroups: [][]string{{"a", "b", "c"}}, }, + Limit: math.MaxInt, Privacy: usersyncPrivacy{ gdprPermissions: &fakePermissions{}, activityRequest: emptyActivityPoliciesRequest, @@ -804,6 +809,7 @@ func TestCookieSyncParseRequest(t *testing.T) { Enabled: false, PriorityGroups: [][]string{{"a", "b", "c"}}, }, + Limit: math.MaxInt, Privacy: usersyncPrivacy{ gdprPermissions: &fakePermissions{}, activityRequest: emptyActivityPoliciesRequest, @@ -832,6 +838,7 @@ func TestCookieSyncParseRequest(t *testing.T) { Enabled: true, PriorityGroups: [][]string{{"a", "b", "c"}}, }, + Limit: math.MaxInt, Privacy: usersyncPrivacy{ gdprPermissions: &fakePermissions{}, activityRequest: emptyActivityPoliciesRequest, @@ -860,6 +867,7 @@ func TestCookieSyncParseRequest(t *testing.T) { Enabled: true, PriorityGroups: [][]string{{"a", "b", "c"}}, }, + Limit: math.MaxInt, Privacy: usersyncPrivacy{ gdprPermissions: &fakePermissions{}, activityRequest: emptyActivityPoliciesRequest, @@ -878,6 +886,7 @@ func TestCookieSyncParseRequest(t *testing.T) { givenCCPAEnabled: true, expectedPrivacy: macros.UserSyncPrivacy{}, expectedRequest: usersync.Request{ + Limit: math.MaxInt, Privacy: usersyncPrivacy{ gdprPermissions: &fakePermissions{}, activityRequest: emptyActivityPoliciesRequest, @@ -898,6 +907,7 @@ func TestCookieSyncParseRequest(t *testing.T) { USPrivacy: "1NYN", }, expectedRequest: usersync.Request{ + Limit: math.MaxInt, Privacy: usersyncPrivacy{ gdprPermissions: &fakePermissions{}, activityRequest: emptyActivityPoliciesRequest, @@ -939,6 +949,7 @@ func TestCookieSyncParseRequest(t *testing.T) { GDPR: "0", }, expectedRequest: usersync.Request{ + Limit: math.MaxInt, Privacy: usersyncPrivacy{ gdprPermissions: &fakePermissions{}, activityRequest: emptyActivityPoliciesRequest, @@ -966,6 +977,7 @@ func TestCookieSyncParseRequest(t *testing.T) { GDPR: "", }, expectedRequest: usersync.Request{ + Limit: math.MaxInt, Privacy: usersyncPrivacy{ gdprPermissions: &fakePermissions{}, activityRequest: emptyActivityPoliciesRequest, @@ -1135,152 +1147,242 @@ func TestCookieSyncParseRequest(t *testing.T) { } } -func TestSetLimit(t *testing.T) { - intNegative1 := -1 - int20 := 20 - int30 := 30 - int40 := 40 +func TestGetEffectiveLimit(t *testing.T) { + intNegative := ptrutil.ToPtr(-1) + int0 := ptrutil.ToPtr(0) + int30 := ptrutil.ToPtr(30) + int40 := ptrutil.ToPtr(40) + intMax := ptrutil.ToPtr(math.MaxInt) - testCases := []struct { - description string - givenRequest cookieSyncRequest - givenAccount *config.Account - expectedRequest cookieSyncRequest + tests := []struct { + name string + reqLimit *int + defaultLimit *int + expectedLimit int }{ { - description: "Default Limit is Applied (request limit = 0)", - givenRequest: cookieSyncRequest{ - Limit: 0, - }, - givenAccount: &config.Account{ - CookieSync: config.CookieSync{ - DefaultLimit: &int20, - }, - }, - expectedRequest: cookieSyncRequest{ - Limit: 20, - }, + name: "nil", + reqLimit: nil, + defaultLimit: nil, + expectedLimit: math.MaxInt, }, { - description: "Default Limit is Not Applied (default limit not set)", - givenRequest: cookieSyncRequest{ - Limit: 0, - }, - givenAccount: &config.Account{ - CookieSync: config.CookieSync{ - DefaultLimit: nil, - }, - }, - expectedRequest: cookieSyncRequest{ - Limit: 0, - }, + name: "req_limit_negative", + reqLimit: intNegative, + defaultLimit: nil, + expectedLimit: math.MaxInt, }, { - description: "Default Limit is Not Applied (request limit > 0)", - givenRequest: cookieSyncRequest{ - Limit: 10, - }, - givenAccount: &config.Account{ - CookieSync: config.CookieSync{ - DefaultLimit: &int20, - }, - }, - expectedRequest: cookieSyncRequest{ - Limit: 10, - }, + name: "req_limit_zero", + reqLimit: int0, + defaultLimit: nil, + expectedLimit: math.MaxInt, + }, + { + name: "req_limit_in_range", + reqLimit: int30, + defaultLimit: nil, + expectedLimit: 30, + }, + { + name: "req_limit_at_max", + reqLimit: intMax, + defaultLimit: nil, + expectedLimit: math.MaxInt, + }, + { + name: "default_limit_negative", + reqLimit: nil, + defaultLimit: intNegative, + expectedLimit: math.MaxInt, + }, + { + name: "default_limit_zero", + reqLimit: nil, + defaultLimit: intNegative, + expectedLimit: math.MaxInt, + }, + { + name: "default_limit_in_range", + reqLimit: nil, + defaultLimit: int30, + expectedLimit: 30, + }, + { + name: "default_limit_at_max", + reqLimit: nil, + defaultLimit: intMax, + expectedLimit: math.MaxInt, }, { - description: "Max Limit is Applied (request limit <= 0)", + name: "both_in_range", + reqLimit: int30, + defaultLimit: int40, + expectedLimit: 30, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + result := getEffectiveLimit(test.reqLimit, test.defaultLimit) + assert.Equal(t, test.expectedLimit, result) + }) + } +} + +func TestGetEffectiveMaxLimit(t *testing.T) { + intNegative := ptrutil.ToPtr(-1) + int0 := ptrutil.ToPtr(0) + int30 := ptrutil.ToPtr(30) + intMax := ptrutil.ToPtr(math.MaxInt) + + tests := []struct { + name string + maxLimit *int + expectedLimit int + }{ + { + name: "nil", + maxLimit: nil, + expectedLimit: math.MaxInt, + }, + { + name: "req_limit_negative", + maxLimit: intNegative, + expectedLimit: math.MaxInt, + }, + { + name: "req_limit_zero", + maxLimit: int0, + expectedLimit: math.MaxInt, + }, + { + name: "req_limit_in_range", + maxLimit: int30, + expectedLimit: 30, + }, + { + name: "req_limit_too_large", + maxLimit: intMax, + expectedLimit: math.MaxInt, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + result := getEffectiveMaxLimit(test.maxLimit) + assert.Equal(t, test.expectedLimit, result) + }) + } +} + +func TestSetLimit(t *testing.T) { + intNegative := ptrutil.ToPtr(-1) + int0 := ptrutil.ToPtr(0) + int10 := ptrutil.ToPtr(10) + int20 := ptrutil.ToPtr(20) + int30 := ptrutil.ToPtr(30) + intMax := ptrutil.ToPtr(math.MaxInt) + + tests := []struct { + name string + givenRequest cookieSyncRequest + givenAccount *config.Account + expectedRequest cookieSyncRequest + }{ + { + name: "nil_limits", givenRequest: cookieSyncRequest{ - Limit: 0, + Limit: nil, }, givenAccount: &config.Account{ CookieSync: config.CookieSync{ - MaxLimit: &int30, + DefaultLimit: nil, + MaxLimit: nil, }, }, expectedRequest: cookieSyncRequest{ - Limit: 30, + Limit: intMax, }, }, { - description: "Max Limit is Applied (0 < max < limit)", + name: "limit_negative", givenRequest: cookieSyncRequest{ - Limit: 40, + Limit: intNegative, }, givenAccount: &config.Account{ CookieSync: config.CookieSync{ - MaxLimit: &int30, + DefaultLimit: int20, }, }, expectedRequest: cookieSyncRequest{ - Limit: 30, + Limit: intMax, }, }, { - description: "Max Limit is Not Applied (max not set)", + name: "limit_zero", givenRequest: cookieSyncRequest{ - Limit: 10, + Limit: int0, }, givenAccount: &config.Account{ CookieSync: config.CookieSync{ - MaxLimit: nil, + DefaultLimit: int20, }, }, expectedRequest: cookieSyncRequest{ - Limit: 10, + Limit: intMax, }, }, { - description: "Max Limit is Not Applied (0 < limit < max)", + name: "limit_less_than_max", givenRequest: cookieSyncRequest{ - Limit: 10, + Limit: int10, }, givenAccount: &config.Account{ CookieSync: config.CookieSync{ - MaxLimit: &int30, + DefaultLimit: int20, + MaxLimit: int30, }, }, expectedRequest: cookieSyncRequest{ - Limit: 10, + Limit: int10, }, }, { - description: "Max Limit is Applied After applying the default", + name: "limit_greater_than_max", givenRequest: cookieSyncRequest{ - Limit: 0, + Limit: int30, }, givenAccount: &config.Account{ CookieSync: config.CookieSync{ - DefaultLimit: &int40, - MaxLimit: &int30, + DefaultLimit: int20, + MaxLimit: int10, }, }, expectedRequest: cookieSyncRequest{ - Limit: 30, + Limit: int10, }, }, { - description: "Negative Value Check", + name: "limit_at_max", givenRequest: cookieSyncRequest{ - Limit: 0, + Limit: intMax, }, givenAccount: &config.Account{ - CookieSync: config.CookieSync{ - DefaultLimit: &intNegative1, - MaxLimit: &intNegative1, - }, + CookieSync: config.CookieSync{}, }, expectedRequest: cookieSyncRequest{ - Limit: 0, + Limit: intMax, }, }, } - for _, test := range testCases { - endpoint := cookieSyncEndpoint{} - request := endpoint.setLimit(test.givenRequest, test.givenAccount.CookieSync) - assert.Equal(t, test.expectedRequest, request, test.description) + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + endpoint := cookieSyncEndpoint{} + request := endpoint.setLimit(test.givenRequest, test.givenAccount.CookieSync) + assert.Equal(t, test.expectedRequest, request) + }) } } @@ -1642,10 +1744,10 @@ func TestCookieSyncWriteBidderMetrics(t *testing.T) { }, }, { - description: "One - Type Not Supported", - given: []usersync.BidderEvaluation{{Bidder: "a", SyncerKey: "aSyncer", Status: usersync.StatusTypeNotSupported}}, + description: "One - Rejected By Filter", + given: []usersync.BidderEvaluation{{Bidder: "a", SyncerKey: "aSyncer", Status: usersync.StatusRejectedByFilter}}, setExpectations: func(m *metrics.MetricsEngineMock) { - m.On("RecordSyncerRequest", "aSyncer", metrics.SyncerCookieSyncTypeNotSupported).Once() + m.On("RecordSyncerRequest", "aSyncer", metrics.SyncerCookieSyncRejectedByFilter).Once() }, }, { @@ -1699,7 +1801,7 @@ func TestCookieSyncHandleResponse(t *testing.T) { {Bidder: "Bidder2", Status: usersync.StatusUnknownBidder}, {Bidder: "Bidder3", Status: usersync.StatusUnconfiguredBidder}, {Bidder: "Bidder4", Status: usersync.StatusBlockedByPrivacy}, - {Bidder: "Bidder5", Status: usersync.StatusTypeNotSupported}, + {Bidder: "Bidder5", Status: usersync.StatusRejectedByFilter}, {Bidder: "Bidder6", Status: usersync.StatusBlockedByUserOptOut}, {Bidder: "Bidder7", Status: usersync.StatusBlockedByDisabledUsersync}, {Bidder: "BidderA", Status: usersync.StatusDuplicate, SyncerKey: "syncerB"}, @@ -1792,7 +1894,7 @@ func TestCookieSyncHandleResponse(t *testing.T) { givenCookieHasSyncs: true, givenDebug: true, givenSyncersChosen: []usersync.SyncerChoice{}, - expectedJSON: `{"status":"ok","bidder_status":[],"debug":[{"bidder":"Bidder1","error":"Already in sync"},{"bidder":"Bidder2","error":"Unsupported bidder"},{"bidder":"Bidder3","error":"No sync config"},{"bidder":"Bidder4","error":"Rejected by privacy"},{"bidder":"Bidder5","error":"Type not supported"},{"bidder":"Bidder6","error":"Status blocked by user opt out"},{"bidder":"Bidder7","error":"Sync disabled by config"},{"bidder":"BidderA","error":"Duplicate bidder synced as syncerB"}]}` + "\n", + expectedJSON: `{"status":"ok","bidder_status":[],"debug":[{"bidder":"Bidder1","error":"Already in sync"},{"bidder":"Bidder2","error":"Unsupported bidder"},{"bidder":"Bidder3","error":"No sync config"},{"bidder":"Bidder4","error":"Rejected by privacy"},{"bidder":"Bidder5","error":"Rejected by request filter"},{"bidder":"Bidder6","error":"Status blocked by user opt out"},{"bidder":"Bidder7","error":"Sync disabled by config"},{"bidder":"BidderA","error":"Duplicate bidder synced as syncerB"}]}` + "\n", expectedAnalytics: analytics.CookieSyncObject{Status: 200, BidderStatus: []*analytics.CookieSyncBidder{}}, }, } @@ -2198,6 +2300,10 @@ func (m *MockAnalyticsRunner) LogNotificationEventObject(obj *analytics.Notifica m.Called(obj, ac) } +func (m *MockAnalyticsRunner) Shutdown() { + m.Called() +} + type MockGDPRPerms struct { mock.Mock } @@ -2212,9 +2318,9 @@ func (m *MockGDPRPerms) BidderSyncAllowed(ctx context.Context, bidder openrtb_ex return args.Bool(0), args.Error(1) } -func (m *MockGDPRPerms) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) (permissions gdpr.AuctionPermissions, err error) { +func (m *MockGDPRPerms) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) gdpr.AuctionPermissions { args := m.Called(ctx, bidderCoreName, bidder) - return args.Get(0).(gdpr.AuctionPermissions), args.Error(1) + return args.Get(0).(gdpr.AuctionPermissions) } type FakeAccountsFetcher struct { @@ -2244,10 +2350,10 @@ func (p *fakePermissions) BidderSyncAllowed(ctx context.Context, bidder openrtb_ return true, nil } -func (p *fakePermissions) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) (permissions gdpr.AuctionPermissions, err error) { +func (p *fakePermissions) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) gdpr.AuctionPermissions { return gdpr.AuctionPermissions{ AllowBidRequest: true, - }, nil + } } func getDefaultActivityConfig(componentName string, allow bool) *config.AccountPrivacy { diff --git a/endpoints/currency_rates.go b/endpoints/currency_rates.go index f08154471fe..9d27fb2497d 100644 --- a/endpoints/currency_rates.go +++ b/endpoints/currency_rates.go @@ -5,8 +5,8 @@ import ( "time" "github.com/golang/glog" - "github.com/prebid/prebid-server/v2/currency" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/currency" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) // currencyRatesInfo holds currency rates information. diff --git a/endpoints/currency_rates_test.go b/endpoints/currency_rates_test.go index 0b953c640e2..00da093a2d5 100644 --- a/endpoints/currency_rates_test.go +++ b/endpoints/currency_rates_test.go @@ -7,7 +7,7 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/v2/currency" + "github.com/prebid/prebid-server/v3/currency" "github.com/stretchr/testify/assert" ) diff --git a/endpoints/events/account_test.go b/endpoints/events/account_test.go index d19a3912f59..b379621b061 100644 --- a/endpoints/events/account_test.go +++ b/endpoints/events/account_test.go @@ -9,10 +9,10 @@ import ( "testing" "github.com/julienschmidt/httprouter" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/metrics" - "github.com/prebid/prebid-server/v2/stored_requests" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/metrics" + "github.com/prebid/prebid-server/v3/stored_requests" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/endpoints/events/event.go b/endpoints/events/event.go index e202932aff8..fa2fca2f96c 100644 --- a/endpoints/events/event.go +++ b/endpoints/events/event.go @@ -10,17 +10,17 @@ import ( "time" "unicode" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/julienschmidt/httprouter" - accountService "github.com/prebid/prebid-server/v2/account" - "github.com/prebid/prebid-server/v2/analytics" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/metrics" - "github.com/prebid/prebid-server/v2/privacy" - "github.com/prebid/prebid-server/v2/stored_requests" - "github.com/prebid/prebid-server/v2/util/httputil" + accountService "github.com/prebid/prebid-server/v3/account" + "github.com/prebid/prebid-server/v3/analytics" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/metrics" + "github.com/prebid/prebid-server/v3/privacy" + "github.com/prebid/prebid-server/v3/stored_requests" + "github.com/prebid/prebid-server/v3/util/httputil" ) const ( @@ -216,7 +216,7 @@ func HandleAccountServiceErrors(errs []error) (status int, messages []string) { errCode := errortypes.ReadCode(er) - if errCode == errortypes.BlacklistedAppErrorCode || errCode == errortypes.AccountDisabledErrorCode { + if errCode == errortypes.BlockedAppErrorCode || errCode == errortypes.AccountDisabledErrorCode { status = http.StatusServiceUnavailable } if errCode == errortypes.MalformedAcctErrorCode { diff --git a/endpoints/events/event_test.go b/endpoints/events/event_test.go index 81d000fd8a4..eb52d8c1287 100644 --- a/endpoints/events/event_test.go +++ b/endpoints/events/event_test.go @@ -12,12 +12,12 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/v2/analytics" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/metrics" - "github.com/prebid/prebid-server/v2/privacy" - "github.com/prebid/prebid-server/v2/stored_requests" + "github.com/prebid/prebid-server/v3/analytics" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/metrics" + "github.com/prebid/prebid-server/v3/privacy" + "github.com/prebid/prebid-server/v3/stored_requests" "github.com/stretchr/testify/assert" ) @@ -64,6 +64,8 @@ func (e *eventsMockAnalyticsModule) LogNotificationEventObject(ne *analytics.Not e.Invoked = true } +func (e *eventsMockAnalyticsModule) Shutdown() {} + var mockAccountData = map[string]json.RawMessage{ "events_enabled": json.RawMessage(`{"events": {"enabled":true}}`), "events_disabled": json.RawMessage(`{"events": {"enabled":false}}`), diff --git a/endpoints/events/vtrack.go b/endpoints/events/vtrack.go index bb479f2a919..590243bb5c2 100644 --- a/endpoints/events/vtrack.go +++ b/endpoints/events/vtrack.go @@ -11,15 +11,15 @@ import ( "github.com/golang/glog" "github.com/julienschmidt/httprouter" - accountService "github.com/prebid/prebid-server/v2/account" - "github.com/prebid/prebid-server/v2/analytics" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/metrics" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/prebid_cache_client" - "github.com/prebid/prebid-server/v2/stored_requests" - "github.com/prebid/prebid-server/v2/util/jsonutil" + accountService "github.com/prebid/prebid-server/v3/account" + "github.com/prebid/prebid-server/v3/analytics" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/metrics" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/prebid_cache_client" + "github.com/prebid/prebid-server/v3/stored_requests" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) const ( diff --git a/endpoints/events/vtrack_test.go b/endpoints/events/vtrack_test.go index 695ba87aa5f..1345d563db5 100644 --- a/endpoints/events/vtrack_test.go +++ b/endpoints/events/vtrack_test.go @@ -12,11 +12,11 @@ import ( "strings" "testing" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/prebid_cache_client" - "github.com/prebid/prebid-server/v2/stored_requests" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/prebid_cache_client" + "github.com/prebid/prebid-server/v3/stored_requests" + "github.com/prebid/prebid-server/v3/util/jsonutil" "github.com/stretchr/testify/assert" ) diff --git a/endpoints/getuids.go b/endpoints/getuids.go index ea87ce70568..dac114da227 100644 --- a/endpoints/getuids.go +++ b/endpoints/getuids.go @@ -4,8 +4,8 @@ import ( "net/http" "github.com/julienschmidt/httprouter" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/usersync" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/usersync" "encoding/json" ) diff --git a/endpoints/getuids_test.go b/endpoints/getuids_test.go index c496d3e270b..1092c51f79f 100644 --- a/endpoints/getuids_test.go +++ b/endpoints/getuids_test.go @@ -5,7 +5,7 @@ import ( "net/http/httptest" "testing" - "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v3/config" "github.com/stretchr/testify/assert" ) diff --git a/endpoints/info/bidders.go b/endpoints/info/bidders.go index 7cbad5e26f6..163f6cee5bd 100644 --- a/endpoints/info/bidders.go +++ b/endpoints/info/bidders.go @@ -7,16 +7,16 @@ import ( "github.com/golang/glog" "github.com/julienschmidt/httprouter" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) var invalidEnabledOnlyMsg = []byte(`Invalid value for 'enabledonly' query param, must be of boolean type`) var invalidBaseAdaptersOnlyMsg = []byte(`Invalid value for 'baseadaptersonly' query param, must be of boolean type`) // NewBiddersEndpoint builds a handler for the /info/bidders endpoint. -func NewBiddersEndpoint(bidders config.BidderInfos, aliases map[string]string) httprouter.Handle { - responseAll, err := prepareBiddersResponseAll(bidders, aliases) +func NewBiddersEndpoint(bidders config.BidderInfos) httprouter.Handle { + responseAll, err := prepareBiddersResponseAll(bidders) if err != nil { glog.Fatalf("error creating /info/bidders endpoint all bidders response: %v", err) } @@ -26,7 +26,7 @@ func NewBiddersEndpoint(bidders config.BidderInfos, aliases map[string]string) h glog.Fatalf("error creating /info/bidders endpoint all bidders (base adapters only) response: %v", err) } - responseEnabledOnly, err := prepareBiddersResponseEnabledOnly(bidders, aliases) + responseEnabledOnly, err := prepareBiddersResponseEnabledOnly(bidders) if err != nil { glog.Fatalf("error creating /info/bidders endpoint enabled only response: %v", err) } @@ -76,7 +76,6 @@ func readQueryFlag(r *http.Request, queryParam string) (flag, ok bool) { q := r.URL.Query() v, exists := q[queryParam] - if !exists || len(v) == 0 { return false, true } @@ -91,26 +90,13 @@ func readQueryFlag(r *http.Request, queryParam string) (flag, ok bool) { } } -func prepareBiddersResponseAll(bidders config.BidderInfos, aliases map[string]string) ([]byte, error) { - bidderNames := make([]string, 0, len(bidders)+len(aliases)) - - for name := range bidders { - bidderNames = append(bidderNames, name) - } - - for name := range aliases { - bidderNames = append(bidderNames, name) - } - - sort.Strings(bidderNames) - return jsonutil.Marshal(bidderNames) -} +type bidderPredicate func(config.BidderInfo) bool -func prepareBiddersResponseAllBaseOnly(bidders config.BidderInfos) ([]byte, error) { +func prepareResponse(bidders config.BidderInfos, p bidderPredicate) ([]byte, error) { bidderNames := make([]string, 0, len(bidders)) for name, info := range bidders { - if len(info.AliasOf) == 0 { + if p(info) { bidderNames = append(bidderNames, name) } } @@ -119,36 +105,24 @@ func prepareBiddersResponseAllBaseOnly(bidders config.BidderInfos) ([]byte, erro return jsonutil.Marshal(bidderNames) } -func prepareBiddersResponseEnabledOnly(bidders config.BidderInfos, aliases map[string]string) ([]byte, error) { - bidderNames := make([]string, 0, len(bidders)+len(aliases)) - - for name, info := range bidders { - if info.IsEnabled() { - bidderNames = append(bidderNames, name) - } - } +func prepareBiddersResponseAll(bidders config.BidderInfos) ([]byte, error) { + filterNone := func(_ config.BidderInfo) bool { return true } + return prepareResponse(bidders, filterNone) +} - for name, bidder := range aliases { - if info, ok := bidders[bidder]; ok && info.IsEnabled() { - bidderNames = append(bidderNames, name) - } - } +func prepareBiddersResponseAllBaseOnly(bidders config.BidderInfos) ([]byte, error) { + filterBaseOnly := func(info config.BidderInfo) bool { return len(info.AliasOf) == 0 } + return prepareResponse(bidders, filterBaseOnly) +} - sort.Strings(bidderNames) - return jsonutil.Marshal(bidderNames) +func prepareBiddersResponseEnabledOnly(bidders config.BidderInfos) ([]byte, error) { + filterEnabledOnly := func(info config.BidderInfo) bool { return info.IsEnabled() } + return prepareResponse(bidders, filterEnabledOnly) } func prepareBiddersResponseEnabledOnlyBaseOnly(bidders config.BidderInfos) ([]byte, error) { - bidderNames := make([]string, 0, len(bidders)) - - for name, info := range bidders { - if info.IsEnabled() && len(info.AliasOf) == 0 { - bidderNames = append(bidderNames, name) - } - } - - sort.Strings(bidderNames) - return jsonutil.Marshal(bidderNames) + filterEnabledOnlyBaseOnly := func(info config.BidderInfo) bool { return info.IsEnabled() && len(info.AliasOf) == 0 } + return prepareResponse(bidders, filterEnabledOnlyBaseOnly) } func writeBadRequest(w http.ResponseWriter, data []byte) { diff --git a/endpoints/info/bidders_detail.go b/endpoints/info/bidders_detail.go index fbc9ab43486..fb9ce252167 100644 --- a/endpoints/info/bidders_detail.go +++ b/endpoints/info/bidders_detail.go @@ -8,9 +8,9 @@ import ( "github.com/golang/glog" "github.com/julienschmidt/httprouter" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) const ( @@ -19,20 +19,21 @@ const ( ) // NewBiddersDetailEndpoint builds a handler for the /info/bidders/ endpoint. -func NewBiddersDetailEndpoint(bidders config.BidderInfos, aliases map[string]string) httprouter.Handle { - responses, err := prepareBiddersDetailResponse(bidders, aliases) +func NewBiddersDetailEndpoint(bidders config.BidderInfos) httprouter.Handle { + responses, err := prepareBiddersDetailResponse(bidders) if err != nil { glog.Fatalf("error creating /info/bidders/ endpoint response: %v", err) } return func(w http.ResponseWriter, _ *http.Request, ps httprouter.Params) { bidder := ps.ByName("bidderName") + bidderName, found := getNormalizedBidderName(bidder) - coreBidderName, found := getNormalisedBidderName(bidder, aliases) if !found { w.WriteHeader(http.StatusNotFound) } - if response, ok := responses[coreBidderName]; ok { + + if response, ok := responses[bidderName]; ok { w.Header().Set("Content-Type", "application/json") if _, err := w.Write(response); err != nil { glog.Errorf("error writing response to /info/bidders/%s: %v", bidder, err) @@ -43,25 +44,21 @@ func NewBiddersDetailEndpoint(bidders config.BidderInfos, aliases map[string]str } } -func getNormalisedBidderName(bidderName string, aliases map[string]string) (string, bool) { +func getNormalizedBidderName(bidderName string) (string, bool) { if strings.ToLower(bidderName) == "all" { return "all", true } - coreBidderName, ok := openrtb_ext.NormalizeBidderName(bidderName) - if !ok { //check default aliases if not found in coreBidders - if _, isDefaultAlias := aliases[bidderName]; isDefaultAlias { - return bidderName, true - } + + bidderNameNormalized, ok := openrtb_ext.NormalizeBidderName(bidderName) + if !ok { return "", false } - return coreBidderName.String(), true + + return bidderNameNormalized.String(), true } -func prepareBiddersDetailResponse(bidders config.BidderInfos, aliases map[string]string) (map[string][]byte, error) { - details, err := mapDetails(bidders, aliases) - if err != nil { - return nil, err - } +func prepareBiddersDetailResponse(bidders config.BidderInfos) (map[string][]byte, error) { + details := mapDetails(bidders) responses, err := marshalDetailsResponse(details) if err != nil { @@ -77,25 +74,14 @@ func prepareBiddersDetailResponse(bidders config.BidderInfos, aliases map[string return responses, nil } -func mapDetails(bidders config.BidderInfos, aliases map[string]string) (map[string]bidderDetail, error) { +func mapDetails(bidders config.BidderInfos) map[string]bidderDetail { details := map[string]bidderDetail{} for bidderName, bidderInfo := range bidders { details[bidderName] = mapDetailFromConfig(bidderInfo) } - for aliasName, bidderName := range aliases { - aliasBaseInfo, aliasBaseInfoFound := details[bidderName] - if !aliasBaseInfoFound { - return nil, fmt.Errorf("base adapter %s for alias %s not found", bidderName, aliasName) - } - - aliasInfo := aliasBaseInfo - aliasInfo.AliasOf = bidderName - details[aliasName] = aliasInfo - } - - return details, nil + return details } func marshalDetailsResponse(details map[string]bidderDetail) (map[string][]byte, error) { @@ -151,6 +137,8 @@ type platform struct { func mapDetailFromConfig(c config.BidderInfo) bidderDetail { var bidderDetail bidderDetail + bidderDetail.AliasOf = c.AliasOf + if c.Maintainer != nil { bidderDetail.Maintainer = &maintainer{ Email: c.Maintainer.Email, diff --git a/endpoints/info/bidders_detail_test.go b/endpoints/info/bidders_detail_test.go index 4965decef40..f86a52692d9 100644 --- a/endpoints/info/bidders_detail_test.go +++ b/endpoints/info/bidders_detail_test.go @@ -9,8 +9,9 @@ import ( "testing" "github.com/julienschmidt/httprouter" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/ptrutil" "github.com/stretchr/testify/assert" ) @@ -34,124 +35,72 @@ func TestPrepareBiddersDetailResponse(t *testing.T) { allResponseBidderAB.WriteString(`}`) var testCases = []struct { - description string + name string givenBidders config.BidderInfos - givenAliases map[string]string expectedResponses map[string][]byte - expectedError string }{ { - description: "None", + name: "none", givenBidders: config.BidderInfos{}, - givenAliases: map[string]string{}, expectedResponses: map[string][]byte{"all": []byte(`{}`)}, }, { - description: "One", + name: "one", givenBidders: config.BidderInfos{"a": bidderAInfo}, - givenAliases: map[string]string{}, expectedResponses: map[string][]byte{"a": bidderAResponse, "all": allResponseBidderA.Bytes()}, }, { - description: "Many", + name: "many", givenBidders: config.BidderInfos{"a": bidderAInfo, "b": bidderBInfo}, - givenAliases: map[string]string{}, expectedResponses: map[string][]byte{"a": bidderAResponse, "b": bidderBResponse, "all": allResponseBidderAB.Bytes()}, }, - { - description: "Error - Map Details", // Returns error due to invalid alias. - givenBidders: config.BidderInfos{"a": bidderAInfo}, - givenAliases: map[string]string{"zAlias": "z"}, - expectedError: "base adapter z for alias zAlias not found", - }, } for _, test := range testCases { - responses, err := prepareBiddersDetailResponse(test.givenBidders, test.givenAliases) - - if test.expectedError == "" { - assert.Equal(t, test.expectedResponses, responses, test.description+":responses") - assert.NoError(t, err, test.expectedError, test.description+":err") - } else { - assert.Empty(t, responses, test.description+":responses") - assert.EqualError(t, err, test.expectedError, test.description+":err") - } + t.Run(test.name, func(t *testing.T) { + responses, err := prepareBiddersDetailResponse(test.givenBidders) + assert.NoError(t, err) + assert.Equal(t, test.expectedResponses, responses) + }) } } func TestMapDetails(t *testing.T) { - trueValue := true - falseValue := false + var ( + bidderAInfo = config.BidderInfo{Endpoint: "https://secureEndpoint.com", Disabled: false, Maintainer: &config.MaintainerInfo{Email: "bidderA"}} + bidderADetail = bidderDetail{Status: "ACTIVE", UsesHTTPS: ptrutil.ToPtr(true), Maintainer: &maintainer{Email: "bidderA"}} - bidderAInfo := config.BidderInfo{Endpoint: "https://secureEndpoint.com", Disabled: false, Maintainer: &config.MaintainerInfo{Email: "bidderA"}} - bidderADetail := bidderDetail{Status: "ACTIVE", UsesHTTPS: &trueValue, Maintainer: &maintainer{Email: "bidderA"}} - aliasADetail := bidderDetail{Status: "ACTIVE", UsesHTTPS: &trueValue, Maintainer: &maintainer{Email: "bidderA"}, AliasOf: "a"} - - bidderBInfo := config.BidderInfo{Endpoint: "http://unsecureEndpoint.com", Disabled: false, Maintainer: &config.MaintainerInfo{Email: "bidderB"}} - bidderBDetail := bidderDetail{Status: "ACTIVE", UsesHTTPS: &falseValue, Maintainer: &maintainer{Email: "bidderB"}} - aliasBDetail := bidderDetail{Status: "ACTIVE", UsesHTTPS: &falseValue, Maintainer: &maintainer{Email: "bidderB"}, AliasOf: "b"} + bidderBInfo = config.BidderInfo{Endpoint: "http://unsecureEndpoint.com", Disabled: false, Maintainer: &config.MaintainerInfo{Email: "bidderB"}} + bidderBDetail = bidderDetail{Status: "ACTIVE", UsesHTTPS: ptrutil.ToPtr(false), Maintainer: &maintainer{Email: "bidderB"}} + ) var testCases = []struct { - description string + name string givenBidders config.BidderInfos - givenAliases map[string]string expectedDetails map[string]bidderDetail - expectedError string }{ { - description: "None", + name: "none", givenBidders: config.BidderInfos{}, - givenAliases: map[string]string{}, expectedDetails: map[string]bidderDetail{}, }, { - description: "One Core Bidder", + name: "one", givenBidders: config.BidderInfos{"a": bidderAInfo}, - givenAliases: map[string]string{}, expectedDetails: map[string]bidderDetail{"a": bidderADetail}, }, { - description: "Many Core Bidders", + name: "many", givenBidders: config.BidderInfos{"a": bidderAInfo, "b": bidderBInfo}, - givenAliases: map[string]string{}, expectedDetails: map[string]bidderDetail{"a": bidderADetail, "b": bidderBDetail}, }, - { - description: "One Alias", - givenBidders: config.BidderInfos{"a": bidderAInfo}, - givenAliases: map[string]string{"aAlias": "a"}, - expectedDetails: map[string]bidderDetail{"a": bidderADetail, "aAlias": aliasADetail}, - }, - { - description: "Many Aliases - Same Core Bidder", - givenBidders: config.BidderInfos{"a": bidderAInfo}, - givenAliases: map[string]string{"aAlias1": "a", "aAlias2": "a"}, - expectedDetails: map[string]bidderDetail{"a": bidderADetail, "aAlias1": aliasADetail, "aAlias2": aliasADetail}, - }, - { - description: "Many Aliases - Different Core Bidders", - givenBidders: config.BidderInfos{"a": bidderAInfo, "b": bidderBInfo}, - givenAliases: map[string]string{"aAlias": "a", "bAlias": "b"}, - expectedDetails: map[string]bidderDetail{"a": bidderADetail, "b": bidderBDetail, "aAlias": aliasADetail, "bAlias": aliasBDetail}, - }, - { - description: "Error - Alias Without Core Bidder", - givenBidders: config.BidderInfos{"a": bidderAInfo}, - givenAliases: map[string]string{"zAlias": "z"}, - expectedError: "base adapter z for alias zAlias not found", - }, } for _, test := range testCases { - details, err := mapDetails(test.givenBidders, test.givenAliases) - - if test.expectedError == "" { - assert.Equal(t, test.expectedDetails, details, test.description+":details") - assert.NoError(t, err, test.expectedError, test.description+":err") - } else { - assert.Empty(t, details, test.description+":details") - assert.EqualError(t, err, test.expectedError, test.description+":err") - } + t.Run(test.name, func(t *testing.T) { + details := mapDetails(test.givenBidders) + assert.Equal(t, test.expectedDetails, details) + }) } } @@ -165,32 +114,33 @@ func TestMarshalDetailsResponse(t *testing.T) { bidderDetailBResponse := []byte(`{"status":"ACTIVE","maintainer":{"email":"bidderB"},"capabilities":{"app":{"mediaTypes":["banner"]}}}`) var testCases = []struct { - description string + name string givenDetails map[string]bidderDetail expectedResponse map[string][]byte }{ { - description: "None", + name: "none", givenDetails: map[string]bidderDetail{}, expectedResponse: map[string][]byte{}, }, { - description: "One", + name: "one", givenDetails: map[string]bidderDetail{"a": bidderDetailA}, expectedResponse: map[string][]byte{"a": bidderDetailAResponse}, }, { - description: "Many", + name: "many", givenDetails: map[string]bidderDetail{"a": bidderDetailA, "b": bidderDetailB}, expectedResponse: map[string][]byte{"a": bidderDetailAResponse, "b": bidderDetailBResponse}, }, } for _, test := range testCases { - response, err := marshalDetailsResponse(test.givenDetails) - - assert.NoError(t, err, test.description+":err") - assert.Equal(t, test.expectedResponse, response, test.description+":response") + t.Run(test.name, func(t *testing.T) { + response, err := marshalDetailsResponse(test.givenDetails) + assert.NoError(t, err) + assert.Equal(t, test.expectedResponse, response) + }) } } @@ -211,12 +161,12 @@ func TestMapDetailFromConfig(t *testing.T) { falseValue := false var testCases = []struct { - description string + name string givenBidderInfo config.BidderInfo expected bidderDetail }{ { - description: "Enabled - All Values Present", + name: "enabled-all-values", givenBidderInfo: config.BidderInfo{ Endpoint: "http://anyEndpoint", Disabled: false, @@ -244,7 +194,7 @@ func TestMapDetailFromConfig(t *testing.T) { }, }, { - description: "Disabled - All Values Present", + name: "disabled-all-values", givenBidderInfo: config.BidderInfo{ Endpoint: "http://anyEndpoint", Disabled: true, @@ -267,7 +217,7 @@ func TestMapDetailFromConfig(t *testing.T) { }, }, { - description: "Enabled - No Values Present", + name: "enabled-no-values", givenBidderInfo: config.BidderInfo{ Endpoint: "http://amyEndpoint", Disabled: false, @@ -278,7 +228,7 @@ func TestMapDetailFromConfig(t *testing.T) { }, }, { - description: "Enabled - Protocol - HTTP", + name: "enabled-protocol-http", givenBidderInfo: config.BidderInfo{ Endpoint: "http://amyEndpoint", Disabled: false, @@ -289,7 +239,7 @@ func TestMapDetailFromConfig(t *testing.T) { }, }, { - description: "Enabled - Protocol - HTTPS", + name: "enabled-protocol-https", givenBidderInfo: config.BidderInfo{ Endpoint: "https://amyEndpoint", Disabled: false, @@ -300,7 +250,7 @@ func TestMapDetailFromConfig(t *testing.T) { }, }, { - description: "Enabled - Protocol - HTTPS - Case Insensitive", + name: "enabled-protocol-https-case-insensitive", givenBidderInfo: config.BidderInfo{ Disabled: false, Endpoint: "https://amyEndpoint", @@ -311,7 +261,7 @@ func TestMapDetailFromConfig(t *testing.T) { }, }, { - description: "Enabled - Protocol - Unknown", + name: "enabled-protocol-unknown", givenBidderInfo: config.BidderInfo{ Endpoint: "endpointWithoutProtocol", Disabled: false, @@ -324,125 +274,132 @@ func TestMapDetailFromConfig(t *testing.T) { } for _, test := range testCases { - result := mapDetailFromConfig(test.givenBidderInfo) - assert.Equal(t, test.expected, result, test.description) + t.Run(test.name, func(t *testing.T) { + result := mapDetailFromConfig(test.givenBidderInfo) + assert.Equal(t, test.expected, result) + }) } } func TestMapMediaTypes(t *testing.T) { var testCases = []struct { - description string - mediaTypes []openrtb_ext.BidType - expected []string + name string + mediaTypes []openrtb_ext.BidType + expected []string }{ { - description: "Nil", - mediaTypes: nil, - expected: nil, + name: "nil", + mediaTypes: nil, + expected: nil, }, { - description: "None", - mediaTypes: []openrtb_ext.BidType{}, - expected: []string{}, + name: "none", + mediaTypes: []openrtb_ext.BidType{}, + expected: []string{}, }, { - description: "One", - mediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner}, - expected: []string{"banner"}, + name: "one", + mediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner}, + expected: []string{"banner"}, }, { - description: "Many", - mediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner, openrtb_ext.BidTypeVideo}, - expected: []string{"banner", "video"}, + name: "many", + mediaTypes: []openrtb_ext.BidType{openrtb_ext.BidTypeBanner, openrtb_ext.BidTypeVideo}, + expected: []string{"banner", "video"}, }, } for _, test := range testCases { - result := mapMediaTypes(test.mediaTypes) - assert.ElementsMatch(t, test.expected, result, test.description) + t.Run(test.name, func(t *testing.T) { + result := mapMediaTypes(test.mediaTypes) + assert.ElementsMatch(t, test.expected, result) + }) } } func TestBiddersDetailHandler(t *testing.T) { bidderAInfo := config.BidderInfo{Endpoint: "https://secureEndpoint.com", Disabled: false, Maintainer: &config.MaintainerInfo{Email: "bidderA"}} bidderAResponse := []byte(`{"status":"ACTIVE","usesHttps":true,"maintainer":{"email":"bidderA"}}`) - aliasAResponse := []byte(`{"status":"ACTIVE","usesHttps":true,"maintainer":{"email":"bidderA"},"aliasOf":"appnexus"}`) bidderBInfo := config.BidderInfo{Endpoint: "http://unsecureEndpoint.com", Disabled: false, Maintainer: &config.MaintainerInfo{Email: "bidderB"}} bidderBResponse := []byte(`{"status":"ACTIVE","usesHttps":false,"maintainer":{"email":"bidderB"}}`) + aliasInfo := config.BidderInfo{AliasOf: "appnexus", Endpoint: "https://secureEndpoint.com", Disabled: false, Maintainer: &config.MaintainerInfo{Email: "alias"}} + aliasResponse := []byte(`{"status":"ACTIVE","usesHttps":true,"maintainer":{"email":"alias"},"aliasOf":"appnexus"}`) + allResponse := bytes.Buffer{} allResponse.WriteString(`{"aAlias":`) - allResponse.Write(aliasAResponse) + allResponse.Write(aliasResponse) allResponse.WriteString(`,"appnexus":`) allResponse.Write(bidderAResponse) allResponse.WriteString(`,"rubicon":`) allResponse.Write(bidderBResponse) allResponse.WriteString(`}`) - bidders := config.BidderInfos{"appnexus": bidderAInfo, "rubicon": bidderBInfo} - aliases := map[string]string{"aAlias": "appnexus"} + bidders := config.BidderInfos{"aAlias": aliasInfo, "appnexus": bidderAInfo, "rubicon": bidderBInfo} + + handler := NewBiddersDetailEndpoint(bidders) - handler := NewBiddersDetailEndpoint(bidders, aliases) + openrtb_ext.SetAliasBidderName("aAlias", "appnexus") var testCases = []struct { - description string + name string givenBidder string expectedStatus int expectedHeaders http.Header expectedResponse []byte }{ { - description: "Bidder A", + name: "bidder-a", givenBidder: "appnexus", expectedStatus: http.StatusOK, expectedHeaders: http.Header{"Content-Type": []string{"application/json"}}, expectedResponse: bidderAResponse, }, { - description: "Bidder B", + name: "bidder-b", givenBidder: "rubicon", expectedStatus: http.StatusOK, expectedHeaders: http.Header{"Content-Type": []string{"application/json"}}, expectedResponse: bidderBResponse, }, { - description: "Bidder B - case insensitive", + name: "bidder-b-case-insensitive", givenBidder: "RUBICON", expectedStatus: http.StatusOK, expectedHeaders: http.Header{"Content-Type": []string{"application/json"}}, expectedResponse: bidderBResponse, }, { - description: "Bidder A Alias", + name: "bidder-a-alias", givenBidder: "aAlias", expectedStatus: http.StatusOK, expectedHeaders: http.Header{"Content-Type": []string{"application/json"}}, - expectedResponse: aliasAResponse, + expectedResponse: aliasResponse, }, { - description: "Bidder A Alias - case insensitive", + name: "bidder-a-alias-case-insensitive", givenBidder: "aAlias", expectedStatus: http.StatusOK, expectedHeaders: http.Header{"Content-Type": []string{"application/json"}}, - expectedResponse: aliasAResponse, + expectedResponse: aliasResponse, }, { - description: "All Bidders", + name: "all-bidders", givenBidder: "all", expectedStatus: http.StatusOK, expectedHeaders: http.Header{"Content-Type": []string{"application/json"}}, expectedResponse: allResponse.Bytes(), }, { - description: "All Bidders - Case insensitive", + name: "all-bidders-case-insensitive", givenBidder: "All", expectedStatus: http.StatusOK, expectedHeaders: http.Header{"Content-Type": []string{"application/json"}}, expectedResponse: allResponse.Bytes(), }, { - description: "Invalid Bidder", + name: "invalid", givenBidder: "doesntExist", expectedStatus: http.StatusNotFound, expectedHeaders: http.Header{}, @@ -451,7 +408,7 @@ func TestBiddersDetailHandler(t *testing.T) { } for _, test := range testCases { - t.Run(test.description, func(t *testing.T) { + t.Run(test.name, func(t *testing.T) { responseRecorder := httptest.NewRecorder() handler(responseRecorder, nil, httprouter.Params{{ Key: "bidderName", @@ -459,14 +416,14 @@ func TestBiddersDetailHandler(t *testing.T) { }}) result := responseRecorder.Result() - assert.Equal(t, result.StatusCode, test.expectedStatus, test.description+":statuscode") + assert.Equal(t, test.expectedStatus, result.StatusCode, "statuscode") resultBody, _ := io.ReadAll(result.Body) fmt.Println(string(test.expectedResponse)) - assert.Equal(t, test.expectedResponse, resultBody, test.description+":body") + assert.Equal(t, test.expectedResponse, resultBody, "body") resultHeaders := result.Header - assert.Equal(t, test.expectedHeaders, resultHeaders, test.description+":headers") + assert.Equal(t, test.expectedHeaders, resultHeaders, "headers") }) } } diff --git a/endpoints/info/bidders_test.go b/endpoints/info/bidders_test.go index 189eb865551..b75b32aae10 100644 --- a/endpoints/info/bidders_test.go +++ b/endpoints/info/bidders_test.go @@ -6,7 +6,7 @@ import ( "net/http/httptest" "testing" - "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v3/config" "github.com/stretchr/testify/assert" ) @@ -19,88 +19,65 @@ func TestPrepareBiddersResponseAll(t *testing.T) { ) testCases := []struct { - name string - givenBidders config.BidderInfos - givenRequestAliases map[string]string - expected string + name string + givenBidders config.BidderInfos + expected string }{ { - name: "none", - givenBidders: config.BidderInfos{}, - givenRequestAliases: nil, - expected: `[]`, - }, - { - name: "core-one-enabled", - givenBidders: config.BidderInfos{"a": enabledCore}, - givenRequestAliases: nil, - expected: `["a"]`, - }, - { - name: "core-one-disabled", - givenBidders: config.BidderInfos{"a": disabledCore}, - givenRequestAliases: nil, - expected: `["a"]`, + name: "none", + givenBidders: config.BidderInfos{}, + expected: `[]`, }, { - name: "core-one-mixed", - givenBidders: config.BidderInfos{"a": disabledCore, "b": enabledCore}, - givenRequestAliases: nil, - expected: `["a","b"]`, + name: "core-one-enabled", + givenBidders: config.BidderInfos{"a": enabledCore}, + expected: `["a"]`, }, { - name: "core-one-mixed-sorted", - givenBidders: config.BidderInfos{"z": enabledCore, "a": enabledCore}, - givenRequestAliases: nil, - expected: `["a","z"]`, + name: "core-one-disabled", + givenBidders: config.BidderInfos{"a": disabledCore}, + expected: `["a"]`, }, { - name: "alias-one", - givenBidders: config.BidderInfos{"a": enabledAlias}, - givenRequestAliases: nil, - expected: `["a"]`, + name: "core-many-mixed", + givenBidders: config.BidderInfos{"a": disabledCore, "b": enabledCore}, + expected: `["a","b"]`, }, { - name: "alias-mixed", - givenBidders: config.BidderInfos{"a": disabledCore, "b": disabledAlias, "c": enabledCore, "d": enabledAlias}, - givenRequestAliases: nil, - expected: `["a","b","c","d"]`, + name: "core-many-sorted", + givenBidders: config.BidderInfos{"z": enabledCore, "a": enabledCore}, + expected: `["a","z"]`, }, { - name: "alias-mixed-sorted", - givenBidders: config.BidderInfos{"z": enabledAlias, "a": enabledCore}, - givenRequestAliases: nil, - expected: `["a","z"]`, + name: "alias-one-enabled", + givenBidders: config.BidderInfos{"a": enabledAlias}, + expected: `["a"]`, }, { - name: "defaultrequest-one", - givenBidders: config.BidderInfos{"a": enabledCore}, - givenRequestAliases: map[string]string{"b": "a"}, - expected: `["a","b"]`, + name: "alias-one-disabled", + givenBidders: config.BidderInfos{"a": disabledAlias}, + expected: `["a"]`, }, { - name: "defaultrequest-mixed", - givenBidders: config.BidderInfos{"a": enabledCore, "b": disabledCore}, - givenRequestAliases: map[string]string{"x": "a", "y": "b"}, - expected: `["a","b","x","y"]`, + name: "alias-many-mixed", + givenBidders: config.BidderInfos{"a": enabledAlias, "b": disabledAlias}, + expected: `["a","b"]`, }, { - name: "defaultrequest-mixed-sorted", - givenBidders: config.BidderInfos{"z": enabledCore}, - givenRequestAliases: map[string]string{"a": "z"}, - expected: `["a","z"]`, + name: "alias-many-sorted", + givenBidders: config.BidderInfos{"z": enabledAlias, "a": enabledCore}, + expected: `["a","z"]`, }, { - name: "mixed", - givenBidders: config.BidderInfos{"a": disabledCore, "b": disabledAlias, "c": enabledCore, "d": enabledAlias}, - givenRequestAliases: map[string]string{"z": "a"}, - expected: `["a","b","c","d","z"]`, + name: "mixed", + givenBidders: config.BidderInfos{"a": disabledCore, "b": disabledAlias, "c": enabledCore, "d": enabledAlias}, + expected: `["a","b","c","d"]`, }, } for _, test := range testCases { t.Run(test.name, func(t *testing.T) { - result, err := prepareBiddersResponseAll(test.givenBidders, test.givenRequestAliases) + result, err := prepareBiddersResponseAll(test.givenBidders) assert.NoError(t, err) assert.Equal(t, []byte(test.expected), result) }) @@ -136,22 +113,32 @@ func TestPrepareBiddersResponseAllBaseOnly(t *testing.T) { expected: `["a"]`, }, { - name: "core-one-mixed", + name: "core-many-mixed", givenBidders: config.BidderInfos{"a": disabledCore, "b": enabledCore}, expected: `["a","b"]`, }, { - name: "core-one-mixed-sorted", + name: "core-many-sorted", givenBidders: config.BidderInfos{"z": enabledCore, "a": enabledCore}, expected: `["a","z"]`, }, { - name: "alias-one", + name: "alias-one-enabled", givenBidders: config.BidderInfos{"a": enabledAlias}, expected: `[]`, }, { - name: "alias-mixed", + name: "alias-one-disabled", + givenBidders: config.BidderInfos{"a": disabledAlias}, + expected: `[]`, + }, + { + name: "alias-many", + givenBidders: config.BidderInfos{"a": enabledAlias, "b": enabledAlias}, + expected: `[]`, + }, + { + name: "mixed", givenBidders: config.BidderInfos{"a": disabledCore, "b": disabledAlias, "c": enabledCore, "d": enabledAlias}, expected: `["a","c"]`, }, @@ -175,88 +162,65 @@ func TestPrepareBiddersResponseEnabledOnly(t *testing.T) { ) testCases := []struct { - name string - givenBidders config.BidderInfos - givenRequestAliases map[string]string - expected string + name string + givenBidders config.BidderInfos + expected string }{ { - name: "none", - givenBidders: config.BidderInfos{}, - givenRequestAliases: nil, - expected: `[]`, - }, - { - name: "core-one-enabled", - givenBidders: config.BidderInfos{"a": enabledCore}, - givenRequestAliases: nil, - expected: `["a"]`, - }, - { - name: "core-one-disabled", - givenBidders: config.BidderInfos{"a": disabledCore}, - givenRequestAliases: nil, - expected: `[]`, + name: "none", + givenBidders: config.BidderInfos{}, + expected: `[]`, }, { - name: "core-one-mixed", - givenBidders: config.BidderInfos{"a": disabledCore, "b": enabledCore}, - givenRequestAliases: nil, - expected: `["b"]`, + name: "core-one-enabled", + givenBidders: config.BidderInfos{"a": enabledCore}, + expected: `["a"]`, }, { - name: "core-one-mixed-sorted", - givenBidders: config.BidderInfos{"z": enabledCore, "a": enabledCore}, - givenRequestAliases: nil, - expected: `["a","z"]`, + name: "core-one-disabled", + givenBidders: config.BidderInfos{"a": disabledCore}, + expected: `[]`, }, { - name: "alias-one", - givenBidders: config.BidderInfos{"a": enabledAlias}, - givenRequestAliases: nil, - expected: `["a"]`, + name: "core-many-mixed", + givenBidders: config.BidderInfos{"a": disabledCore, "b": enabledCore}, + expected: `["b"]`, }, { - name: "alias-mixed", - givenBidders: config.BidderInfos{"a": disabledCore, "b": disabledAlias, "c": enabledCore, "d": enabledAlias}, - givenRequestAliases: nil, - expected: `["c","d"]`, + name: "core-many-sorted", + givenBidders: config.BidderInfos{"z": enabledCore, "a": enabledCore}, + expected: `["a","z"]`, }, { - name: "alias-mixed-sorted", - givenBidders: config.BidderInfos{"z": enabledAlias, "a": enabledCore}, - givenRequestAliases: nil, - expected: `["a","z"]`, + name: "alias-one-enabled", + givenBidders: config.BidderInfos{"a": enabledAlias}, + expected: `["a"]`, }, { - name: "defaultrequest-one", - givenBidders: config.BidderInfos{"a": enabledCore}, - givenRequestAliases: map[string]string{"b": "a"}, - expected: `["a","b"]`, + name: "alias-one-disabled", + givenBidders: config.BidderInfos{"a": disabledAlias}, + expected: `[]`, }, { - name: "defaultrequest-mixed", - givenBidders: config.BidderInfos{"a": enabledCore, "b": disabledCore}, - givenRequestAliases: map[string]string{"x": "a", "y": "b"}, - expected: `["a","x"]`, + name: "alias-many-mixed", + givenBidders: config.BidderInfos{"a": enabledAlias, "b": disabledAlias}, + expected: `["a"]`, }, { - name: "defaultrequest-mixed-sorted", - givenBidders: config.BidderInfos{"z": enabledCore}, - givenRequestAliases: map[string]string{"a": "z"}, - expected: `["a","z"]`, + name: "alias-many-sorted", + givenBidders: config.BidderInfos{"z": enabledAlias, "a": enabledCore}, + expected: `["a","z"]`, }, { - name: "mixed", - givenBidders: config.BidderInfos{"a": disabledCore, "b": disabledAlias, "c": enabledCore, "d": enabledAlias}, - givenRequestAliases: map[string]string{"z": "a"}, - expected: `["c","d"]`, + name: "mixed", + givenBidders: config.BidderInfos{"a": disabledCore, "b": disabledAlias, "c": enabledCore, "d": enabledAlias}, + expected: `["c","d"]`, }, } for _, test := range testCases { t.Run(test.name, func(t *testing.T) { - result, err := prepareBiddersResponseEnabledOnly(test.givenBidders, test.givenRequestAliases) + result, err := prepareBiddersResponseEnabledOnly(test.givenBidders) assert.NoError(t, err) assert.Equal(t, []byte(test.expected), result) }) @@ -292,17 +256,27 @@ func TestPrepareBiddersResponseEnabledOnlyBaseOnly(t *testing.T) { expected: `[]`, }, { - name: "core-one-mixed", + name: "core-many", + givenBidders: config.BidderInfos{"a": enabledCore, "b": enabledCore}, + expected: `["a","b"]`, + }, + { + name: "core-many-mixed", givenBidders: config.BidderInfos{"a": disabledCore, "b": enabledCore}, expected: `["b"]`, }, { - name: "core-one-mixed-sorted", + name: "core-many-sorted", givenBidders: config.BidderInfos{"z": enabledCore, "a": enabledCore}, expected: `["a","z"]`, }, { - name: "alias-one", + name: "alias-one-enabled", + givenBidders: config.BidderInfos{"a": enabledAlias}, + expected: `[]`, + }, + { + name: "alias-one-disabled", givenBidders: config.BidderInfos{"a": enabledAlias}, expected: `[]`, }, @@ -336,7 +310,6 @@ func TestBiddersHandler(t *testing.T) { ) bidders := config.BidderInfos{"a": enabledCore, "b": enabledAlias, "c": disabledCore, "d": disabledAlias} - aliases := map[string]string{"x": "a", "y": "c"} testCases := []struct { name string @@ -349,35 +322,35 @@ func TestBiddersHandler(t *testing.T) { name: "simple", givenURL: "/info/bidders", expectedStatus: http.StatusOK, - expectedBody: `["a","b","c","d","x","y"]`, + expectedBody: `["a","b","c","d"]`, expectedHeaders: http.Header{"Content-Type": []string{"application/json"}}, }, { name: "enabledonly-false", givenURL: "/info/bidders?enabledonly=false", expectedStatus: http.StatusOK, - expectedBody: `["a","b","c","d","x","y"]`, + expectedBody: `["a","b","c","d"]`, expectedHeaders: http.Header{"Content-Type": []string{"application/json"}}, }, { name: "enabledonly-false-caseinsensitive", givenURL: "/info/bidders?enabledonly=fAlSe", expectedStatus: http.StatusOK, - expectedBody: `["a","b","c","d","x","y"]`, + expectedBody: `["a","b","c","d"]`, expectedHeaders: http.Header{"Content-Type": []string{"application/json"}}, }, { name: "enabledonly-true", givenURL: "/info/bidders?enabledonly=true", expectedStatus: http.StatusOK, - expectedBody: `["a","b","x"]`, + expectedBody: `["a","b"]`, expectedHeaders: http.Header{"Content-Type": []string{"application/json"}}, }, { name: "enabledonly-true-caseinsensitive", givenURL: "/info/bidders?enabledonly=TrUe", expectedStatus: http.StatusOK, - expectedBody: `["a","b","x"]`, + expectedBody: `["a","b"]`, expectedHeaders: http.Header{"Content-Type": []string{"application/json"}}, }, { @@ -398,14 +371,14 @@ func TestBiddersHandler(t *testing.T) { name: "baseonly-false", givenURL: "/info/bidders?baseadaptersonly=false", expectedStatus: http.StatusOK, - expectedBody: `["a","b","c","d","x","y"]`, + expectedBody: `["a","b","c","d"]`, expectedHeaders: http.Header{"Content-Type": []string{"application/json"}}, }, { name: "baseonly-false-caseinsensitive", givenURL: "/info/bidders?baseadaptersonly=fAlSe", expectedStatus: http.StatusOK, - expectedBody: `["a","b","c","d","x","y"]`, + expectedBody: `["a","b","c","d"]`, expectedHeaders: http.Header{"Content-Type": []string{"application/json"}}, }, { @@ -440,7 +413,7 @@ func TestBiddersHandler(t *testing.T) { name: "enabledonly-true-baseonly-false", givenURL: "/info/bidders?enabledonly=true&baseadaptersonly=false", expectedStatus: http.StatusOK, - expectedBody: `["a","b","x"]`, + expectedBody: `["a","b"]`, expectedHeaders: http.Header{"Content-Type": []string{"application/json"}}, }, { @@ -461,7 +434,7 @@ func TestBiddersHandler(t *testing.T) { for _, test := range testCases { t.Run(test.name, func(t *testing.T) { - handler := NewBiddersEndpoint(bidders, aliases) + handler := NewBiddersEndpoint(bidders) request := httptest.NewRequest("GET", test.givenURL, nil) diff --git a/endpoints/openrtb2/amp_auction.go b/endpoints/openrtb2/amp_auction.go index 4a409a679c7..b596ec793c6 100644 --- a/endpoints/openrtb2/amp_auction.go +++ b/endpoints/openrtb2/amp_auction.go @@ -16,29 +16,29 @@ import ( "github.com/julienschmidt/httprouter" "github.com/prebid/openrtb/v20/openrtb2" "github.com/prebid/openrtb/v20/openrtb3" - "github.com/prebid/prebid-server/v2/hooks/hookexecution" - "github.com/prebid/prebid-server/v2/ortb" - "github.com/prebid/prebid-server/v2/util/uuidutil" + "github.com/prebid/prebid-server/v3/hooks/hookexecution" + "github.com/prebid/prebid-server/v3/ortb" + "github.com/prebid/prebid-server/v3/util/uuidutil" jsonpatch "gopkg.in/evanphx/json-patch.v4" - accountService "github.com/prebid/prebid-server/v2/account" - "github.com/prebid/prebid-server/v2/amp" - "github.com/prebid/prebid-server/v2/analytics" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/exchange" - "github.com/prebid/prebid-server/v2/gdpr" - "github.com/prebid/prebid-server/v2/hooks" - "github.com/prebid/prebid-server/v2/metrics" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/privacy" - "github.com/prebid/prebid-server/v2/stored_requests" - "github.com/prebid/prebid-server/v2/stored_requests/backends/empty_fetcher" - "github.com/prebid/prebid-server/v2/stored_responses" - "github.com/prebid/prebid-server/v2/usersync" - "github.com/prebid/prebid-server/v2/util/iputil" - "github.com/prebid/prebid-server/v2/util/jsonutil" - "github.com/prebid/prebid-server/v2/version" + accountService "github.com/prebid/prebid-server/v3/account" + "github.com/prebid/prebid-server/v3/amp" + "github.com/prebid/prebid-server/v3/analytics" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/exchange" + "github.com/prebid/prebid-server/v3/gdpr" + "github.com/prebid/prebid-server/v3/hooks" + "github.com/prebid/prebid-server/v3/metrics" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/privacy" + "github.com/prebid/prebid-server/v3/stored_requests" + "github.com/prebid/prebid-server/v3/stored_requests/backends/empty_fetcher" + "github.com/prebid/prebid-server/v3/stored_responses" + "github.com/prebid/prebid-server/v3/usersync" + "github.com/prebid/prebid-server/v3/util/iputil" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/version" ) const defaultAmpRequestTimeoutMillis = 900 @@ -211,9 +211,9 @@ func (deps *endpointDeps) AmpAuction(w http.ResponseWriter, r *http.Request, _ h metricsStatus := metrics.RequestStatusBadInput for _, er := range errL { errCode := errortypes.ReadCode(er) - if errCode == errortypes.BlacklistedAppErrorCode || errCode == errortypes.AccountDisabledErrorCode { + if errCode == errortypes.BlockedAppErrorCode || errCode == errortypes.AccountDisabledErrorCode { httpStatus = http.StatusServiceUnavailable - metricsStatus = metrics.RequestStatusBlacklisted + metricsStatus = metrics.RequestStatusBlockedApp break } if errCode == errortypes.MalformedAcctErrorCode { @@ -510,6 +510,14 @@ func (deps *endpointDeps) parseAmpRequest(httpRequest *http.Request) (req *openr // move to using the request wrapper req = &openrtb_ext.RequestWrapper{BidRequest: reqNormal} + // normalize to openrtb 2.6 + if err := openrtb_ext.ConvertUpTo26(req); err != nil { + errs = append(errs, err) + } + if errortypes.ContainsFatalError(errs) { + return + } + // Need to ensure cache and targeting are turned on e = initAmpTargetingAndCache(req) if errs = append(errs, e...); errortypes.ContainsFatalError(errs) { diff --git a/endpoints/openrtb2/amp_auction_test.go b/endpoints/openrtb2/amp_auction_test.go index e9b0015afe7..3fe8a629f02 100644 --- a/endpoints/openrtb2/amp_auction_test.go +++ b/endpoints/openrtb2/amp_auction_test.go @@ -19,22 +19,22 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/prebid/prebid-server/v2/amp" - "github.com/prebid/prebid-server/v2/analytics" - analyticsBuild "github.com/prebid/prebid-server/v2/analytics/build" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/exchange" - "github.com/prebid/prebid-server/v2/hooks" - "github.com/prebid/prebid-server/v2/hooks/hookexecution" - "github.com/prebid/prebid-server/v2/hooks/hookstage" - "github.com/prebid/prebid-server/v2/metrics" - metricsConfig "github.com/prebid/prebid-server/v2/metrics/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/ortb" - "github.com/prebid/prebid-server/v2/privacy" - "github.com/prebid/prebid-server/v2/stored_requests/backends/empty_fetcher" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/amp" + "github.com/prebid/prebid-server/v3/analytics" + analyticsBuild "github.com/prebid/prebid-server/v3/analytics/build" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/exchange" + "github.com/prebid/prebid-server/v3/hooks" + "github.com/prebid/prebid-server/v3/hooks/hookexecution" + "github.com/prebid/prebid-server/v3/hooks/hookstage" + "github.com/prebid/prebid-server/v3/metrics" + metricsConfig "github.com/prebid/prebid-server/v3/metrics/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/ortb" + "github.com/prebid/prebid-server/v3/privacy" + "github.com/prebid/prebid-server/v3/stored_requests/backends/empty_fetcher" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) // TestGoodRequests makes sure that the auction runs properly-formatted stored bids correctly. @@ -56,6 +56,7 @@ func TestGoodAmpRequests(t *testing.T) { "buyeruids-case-insensitive.json", "buyeruids-camel-case.json", "aliased-buyeruids-case-insensitive.json", + "ortb-2.5-to-2.6-upconvert.json", }, }, { @@ -103,8 +104,8 @@ func TestGoodAmpRequests(t *testing.T) { GDPR: config.GDPR{Enabled: true}, } if test.Config != nil { - cfg.BlacklistedApps = test.Config.BlacklistedApps - cfg.BlacklistedAppMap = test.Config.getBlacklistedAppMap() + cfg.BlockedApps = test.Config.BlockedApps + cfg.BlockedAppsLookup = test.Config.getBlockedAppLookup() cfg.AccountRequired = test.Config.AccountRequired } @@ -138,6 +139,17 @@ func TestGoodAmpRequests(t *testing.T) { assert.JSONEq(t, string(test.ExpectedValidatedBidReq), string(actualJson), "Not the expected validated request. Test file: %s", filename) } } + if test.ExpectedMockBidderRequests != nil { + for bidder, req := range test.ExpectedMockBidderRequests { + a, ok := ex.adapters[openrtb_ext.BidderName(bidder)] + if !ok { + t.Fatalf("Unexpected bidder %s has an expected mock bidder request. Test file: %s", bidder, filename) + } + aa := a.(*exchange.BidderAdapter) + ma := aa.Bidder.(*mockAdapter) + assert.JSONEq(t, string(req), string(ma.requestData[0]), "Not the expected mock bidder request for bidder %s. Test file: %s", bidder, filename) + } + } } } } @@ -235,55 +247,47 @@ func TestGDPRConsent(t *testing.T) { existingConsent := "BONV8oqONXwgmADACHENAO7pqzAAppY" testCases := []struct { - description string - consent string - userExt *openrtb_ext.ExtUser - nilUser bool - expectedUserExt openrtb_ext.ExtUser + description string + consent string + user *openrtb2.User + nilUser bool + expectedUser *openrtb2.User }{ { description: "Nil User", consent: consent, nilUser: true, - expectedUserExt: openrtb_ext.ExtUser{ - Consent: consent, - }, - }, - { - description: "Nil User Ext", - consent: consent, - userExt: nil, - expectedUserExt: openrtb_ext.ExtUser{ + expectedUser: &openrtb2.User{ Consent: consent, }, }, { description: "Overrides Existing Consent", consent: consent, - userExt: &openrtb_ext.ExtUser{ + user: &openrtb2.User{ Consent: existingConsent, }, - expectedUserExt: openrtb_ext.ExtUser{ + expectedUser: &openrtb2.User{ Consent: consent, }, }, { description: "Overrides Existing Consent - With Sibling Data", consent: consent, - userExt: &openrtb_ext.ExtUser{ + user: &openrtb2.User{ Consent: existingConsent, }, - expectedUserExt: openrtb_ext.ExtUser{ + expectedUser: &openrtb2.User{ Consent: consent, }, }, { description: "Does Not Override Existing Consent If Empty", consent: "", - userExt: &openrtb_ext.ExtUser{ + user: &openrtb2.User{ Consent: existingConsent, }, - expectedUserExt: openrtb_ext.ExtUser{ + expectedUser: &openrtb2.User{ Consent: existingConsent, }, }, @@ -291,7 +295,7 @@ func TestGDPRConsent(t *testing.T) { for _, test := range testCases { // Build Request - bid, err := getTestBidRequest(test.nilUser, test.userExt, true, nil) + bid, err := getTestBidRequest(test.nilUser, test.user, true, nil) if err != nil { t.Fatalf("Failed to marshal the complete openrtb2.BidRequest object %v", err) } @@ -341,15 +345,8 @@ func TestGDPRConsent(t *testing.T) { if !assert.NotNil(t, result.User, test.description+":lastRequest.User") { return } - if !assert.NotNil(t, result.User.Ext, test.description+":lastRequest.User.Ext") { - return - } - var ue openrtb_ext.ExtUser - err = jsonutil.UnmarshalValid(result.User.Ext, &ue) - if !assert.NoError(t, err, test.description+":deserialize") { - return - } - assert.Equal(t, test.expectedUserExt, ue, test.description) + + assert.Equal(t, test.expectedUser, result.User, test.description) assert.Equal(t, expectedErrorsFromHoldAuction, response.ORTB2.Ext.Errors, test.description+":errors") assert.Empty(t, response.ORTB2.Ext.Warnings, test.description+":warnings") @@ -372,15 +369,8 @@ func TestGDPRConsent(t *testing.T) { if !assert.NotNil(t, resultLegacy.User, test.description+":legacy:lastRequest.User") { return } - if !assert.NotNil(t, resultLegacy.User.Ext, test.description+":legacy:lastRequest.User.Ext") { - return - } - var ueLegacy openrtb_ext.ExtUser - err = jsonutil.UnmarshalValid(resultLegacy.User.Ext, &ueLegacy) - if !assert.NoError(t, err, test.description+":legacy:deserialize") { - return - } - assert.Equal(t, test.expectedUserExt, ueLegacy, test.description+":legacy") + + assert.Equal(t, test.expectedUser, resultLegacy.User, test.description+":legacy") assert.Equal(t, expectedErrorsFromHoldAuction, responseLegacy.ORTB2.Ext.Errors, test.description+":legacy:errors") assert.Empty(t, responseLegacy.ORTB2.Ext.Warnings, test.description+":legacy:warnings") } @@ -553,28 +543,6 @@ func TestOverrideWithParams(t *testing.T) { errorMsgs: []string{"unable to merge imp.ext with targeting data, check targeting data is correct: Invalid JSON Patch"}, }, }, - { - desc: "bid request with malformed user.ext.prebid - amp.Params with GDPR consent values - expect policy writer to return error", - given: testInput{ - ampParams: amp.Params{ - ConsentType: amp.ConsentTCF2, - Consent: "CPdECS0PdECS0ACABBENAzCv_____3___wAAAQNd_X9cAAAAAAAA", - }, - bidRequest: &openrtb2.BidRequest{ - Imp: []openrtb2.Imp{{Banner: &openrtb2.Banner{Format: []openrtb2.Format{}}}}, - User: &openrtb2.User{Ext: json.RawMessage(`{"prebid":{malformed}}`)}, - }, - }, - expected: testOutput{ - bidRequest: &openrtb2.BidRequest{ - Imp: []openrtb2.Imp{{Banner: &openrtb2.Banner{Format: []openrtb2.Format{}}}}, - User: &openrtb2.User{Ext: json.RawMessage(`{"prebid":{malformed}}`)}, - Site: &openrtb2.Site{Ext: json.RawMessage(`{"amp":1}`)}, - }, - errorMsgs: []string{"expect \" after {, but found m"}, - expectFatalErrors: true, - }, - }, } for _, test := range testCases { @@ -661,46 +629,46 @@ func TestCCPAConsent(t *testing.T) { var gdpr int8 = 1 testCases := []struct { - description string - consent string - regsExt *openrtb_ext.ExtRegs - nilRegs bool - expectedRegExt openrtb_ext.ExtRegs + description string + consent string + regs openrtb2.Regs + nilRegs bool + expectedReg *openrtb2.Regs }{ { description: "Nil Regs", consent: consent, nilRegs: true, - expectedRegExt: openrtb_ext.ExtRegs{ + expectedReg: &openrtb2.Regs{ USPrivacy: consent, }, }, { description: "Nil Regs Ext", consent: consent, - regsExt: nil, - expectedRegExt: openrtb_ext.ExtRegs{ + nilRegs: true, + expectedReg: &openrtb2.Regs{ USPrivacy: consent, }, }, { description: "Overrides Existing Consent", consent: consent, - regsExt: &openrtb_ext.ExtRegs{ + regs: openrtb2.Regs{ USPrivacy: existingConsent, }, - expectedRegExt: openrtb_ext.ExtRegs{ + expectedReg: &openrtb2.Regs{ USPrivacy: consent, }, }, { description: "Overrides Existing Consent - With Sibling Data", consent: consent, - regsExt: &openrtb_ext.ExtRegs{ + regs: openrtb2.Regs{ USPrivacy: existingConsent, GDPR: &gdpr, }, - expectedRegExt: openrtb_ext.ExtRegs{ + expectedReg: &openrtb2.Regs{ USPrivacy: consent, GDPR: &gdpr, }, @@ -708,10 +676,10 @@ func TestCCPAConsent(t *testing.T) { { description: "Does Not Override Existing Consent If Empty", consent: "", - regsExt: &openrtb_ext.ExtRegs{ + regs: openrtb2.Regs{ USPrivacy: existingConsent, }, - expectedRegExt: openrtb_ext.ExtRegs{ + expectedReg: &openrtb2.Regs{ USPrivacy: existingConsent, }, }, @@ -719,7 +687,7 @@ func TestCCPAConsent(t *testing.T) { for _, test := range testCases { // Build Request - bid, err := getTestBidRequest(true, nil, test.nilRegs, test.regsExt) + bid, err := getTestBidRequest(true, nil, test.nilRegs, &test.regs) if err != nil { t.Fatalf("Failed to marshal the complete openrtb2.BidRequest object %v", err) } @@ -765,15 +733,8 @@ func TestCCPAConsent(t *testing.T) { if !assert.NotNil(t, result.Regs, test.description+":lastRequest.Regs") { return } - if !assert.NotNil(t, result.Regs.Ext, test.description+":lastRequest.Regs.Ext") { - return - } - var re openrtb_ext.ExtRegs - err = jsonutil.UnmarshalValid(result.Regs.Ext, &re) - if !assert.NoError(t, err, test.description+":deserialize") { - return - } - assert.Equal(t, test.expectedRegExt, re, test.description) + + assert.Equal(t, test.expectedReg, result.Regs, test.description) assert.Equal(t, expectedErrorsFromHoldAuction, response.ORTB2.Ext.Errors) assert.Empty(t, response.ORTB2.Ext.Warnings) } @@ -781,7 +742,7 @@ func TestCCPAConsent(t *testing.T) { func TestConsentWarnings(t *testing.T) { type inputTest struct { - regs *openrtb_ext.ExtRegs + regs *openrtb2.Regs invalidConsentURL bool expectedWarnings map[openrtb_ext.BidderName][]openrtb_ext.ExtBidderMessage } @@ -812,7 +773,7 @@ func TestConsentWarnings(t *testing.T) { expectedWarnings: map[openrtb_ext.BidderName][]openrtb_ext.ExtBidderMessage{openrtb_ext.BidderReservedGeneral: {invalidCCPAWarning}}, }, { - regs: &openrtb_ext.ExtRegs{USPrivacy: "invalid"}, + regs: &openrtb2.Regs{USPrivacy: "invalid"}, invalidConsentURL: true, expectedWarnings: map[openrtb_ext.BidderName][]openrtb_ext.ExtBidderMessage{ openrtb_ext.BidderReservedGeneral: {invalidCCPAWarning, invalidConsentWarning}, @@ -820,7 +781,7 @@ func TestConsentWarnings(t *testing.T) { }, }, { - regs: &openrtb_ext.ExtRegs{USPrivacy: "1NYN"}, + regs: &openrtb2.Regs{USPrivacy: "1NYN"}, invalidConsentURL: false, expectedWarnings: map[openrtb_ext.BidderName][]openrtb_ext.ExtBidderMessage{openrtb_ext.BidderName("appnexus"): {bidderWarning}}, }, @@ -903,17 +864,18 @@ func TestNewAndLegacyConsentBothProvided(t *testing.T) { validConsentGDPR2 := "CPdiPIJPdiPIJACABBENAzCv_____3___wAAAQNd_X9cAAAAAAAA" testCases := []struct { - description string - consent string - consentLegacy string - userExt *openrtb_ext.ExtUser - expectedUserExt openrtb_ext.ExtUser + description string + consent string + consentLegacy string + user *openrtb2.User + expectedUser *openrtb2.User }{ { description: "New Consent Wins", consent: validConsentGDPR1, consentLegacy: validConsentGDPR2, - expectedUserExt: openrtb_ext.ExtUser{ + user: &openrtb2.User{}, + expectedUser: &openrtb2.User{ Consent: validConsentGDPR1, }, }, @@ -921,7 +883,8 @@ func TestNewAndLegacyConsentBothProvided(t *testing.T) { description: "New Consent Wins - Reverse", consent: validConsentGDPR2, consentLegacy: validConsentGDPR1, - expectedUserExt: openrtb_ext.ExtUser{ + user: &openrtb2.User{}, + expectedUser: &openrtb2.User{ Consent: validConsentGDPR2, }, }, @@ -929,7 +892,7 @@ func TestNewAndLegacyConsentBothProvided(t *testing.T) { for _, test := range testCases { // Build Request - bid, err := getTestBidRequest(false, nil, true, nil) + bid, err := getTestBidRequest(false, test.user, true, nil) if err != nil { t.Fatalf("Failed to marshal the complete openrtb2.BidRequest object %v", err) } @@ -978,15 +941,8 @@ func TestNewAndLegacyConsentBothProvided(t *testing.T) { if !assert.NotNil(t, result.User, test.description+":lastRequest.User") { return } - if !assert.NotNil(t, result.User.Ext, test.description+":lastRequest.User.Ext") { - return - } - var ue openrtb_ext.ExtUser - err = jsonutil.UnmarshalValid(result.User.Ext, &ue) - if !assert.NoError(t, err, test.description+":deserialize") { - return - } - assert.Equal(t, test.expectedUserExt, ue, test.description) + + assert.Equal(t, test.expectedUser, result.User, test.description) assert.Equal(t, expectedErrorsFromHoldAuction, response.ORTB2.Ext.Errors) assert.Empty(t, response.ORTB2.Ext.Warnings) } @@ -1030,6 +986,7 @@ func TestAMPSiteExt(t *testing.T) { } // TestBadRequests makes sure we return 400's on bad requests. +// RTB26: Will need to be fixed once all validation functions are updated to rtb 2.6 func TestAmpBadRequests(t *testing.T) { dir := "sample-requests/invalid-whole/" files, err := os.ReadDir(dir) @@ -1037,6 +994,7 @@ func TestAmpBadRequests(t *testing.T) { mockAmpStoredReq := make(map[string]json.RawMessage, len(files)) badRequests := make(map[string]testCase, len(files)) + filemap := make(map[string]string, len(files)) for index, file := range files { filename := file.Name() fileData := readFile(t, dir+filename) @@ -1055,6 +1013,7 @@ func TestAmpBadRequests(t *testing.T) { badRequests[requestID] = test mockAmpStoredReq[requestID] = test.BidRequest + filemap[requestID] = filename } addAmpBadRequests(badRequests, mockAmpStoredReq) @@ -1076,15 +1035,17 @@ func TestAmpBadRequests(t *testing.T) { nil, ) - for _, test := range badRequests { - request := httptest.NewRequest("GET", fmt.Sprintf("/openrtb2/auction/amp?%s", test.Query), nil) - recorder := httptest.NewRecorder() + for id, test := range badRequests { + t.Run(filemap[id], func(t *testing.T) { + request := httptest.NewRequest("GET", fmt.Sprintf("/openrtb2/auction/amp?%s", test.Query), nil) + recorder := httptest.NewRecorder() - endpoint(recorder, request, nil) + endpoint(recorder, request, nil) - response := recorder.Body.String() - assert.Equal(t, test.ExpectedReturnCode, recorder.Code, test.Description) - assert.Contains(t, response, test.ExpectedErrorMessage, "Actual: %s \nExpected: %s. Description: %s \n", response, test.ExpectedErrorMessage, test.Description) + response := recorder.Body.String() + assert.Equal(t, test.ExpectedReturnCode, recorder.Code, test.Description) + assert.Contains(t, response, test.ExpectedErrorMessage, "Actual: %s \nExpected: %s. Description: %s \n", response, test.ExpectedErrorMessage, test.Description) + }) } } @@ -1555,7 +1516,7 @@ func (m *mockAmpExchangeWarnings) HoldAuction(ctx context.Context, r *exchange.A return &exchange.AuctionResponse{BidResponse: response}, nil } -func getTestBidRequest(nilUser bool, userExt *openrtb_ext.ExtUser, nilRegs bool, regsExt *openrtb_ext.ExtRegs) ([]byte, error) { +func getTestBidRequest(nilUser bool, user *openrtb2.User, nilRegs bool, regs *openrtb2.Regs) ([]byte, error) { var width int64 = 300 var height int64 = 300 bidRequest := &openrtb2.BidRequest{ @@ -1586,37 +1547,12 @@ func getTestBidRequest(nilUser bool, userExt *openrtb_ext.ExtUser, nilRegs bool, }, } - var userExtData []byte - if userExt != nil { - var err error - userExtData, err = jsonutil.Marshal(userExt) - if err != nil { - return nil, err - } - } - if !nilUser { - bidRequest.User = &openrtb2.User{ - ID: "aUserId", - BuyerUID: "aBuyerID", - Ext: userExtData, - } - } - - var regsExtData []byte - if regsExt != nil { - var err error - regsExtData, err = jsonutil.Marshal(regsExt) - if err != nil { - return nil, err - } + bidRequest.User = user } if !nilRegs { - bidRequest.Regs = &openrtb2.Regs{ - COPPA: 1, - Ext: regsExtData, - } + bidRequest.Regs = regs } return jsonutil.Marshal(bidRequest) } @@ -1734,6 +1670,7 @@ func (logger mockLogger) LogNotificationEventObject(uuidObj *analytics.Notificat func (logger mockLogger) LogAmpObject(ao *analytics.AmpObject, _ privacy.ActivityControl) { *logger.ampObject = *ao } +func (logger mockLogger) Shutdown() {} func TestBuildAmpObject(t *testing.T) { testCases := []struct { diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go index 57d9e73a27d..fa61c484f0d 100644 --- a/endpoints/openrtb2/auction.go +++ b/endpoints/openrtb2/auction.go @@ -22,37 +22,37 @@ import ( "github.com/prebid/go-gpp/constants" "github.com/prebid/openrtb/v20/openrtb2" "github.com/prebid/openrtb/v20/openrtb3" - "github.com/prebid/prebid-server/v2/bidadjustment" - "github.com/prebid/prebid-server/v2/hooks" - "github.com/prebid/prebid-server/v2/ortb" - "github.com/prebid/prebid-server/v2/privacy" - "github.com/prebid/prebid-server/v2/privacysandbox" + "github.com/prebid/prebid-server/v3/bidadjustment" + "github.com/prebid/prebid-server/v3/hooks" + "github.com/prebid/prebid-server/v3/ortb" + "github.com/prebid/prebid-server/v3/privacy" + "github.com/prebid/prebid-server/v3/privacysandbox" + "github.com/prebid/prebid-server/v3/schain" "golang.org/x/net/publicsuffix" jsonpatch "gopkg.in/evanphx/json-patch.v4" - accountService "github.com/prebid/prebid-server/v2/account" - "github.com/prebid/prebid-server/v2/analytics" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/currency" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/exchange" - "github.com/prebid/prebid-server/v2/gdpr" - "github.com/prebid/prebid-server/v2/hooks/hookexecution" - "github.com/prebid/prebid-server/v2/metrics" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/prebid_cache_client" - "github.com/prebid/prebid-server/v2/privacy/ccpa" - "github.com/prebid/prebid-server/v2/privacy/lmt" - "github.com/prebid/prebid-server/v2/schain" - "github.com/prebid/prebid-server/v2/stored_requests" - "github.com/prebid/prebid-server/v2/stored_requests/backends/empty_fetcher" - "github.com/prebid/prebid-server/v2/stored_responses" - "github.com/prebid/prebid-server/v2/usersync" - "github.com/prebid/prebid-server/v2/util/httputil" - "github.com/prebid/prebid-server/v2/util/iputil" - "github.com/prebid/prebid-server/v2/util/jsonutil" - "github.com/prebid/prebid-server/v2/util/uuidutil" - "github.com/prebid/prebid-server/v2/version" + accountService "github.com/prebid/prebid-server/v3/account" + "github.com/prebid/prebid-server/v3/analytics" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/currency" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/exchange" + "github.com/prebid/prebid-server/v3/gdpr" + "github.com/prebid/prebid-server/v3/hooks/hookexecution" + "github.com/prebid/prebid-server/v3/metrics" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/prebid_cache_client" + "github.com/prebid/prebid-server/v3/privacy/ccpa" + "github.com/prebid/prebid-server/v3/privacy/lmt" + "github.com/prebid/prebid-server/v3/stored_requests" + "github.com/prebid/prebid-server/v3/stored_requests/backends/empty_fetcher" + "github.com/prebid/prebid-server/v3/stored_responses" + "github.com/prebid/prebid-server/v3/usersync" + "github.com/prebid/prebid-server/v3/util/httputil" + "github.com/prebid/prebid-server/v3/util/iputil" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/uuidutil" + "github.com/prebid/prebid-server/v3/version" ) const ampChannel = "amp" @@ -64,6 +64,7 @@ const observeBrowsingTopicsValue = "?1" var ( dntKey string = http.CanonicalHeaderKey("DNT") + secGPCKey string = http.CanonicalHeaderKey("Sec-GPC") dntDisabled int8 = 0 dntEnabled int8 = 1 notAmp int8 = 0 @@ -533,6 +534,12 @@ func (deps *endpointDeps) parseRequest(httpRequest *http.Request, labels *metric return } + // normalize to openrtb 2.6 + if err := openrtb_ext.ConvertUpTo26(req); err != nil { + errs = []error{err} + return + } + if err := mergeBidderParams(req); err != nil { errs = []error{err} return @@ -823,10 +830,6 @@ func (deps *endpointDeps) validateRequest(account *config.Account, httpReq *http } } - if err := mapSChains(req); err != nil { - return []error{err} - } - if err := validateOrFillChannel(req, isAmp); err != nil { return []error{err} } @@ -930,32 +933,6 @@ func (deps *endpointDeps) validateRequest(account *config.Account, httpReq *http return errL } -// mapSChains maps an schain defined in an ORTB 2.4 location (req.ext.schain) to the ORTB 2.5 location -// (req.source.ext.schain) if no ORTB 2.5 schain (req.source.ext.schain, req.ext.prebid.schains) exists. -// An ORTB 2.4 schain is always deleted from the 2.4 location regardless of whether an ORTB 2.5 schain exists. -func mapSChains(req *openrtb_ext.RequestWrapper) error { - reqExt, err := req.GetRequestExt() - if err != nil { - return fmt.Errorf("req.ext is invalid: %v", err) - } - sourceExt, err := req.GetSourceExt() - if err != nil { - return fmt.Errorf("source.ext is invalid: %v", err) - } - - reqExtSChain := reqExt.GetSChain() - reqExt.SetSChain(nil) - - if reqPrebid := reqExt.GetPrebid(); reqPrebid != nil && reqPrebid.SChains != nil { - return nil - } else if sourceExt.GetSChain() != nil { - return nil - } else if reqExtSChain != nil { - sourceExt.SetSChain(reqExtSChain) - } - return nil -} - func validateAndFillSourceTID(req *openrtb_ext.RequestWrapper, generateRequestID bool, hasStoredBidRequest bool, isAmp bool) error { if req.Source == nil { req.Source = &openrtb2.Source{} @@ -1229,8 +1206,8 @@ func (deps *endpointDeps) validateApp(req *openrtb_ext.RequestWrapper) error { } if req.App.ID != "" { - if _, found := deps.cfg.BlacklistedAppMap[req.App.ID]; found { - return &errortypes.BlacklistedApp{Message: fmt.Sprintf("Prebid-server does not process requests from App ID: %s", req.App.ID)} + if _, found := deps.cfg.BlockedAppsLookup[req.App.ID]; found { + return &errortypes.BlockedApp{Message: fmt.Sprintf("Prebid-server does not process requests from App ID: %s", req.App.ID)} } } @@ -1294,22 +1271,18 @@ func (deps *endpointDeps) validateUser(req *openrtb_ext.RequestWrapper, aliases } // Check Universal User ID - eids := userExt.GetEid() - if eids != nil { - eidsValue := *eids - for eidIndex, eid := range eidsValue { - if eid.Source == "" { - return append(errL, fmt.Errorf("request.user.ext.eids[%d] missing required field: \"source\"", eidIndex)) - } + for eidIndex, eid := range req.User.EIDs { + if eid.Source == "" { + return append(errL, fmt.Errorf("request.user.eids[%d] missing required field: \"source\"", eidIndex)) + } - if len(eid.UIDs) == 0 { - return append(errL, fmt.Errorf("request.user.ext.eids[%d].uids must contain at least one element or be undefined", eidIndex)) - } + if len(eid.UIDs) == 0 { + return append(errL, fmt.Errorf("request.user.eids[%d].uids must contain at least one element or be undefined", eidIndex)) + } - for uidIndex, uid := range eid.UIDs { - if uid.ID == "" { - return append(errL, fmt.Errorf("request.user.ext.eids[%d].uids[%d] missing required field: \"id\"", eidIndex, uidIndex)) - } + for uidIndex, uid := range eid.UIDs { + if uid.ID == "" { + return append(errL, fmt.Errorf("request.user.eids[%d].uids[%d] missing required field: \"id\"", eidIndex, uidIndex)) } } } @@ -1338,16 +1311,11 @@ func validateRegs(req *openrtb_ext.RequestWrapper, gpp gpplib.GppContainer) []er WarningCode: errortypes.InvalidPrivacyConsentWarningCode}) } } - regsExt, err := req.GetRegExt() - if err != nil { - return append(errL, fmt.Errorf("request.regs.ext is invalid: %v", err)) - } - gdpr := regsExt.GetGDPR() - if gdpr != nil && *gdpr != 0 && *gdpr != 1 { - return append(errL, errors.New("request.regs.ext.gdpr must be either 0 or 1")) + reqGDPR := req.BidRequest.Regs.GDPR + if reqGDPR != nil && *reqGDPR != 0 && *reqGDPR != 1 { + return append(errL, errors.New("request.regs.gdpr must be either 0 or 1")) } - return errL } @@ -1370,7 +1338,6 @@ func validateDevice(device *openrtb2.Device) error { if device.Geo != nil && device.Geo.Accuracy < 0 { return errors.New("request.device.geo.accuracy must be a positive number") } - return nil } @@ -1497,6 +1464,11 @@ func (deps *endpointDeps) setFieldsImplicitly(httpReq *http.Request, r *openrtb_ setAuctionTypeImplicitly(r) + err := setGPCImplicitly(httpReq, r) + if err != nil { + return []error{err} + } + errs := setSecBrowsingTopicsImplicitly(httpReq, r, account) return errs } @@ -1516,6 +1488,28 @@ func setAuctionTypeImplicitly(r *openrtb_ext.RequestWrapper) { } } +func setGPCImplicitly(httpReq *http.Request, r *openrtb_ext.RequestWrapper) error { + secGPC := httpReq.Header.Get(secGPCKey) + + if secGPC != "1" { + return nil + } + + regExt, err := r.GetRegExt() + if err != nil { + return err + } + + if regExt.GetGPC() != nil { + return nil + } + + gpc := "1" + regExt.SetGPC(&gpc) + + return nil +} + // setSecBrowsingTopicsImplicitly updates user.data with data from request header 'Sec-Browsing-Topics' func setSecBrowsingTopicsImplicitly(httpReq *http.Request, r *openrtb_ext.RequestWrapper, account *config.Account) []error { secBrowsingTopics := httpReq.Header.Get(secBrowsingTopics) @@ -1676,9 +1670,9 @@ func (deps *endpointDeps) processStoredRequests(requestJson []byte, impInfo []Im } } - // Apply default aliases, if they are provided + // apply default stored request if deps.defaultRequest { - aliasedRequest, err := jsonpatch.MergePatch(deps.defReqJSON, resolvedRequest) + merged, err := jsonpatch.MergePatch(deps.defReqJSON, resolvedRequest) if err != nil { hasErr, Err := getJsonSyntaxError(resolvedRequest) if hasErr { @@ -1691,7 +1685,7 @@ func (deps *endpointDeps) processStoredRequests(requestJson []byte, impInfo []Im } return nil, nil, []error{err} } - resolvedRequest = aliasedRequest + resolvedRequest = merged } // Apply any Stored Imps, if they exist. Since the JSON Merge Patch overrides arrays, @@ -1870,9 +1864,9 @@ func writeError(errs []error, w http.ResponseWriter, labels *metrics.Labels) boo metricsStatus := metrics.RequestStatusBadInput for _, err := range errs { erVal := errortypes.ReadCode(err) - if erVal == errortypes.BlacklistedAppErrorCode || erVal == errortypes.AccountDisabledErrorCode { + if erVal == errortypes.BlockedAppErrorCode || erVal == errortypes.AccountDisabledErrorCode { httpStatus = http.StatusServiceUnavailable - metricsStatus = metrics.RequestStatusBlacklisted + metricsStatus = metrics.RequestStatusBlockedApp break } else if erVal == errortypes.MalformedAcctErrorCode { httpStatus = http.StatusInternalServerError diff --git a/endpoints/openrtb2/auction_benchmark_test.go b/endpoints/openrtb2/auction_benchmark_test.go index d3dbc518bd3..9697687407e 100644 --- a/endpoints/openrtb2/auction_benchmark_test.go +++ b/endpoints/openrtb2/auction_benchmark_test.go @@ -10,18 +10,18 @@ import ( "testing" "time" - analyticsBuild "github.com/prebid/prebid-server/v2/analytics/build" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/currency" - "github.com/prebid/prebid-server/v2/exchange" - "github.com/prebid/prebid-server/v2/experiment/adscert" - "github.com/prebid/prebid-server/v2/hooks" - "github.com/prebid/prebid-server/v2/macros" - metricsConfig "github.com/prebid/prebid-server/v2/metrics/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/ortb" - "github.com/prebid/prebid-server/v2/stored_requests/backends/empty_fetcher" - "github.com/prebid/prebid-server/v2/usersync" + analyticsBuild "github.com/prebid/prebid-server/v3/analytics/build" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/currency" + "github.com/prebid/prebid-server/v3/exchange" + "github.com/prebid/prebid-server/v3/experiment/adscert" + "github.com/prebid/prebid-server/v3/hooks" + "github.com/prebid/prebid-server/v3/macros" + metricsConfig "github.com/prebid/prebid-server/v3/metrics/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/ortb" + "github.com/prebid/prebid-server/v3/stored_requests/backends/empty_fetcher" + "github.com/prebid/prebid-server/v3/usersync" ) // benchmarkTestServer returns the header bidding test ad. This response was scraped from a real appnexus server response. @@ -152,8 +152,8 @@ func BenchmarkValidWholeExemplary(b *testing.B) { cfg := &config.Configuration{ MaxRequestSize: maxSize, - BlacklistedApps: test.Config.BlacklistedApps, - BlacklistedAppMap: test.Config.getBlacklistedAppMap(), + BlockedApps: test.Config.BlockedApps, + BlockedAppsLookup: test.Config.getBlockedAppLookup(), AccountRequired: test.Config.AccountRequired, } diff --git a/endpoints/openrtb2/auction_test.go b/endpoints/openrtb2/auction_test.go index 717609e23d9..2df4813d157 100644 --- a/endpoints/openrtb2/auction_test.go +++ b/endpoints/openrtb2/auction_test.go @@ -22,23 +22,23 @@ import ( jsoniter "github.com/json-iterator/go" "github.com/julienschmidt/httprouter" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/analytics" - analyticsBuild "github.com/prebid/prebid-server/v2/analytics/build" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/exchange" - "github.com/prebid/prebid-server/v2/hooks" - "github.com/prebid/prebid-server/v2/hooks/hookexecution" - "github.com/prebid/prebid-server/v2/hooks/hookstage" - "github.com/prebid/prebid-server/v2/metrics" - metricsConfig "github.com/prebid/prebid-server/v2/metrics/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/ortb" - "github.com/prebid/prebid-server/v2/stored_requests/backends/empty_fetcher" - "github.com/prebid/prebid-server/v2/stored_responses" - "github.com/prebid/prebid-server/v2/util/iputil" - "github.com/prebid/prebid-server/v2/util/jsonutil" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/analytics" + analyticsBuild "github.com/prebid/prebid-server/v3/analytics/build" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/exchange" + "github.com/prebid/prebid-server/v3/hooks" + "github.com/prebid/prebid-server/v3/hooks/hookexecution" + "github.com/prebid/prebid-server/v3/hooks/hookstage" + "github.com/prebid/prebid-server/v3/metrics" + metricsConfig "github.com/prebid/prebid-server/v3/metrics/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/ortb" + "github.com/prebid/prebid-server/v3/stored_requests/backends/empty_fetcher" + "github.com/prebid/prebid-server/v3/stored_responses" + "github.com/prebid/prebid-server/v3/util/iputil" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/ptrutil" "github.com/stretchr/testify/assert" ) @@ -83,8 +83,8 @@ func TestJsonSampleRequests(t *testing.T) { "account-malformed", }, { - "Asserts we return 503s on requests with blacklisted accounts and apps.", - "blacklisted", + "Asserts we return 503s on requests with blocked apps.", + "blocked", }, { "Assert that requests that come with no user id nor app id return error if the `AccountRequired` field in the `config.Configuration` structure is set to true", @@ -169,18 +169,37 @@ func runJsonBasedTest(t *testing.T, filename, desc string) { // Build endpoint for testing. If no error, run test case cfg := &config.Configuration{MaxRequestSize: maxSize} if test.Config != nil { - cfg.BlacklistedApps = test.Config.BlacklistedApps - cfg.BlacklistedAppMap = test.Config.getBlacklistedAppMap() + cfg.BlockedApps = test.Config.BlockedApps + cfg.BlockedAppsLookup = test.Config.getBlockedAppLookup() cfg.AccountRequired = test.Config.AccountRequired } cfg.MarshalAccountDefaults() test.endpointType = OPENRTB_ENDPOINT - auctionEndpointHandler, _, mockBidServers, mockCurrencyRatesServer, err := buildTestEndpoint(test, cfg) + auctionEndpointHandler, ex, mockBidServers, mockCurrencyRatesServer, err := buildTestEndpoint(test, cfg) if assert.NoError(t, err) { assert.NotPanics(t, func() { runEndToEndTest(t, auctionEndpointHandler, test, fileData, filename) }, filename) } + if test.ExpectedValidatedBidReq != nil { + // compare as json to ignore whitespace and ext field ordering + actualJson, err := jsonutil.Marshal(ex.actualValidatedBidReq) + if assert.NoError(t, err, "Error converting actual bid request to json. Test file: %s", filename) { + assert.JSONEq(t, string(test.ExpectedValidatedBidReq), string(actualJson), "Not the expected validated request. Test file: %s", filename) + } + } + if test.ExpectedMockBidderRequests != nil { + for bidder, req := range test.ExpectedMockBidderRequests { + a, ok := ex.adapters[openrtb_ext.BidderName(bidder)] + if !ok { + t.Fatalf("Unexpected bidder %s has an expected mock bidder request. Test file: %s", bidder, filename) + } + aa := a.(*exchange.BidderAdapter) + ma := aa.Bidder.(*mockAdapter) + assert.JSONEq(t, string(req), string(ma.requestData[0]), "Not the expected mock bidder request for bidder %s. Test file: %s", bidder, filename) + } + } + // Close servers regardless if the test case was run or not for _, mockBidServer := range mockBidServers { mockBidServer.Close() @@ -2775,7 +2794,7 @@ func TestCCPAInvalid(t *testing.T) { ID: "anySiteID", }, Regs: &openrtb2.Regs{ - Ext: json.RawMessage(`{"us_privacy": "invalid by length"}`), + USPrivacy: "invalid by length", }, } @@ -2938,134 +2957,6 @@ func TestSChainInvalid(t *testing.T) { assert.ElementsMatch(t, errL, []error{expectedError}) } -func TestMapSChains(t *testing.T) { - const seller1SChain string = `"schain":{"complete":1,"nodes":[{"asi":"directseller1.com","sid":"00001","rid":"BidRequest1","hp":1}],"ver":"1.0"}` - const seller2SChain string = `"schain":{"complete":2,"nodes":[{"asi":"directseller2.com","sid":"00002","rid":"BidRequest2","hp":2}],"ver":"2.0"}` - - seller1SChainUnpacked := openrtb2.SupplyChain{ - Complete: 1, - Nodes: []openrtb2.SupplyChainNode{{ - ASI: "directseller1.com", - SID: "00001", - RID: "BidRequest1", - HP: openrtb2.Int8Ptr(1), - }}, - Ver: "1.0", - } - - tests := []struct { - description string - bidRequest openrtb2.BidRequest - wantReqExtSChain *openrtb2.SupplyChain - wantSourceExtSChain *openrtb2.SupplyChain - wantError bool - }{ - { - description: "invalid req.ext", - bidRequest: openrtb2.BidRequest{ - Ext: json.RawMessage(`{"prebid":{"schains":invalid}}`), - Source: &openrtb2.Source{ - Ext: json.RawMessage(`{}`), - }, - }, - wantError: true, - }, - { - description: "invalid source.ext", - bidRequest: openrtb2.BidRequest{ - Ext: json.RawMessage(`{}`), - Source: &openrtb2.Source{ - Ext: json.RawMessage(`{"schain":invalid}}`), - }, - }, - wantError: true, - }, - { - description: "req.ext.prebid.schains, req.source.ext.schain and req.ext.schain are nil", - bidRequest: openrtb2.BidRequest{ - Ext: json.RawMessage(`{}`), - Source: &openrtb2.Source{ - Ext: json.RawMessage(`{}`), - }, - }, - wantReqExtSChain: nil, - wantSourceExtSChain: nil, - }, - { - description: "req.ext.prebid.schains is not nil", - bidRequest: openrtb2.BidRequest{ - Ext: json.RawMessage(`{"prebid":{"schains":[{"bidders":["appnexus"],` + seller1SChain + `}]}}`), - Source: &openrtb2.Source{ - Ext: json.RawMessage(`{}`), - }, - }, - wantReqExtSChain: nil, - wantSourceExtSChain: nil, - }, - { - description: "req.source.ext is not nil", - bidRequest: openrtb2.BidRequest{ - Ext: json.RawMessage(`{}`), - Source: &openrtb2.Source{ - Ext: json.RawMessage(`{` + seller1SChain + `}`), - }, - }, - wantReqExtSChain: nil, - wantSourceExtSChain: &seller1SChainUnpacked, - }, - { - description: "req.ext.schain is not nil", - bidRequest: openrtb2.BidRequest{ - Ext: json.RawMessage(`{` + seller1SChain + `}`), - Source: &openrtb2.Source{ - Ext: json.RawMessage(`{}`), - }, - }, - wantReqExtSChain: nil, - wantSourceExtSChain: &seller1SChainUnpacked, - }, - { - description: "req.source.ext.schain and req.ext.schain are not nil", - bidRequest: openrtb2.BidRequest{ - Ext: json.RawMessage(`{` + seller2SChain + `}`), - Source: &openrtb2.Source{ - Ext: json.RawMessage(`{` + seller1SChain + `}`), - }, - }, - wantReqExtSChain: nil, - wantSourceExtSChain: &seller1SChainUnpacked, - }, - } - - for _, test := range tests { - reqWrapper := openrtb_ext.RequestWrapper{ - BidRequest: &test.bidRequest, - } - - err := mapSChains(&reqWrapper) - - if test.wantError { - assert.NotNil(t, err, test.description) - } else { - assert.Nil(t, err, test.description) - - reqExt, err := reqWrapper.GetRequestExt() - if err != nil { - assert.Fail(t, "Error getting request ext from wrapper", test.description) - } - reqExtSChain := reqExt.GetSChain() - assert.Equal(t, test.wantReqExtSChain, reqExtSChain, test.description) - - sourceExt, err := reqWrapper.GetSourceExt() - if err != nil { - assert.Fail(t, "Error getting source ext from wrapper", test.description) - } - sourceExtSChain := sourceExt.GetSChain() - assert.Equal(t, test.wantSourceExtSChain, sourceExtSChain, test.description) - } - } -} - func TestSearchAccountID(t *testing.T) { // Correctness for lookup within Publisher object left to TestGetAccountID // This however tests the expected lookup paths in outer site, app and dooh @@ -5618,6 +5509,175 @@ func TestValidateOrFillCookieDeprecation(t *testing.T) { } } +func TestSetGPCImplicitly(t *testing.T) { + testCases := []struct { + description string + header string + regs *openrtb2.Regs + expectError bool + expectedRegs *openrtb2.Regs + }{ + { + description: "regs_ext_gpc_not_set_and_header_is_1", + header: "1", + regs: &openrtb2.Regs{ + Ext: []byte(`{}`), + }, + expectError: false, + expectedRegs: &openrtb2.Regs{ + Ext: []byte(`{"gpc":"1"}`), + }, + }, + { + description: "sec_gpc_header_not_set_gpc_should_not_be_modified", + header: "", + regs: &openrtb2.Regs{ + Ext: []byte(`{}`), + }, + expectError: false, + expectedRegs: &openrtb2.Regs{ + Ext: []byte(`{}`), + }, + }, + { + description: "sec_gpc_header_set_to_2_gpc_should_not_be_modified", + header: "2", + regs: &openrtb2.Regs{ + Ext: []byte(`{}`), + }, + expectError: false, + expectedRegs: &openrtb2.Regs{ + Ext: []byte(`{}`), + }, + }, + { + description: "sec_gpc_header_set_to_1_and_regs_ext_contains_other_data", + header: "1", + regs: &openrtb2.Regs{ + Ext: []byte(`{"some_other_field":"some_value"}`), + }, + expectError: false, + expectedRegs: &openrtb2.Regs{ + Ext: []byte(`{"some_other_field":"some_value","gpc":"1"}`), + }, + }, + { + description: "regs_ext_gpc_not_set_and_header_not_set", + header: "", + regs: &openrtb2.Regs{ + Ext: []byte(`{}`), + }, + expectError: false, + expectedRegs: &openrtb2.Regs{ + Ext: []byte(`{}`), + }, + }, + { + description: "regs_ext_gpc_not_set_and_header_not_1", + header: "0", + regs: &openrtb2.Regs{ + Ext: []byte(`{}`), + }, + expectError: false, + expectedRegs: &openrtb2.Regs{ + Ext: []byte(`{}`), + }, + }, + { + description: "regs_ext_gpc_is_1_and_header_is_1", + header: "1", + regs: &openrtb2.Regs{ + Ext: []byte(`{"gpc":"1"}`), + }, + expectError: false, + expectedRegs: &openrtb2.Regs{ + Ext: []byte(`{"gpc":"1"}`), + }, + }, + { + description: "regs_ext_gpc_is_1_and_header_not_1", + header: "0", + regs: &openrtb2.Regs{ + Ext: []byte(`{"gpc":"1"}`), + }, + expectError: false, + expectedRegs: &openrtb2.Regs{ + Ext: []byte(`{"gpc":"1"}`), + }, + }, + { + description: "regs_ext_other_data_and_header_is_1", + header: "1", + regs: &openrtb2.Regs{ + Ext: []byte(`{"other":"value"}`), + }, + expectError: false, + expectedRegs: &openrtb2.Regs{ + Ext: []byte(`{"other":"value","gpc":"1"}`), + }, + }, + { + description: "regs_nil_and_header_is_1", + header: "1", + regs: nil, + expectError: false, + expectedRegs: &openrtb2.Regs{ + Ext: []byte(`{"gpc":"1"}`), + }, + }, + { + description: "regs_nil_and_header_not_set", + header: "", + regs: nil, + expectError: false, + expectedRegs: nil, + }, + { + description: "regs_ext_is_nil_and_header_not_set", + header: "", + regs: &openrtb2.Regs{ + Ext: nil, + }, + expectError: false, + expectedRegs: &openrtb2.Regs{ + Ext: nil, + }, + }, + } + + for _, test := range testCases { + t.Run(test.description, func(t *testing.T) { + httpReq := &http.Request{ + Header: http.Header{ + http.CanonicalHeaderKey("Sec-GPC"): []string{test.header}, + }, + } + + r := &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Regs: test.regs, + }, + } + + err := setGPCImplicitly(httpReq, r) + + if test.expectError { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + assert.NoError(t, r.RebuildRequest()) + if test.expectedRegs == nil { + assert.Nil(t, r.BidRequest.Regs) + } else if test.expectedRegs.Ext == nil { + assert.Nil(t, r.BidRequest.Regs.Ext) + } else { + assert.JSONEq(t, string(test.expectedRegs.Ext), string(r.BidRequest.Regs.Ext)) + } + }) + } +} + func TestValidateRequestCookieDeprecation(t *testing.T) { testCases := []struct { diff --git a/endpoints/openrtb2/interstitial.go b/endpoints/openrtb2/interstitial.go index a1af3e4721f..4cb9482c0d5 100644 --- a/endpoints/openrtb2/interstitial.go +++ b/endpoints/openrtb2/interstitial.go @@ -4,9 +4,9 @@ import ( "fmt" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func processInterstitials(req *openrtb_ext.RequestWrapper) error { diff --git a/endpoints/openrtb2/interstitial_test.go b/endpoints/openrtb2/interstitial_test.go index 6373d18407b..d5276d18dba 100644 --- a/endpoints/openrtb2/interstitial_test.go +++ b/endpoints/openrtb2/interstitial_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/endpoints/openrtb2/sample-requests/amp/consent-through-query/gdpr-ccpa-through-query.json b/endpoints/openrtb2/sample-requests/amp/consent-through-query/gdpr-ccpa-through-query.json index 8dc19f6f24d..30d8b9ca240 100644 --- a/endpoints/openrtb2/sample-requests/amp/consent-through-query/gdpr-ccpa-through-query.json +++ b/endpoints/openrtb2/sample-requests/amp/consent-through-query/gdpr-ccpa-through-query.json @@ -74,9 +74,7 @@ } ], "regs": { - "ext": { - "us_privacy": "1YYY" - } + "us_privacy": "1YYY" }, "ext": { "prebid": { diff --git a/endpoints/openrtb2/sample-requests/amp/consent-through-query/gdpr-legacy-tcf2-consent-through-query.json b/endpoints/openrtb2/sample-requests/amp/consent-through-query/gdpr-legacy-tcf2-consent-through-query.json index 4003abf99cb..8c232192a63 100644 --- a/endpoints/openrtb2/sample-requests/amp/consent-through-query/gdpr-legacy-tcf2-consent-through-query.json +++ b/endpoints/openrtb2/sample-requests/amp/consent-through-query/gdpr-legacy-tcf2-consent-through-query.json @@ -74,14 +74,10 @@ } ], "regs": { - "ext": { - "gdpr": 1 - } + "gdpr": 1 }, "user": { - "ext": { - "consent": "CPdECS0PdECS0ACABBENAzCv_____3___wAAAQNd_X9cAAAAAAAA" - } + "consent": "CPdECS0PdECS0ACABBENAzCv_____3___wAAAQNd_X9cAAAAAAAA" }, "ext": { "prebid": { diff --git a/endpoints/openrtb2/sample-requests/amp/consent-through-query/gdpr-tcf1-consent-through-query.json b/endpoints/openrtb2/sample-requests/amp/consent-through-query/gdpr-tcf1-consent-through-query.json index c6389dadc29..0249bbc3f96 100644 --- a/endpoints/openrtb2/sample-requests/amp/consent-through-query/gdpr-tcf1-consent-through-query.json +++ b/endpoints/openrtb2/sample-requests/amp/consent-through-query/gdpr-tcf1-consent-through-query.json @@ -79,9 +79,7 @@ } ], "regs": { - "ext": { - "gdpr": 1 - } + "gdpr": 1 }, "ext": { "prebid": { diff --git a/endpoints/openrtb2/sample-requests/amp/consent-through-query/gdpr-tcf2-consent-through-query.json b/endpoints/openrtb2/sample-requests/amp/consent-through-query/gdpr-tcf2-consent-through-query.json index b62a745b1bf..6f0f5780b43 100644 --- a/endpoints/openrtb2/sample-requests/amp/consent-through-query/gdpr-tcf2-consent-through-query.json +++ b/endpoints/openrtb2/sample-requests/amp/consent-through-query/gdpr-tcf2-consent-through-query.json @@ -74,14 +74,10 @@ } ], "regs": { - "ext": { - "gdpr": 1 - } + "gdpr": 1 }, "user": { - "ext": { - "consent": "CPdECS0PdECS0ACABBENAzCv_____3___wAAAQNd_X9cAAAAAAAA" - } + "consent": "CPdECS0PdECS0ACABBENAzCv_____3___wAAAQNd_X9cAAAAAAAA" }, "ext": { "prebid": { diff --git a/endpoints/openrtb2/sample-requests/amp/valid-supplementary/ortb-2.5-to-2.6-upconvert.json b/endpoints/openrtb2/sample-requests/amp/valid-supplementary/ortb-2.5-to-2.6-upconvert.json new file mode 100644 index 00000000000..766b7fc6ba9 --- /dev/null +++ b/endpoints/openrtb2/sample-requests/amp/valid-supplementary/ortb-2.5-to-2.6-upconvert.json @@ -0,0 +1,306 @@ +{ + "description": "Amp request with all 2.5 ext fields that were moved into 2.6 ortb fields", + "query": "tag_id=101", + "config": { + "mockBidders": [ + { + "bidderName": "appnexus", + "currency": "USD", + "price": 15 + } + ] + }, + "mockBidRequest": { + "id": "b9c97a4b-cbc4-483d-b2c4-58a19ed5cfc5", + "site": { + "page": "prebid.org" + }, + "imp": [ + { + "id": "/19968336/header-bid-tag-0", + "banner": { + "format": [ + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "prebid": { + "bidder": { + "appnexus": { + "placementId": 12883451 + } + }, + "is_rewarded_inventory": 1 + } + } + } + ], + "regs": { + "ext": { + "gdpr": 1, + "us_privacy": "1YYY" + } + }, + "user": { + "ext": { + "consent": "some-consent-string", + "eids": [ + { + "source": "source", + "uids": [ + { + "id": "1", + "atype": 1, + "ext": {} + }, + { + "id": "1", + "atype": 1, + "ext": {} + } + ], + "ext": {} + } + ] + } + }, + "source": { + "ext": { + "schain": { + "complete": 1, + "nodes": [ + { + "asi": "whatever.com", + "sid": "1234", + "rid": "123-456-7890", + "hp": 1 + } + ], + "ver": "2.0" + } + } + } + }, + "expectedValidatedBidRequest": { + "id": "b9c97a4b-cbc4-483d-b2c4-58a19ed5cfc5", + "site": { + "page": "prebid.org", + "ext": { + "amp": 1 + } + }, + "device": { + "ip": "192.0.2.1" + }, + "at": 1, + "imp": [ + { + "id": "/19968336/header-bid-tag-0", + "banner": { + "format": [ + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "prebid": { + "bidder": { + "appnexus": { + "placementId": 12883451 + } + } + } + }, + "secure": 1, + "rwdd": 1 + } + ], + "regs": { + "gdpr": 1, + "us_privacy": "1YYY" + }, + "user": { + "consent": "some-consent-string", + "eids": [ + { + "source": "source", + "uids": [ + { + "id": "1", + "atype": 1, + "ext": {} + }, + { + "id": "1", + "atype": 1, + "ext": {} + } + ], + "ext": {} + } + ] + }, + "source": { + "schain": { + "complete": 1, + "nodes": [ + { + "asi": "whatever.com", + "sid": "1234", + "rid": "123-456-7890", + "hp": 1 + } + ], + "ver": "2.0" + } + }, + "ext": { + "prebid": { + "cache": { + "bids": {} + }, + "channel": { + "name": "amp", + "version": "" + }, + "targeting": { + "pricegranularity": { + "precision": 2, + "ranges": [ + { + "min": 0, + "max": 20, + "increment": 0.1 + } + ] + }, + "includewinners": true, + "includebidderkeys": true, + "mediatypepricegranularity": {} + } + } + } + }, + "expectedMockBidderRequests": { + "appnexus": { + "id": "b9c97a4b-cbc4-483d-b2c4-58a19ed5cfc5", + "site": { + "page": "prebid.org", + "ext": { + "amp": 1 + } + }, + "device": { + "ip": "192.0.2.1" + }, + "at": 1, + "imp": [ + { + "id": "/19968336/header-bid-tag-0", + "banner": { + "format": [ + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": 12883451 + }, + "prebid": { + "is_rewarded_inventory": 1 + } + }, + "secure": 1 + } + ], + "regs": { + "ext": { + "gdpr": 1, + "us_privacy": "1YYY" + } + }, + "user": { + "ext": { + "consent": "some-consent-string", + "eids": [ + { + "source": "source", + "uids": [ + { + "id": "1", + "atype": 1, + "ext": {} + }, + { + "id": "1", + "atype": 1, + "ext": {} + } + ], + "ext": {} + } + ] + } + }, + "source": { + "ext": { + "schain": { + "complete": 1, + "nodes": [ + { + "asi": "whatever.com", + "sid": "1234", + "rid": "123-456-7890", + "hp": 1 + } + ], + "ver": "2.0" + } + } + }, + "ext": { + "prebid": { + "channel": { + "name": "amp", + "version": "" + } + } + } + } + }, + "expectedAmpResponse": { + "targeting": { + "hb_bidder": "appnexus", + "hb_bidder_appnexus": "appnexus", + "hb_cache_host": "www.pbcserver.com", + "hb_cache_host_appnex": "www.pbcserver.com", + "hb_cache_id": "0", + "hb_cache_id_appnexus": "0", + "hb_cache_path": "/pbcache/endpoint", + "hb_cache_path_appnex": "/pbcache/endpoint", + "hb_pb": "15.00", + "hb_pb_appnexus": "15.00" + }, + "ortb2": { + "ext": { + "warnings": { + "general": [ + { + "code": 10002, + "message": "debug turned off for account" + } + ] + } + } + } + }, + "expectedReturnCode": 200 +} \ No newline at end of file diff --git a/endpoints/openrtb2/sample-requests/blacklisted/blacklisted-app.json b/endpoints/openrtb2/sample-requests/blocked/blocked-app.json similarity index 96% rename from endpoints/openrtb2/sample-requests/blacklisted/blacklisted-app.json rename to endpoints/openrtb2/sample-requests/blocked/blocked-app.json index 120fcec08f4..88e0ed43496 100644 --- a/endpoints/openrtb2/sample-requests/blacklisted/blacklisted-app.json +++ b/endpoints/openrtb2/sample-requests/blocked/blocked-app.json @@ -1,7 +1,7 @@ { - "description": "This is a perfectly valid request except that it comes from a blacklisted App", + "description": "This is a perfectly valid request except that it comes from a blocked app", "config": { - "blacklistedApps": ["spam_app"] + "blockedApps": ["spam_app"] }, "mockBidRequest": { "id": "some-request-id", diff --git a/endpoints/openrtb2/sample-requests/disabled/good/partial.json b/endpoints/openrtb2/sample-requests/disabled/good/partial.json index 01b6177fb26..0918b67bdc0 100644 --- a/endpoints/openrtb2/sample-requests/disabled/good/partial.json +++ b/endpoints/openrtb2/sample-requests/disabled/good/partial.json @@ -43,7 +43,7 @@ "openx": { "unit": "539439964", "delDomain": "se-demo-d.openx.net", - "customFloor": 0.1, + "customFloor": "0.5", "customParams": {"foo": "bar"} } } diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/regs-ext-gdpr-string.json b/endpoints/openrtb2/sample-requests/invalid-whole/regs-ext-gdpr-string.json deleted file mode 100644 index dc15410a290..00000000000 --- a/endpoints/openrtb2/sample-requests/invalid-whole/regs-ext-gdpr-string.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "description": "Invalid GDPR value in regs field", - "mockBidRequest": { - "id": "b9c97a4b-cbc4-483d-b2c4-58a19ed5cfc5", - "site": { - "page": "prebid.org", - "publisher": { - "id": "a3de7af2-a86a-4043-a77b-c7e86744155e" - } - }, - "source": { - "tid": "b9c97a4b-cbc4-483d-b2c4-58a19ed5cfc5" - }, - "tmax": 1000, - "imp": [ - { - "id": "/19968336/header-bid-tag-0", - "ext": { - "appnexus": { - "placementId": 12883451 - } - }, - "banner": { - "format": [ - { - "w": 300, - "h": 250 - }, - { - "w": 300, - "h": 300 - } - ] - } - } - ], - "regs": { - "ext": { - "gdpr": "foo" - } - }, - "user": { - "ext": {} - } - }, - "expectedReturnCode": 400, - "expectedErrorMessage": "Invalid request: request.regs.ext is invalid: gdpr must be an integer\n" -} diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/regs-ext-malformed.json b/endpoints/openrtb2/sample-requests/invalid-whole/regs-ext-malformed.json index 7ab2631b701..4a513f703b1 100644 --- a/endpoints/openrtb2/sample-requests/invalid-whole/regs-ext-malformed.json +++ b/endpoints/openrtb2/sample-requests/invalid-whole/regs-ext-malformed.json @@ -42,5 +42,5 @@ } }, "expectedReturnCode": 400, - "expectedErrorMessage": "Invalid request: request.regs.ext is invalid: expect { or n, but found " + "expectedErrorMessage": "Invalid request: req.regs.ext is invalid: expect { or n, but found " } diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/regs-ext-gdpr-invalid.json b/endpoints/openrtb2/sample-requests/invalid-whole/regs-gdpr-invalid.json similarity index 86% rename from endpoints/openrtb2/sample-requests/invalid-whole/regs-ext-gdpr-invalid.json rename to endpoints/openrtb2/sample-requests/invalid-whole/regs-gdpr-invalid.json index 03e789eef86..40b7281d572 100644 --- a/endpoints/openrtb2/sample-requests/invalid-whole/regs-ext-gdpr-invalid.json +++ b/endpoints/openrtb2/sample-requests/invalid-whole/regs-gdpr-invalid.json @@ -35,14 +35,12 @@ } ], "regs": { - "ext": { - "gdpr": 2 - } + "gdpr": 2 }, "user": { "ext": {} } }, "expectedReturnCode": 400, - "expectedErrorMessage": "Invalid request: request.regs.ext.gdpr must be either 0 or 1\n" + "expectedErrorMessage": "Invalid request: request.regs.gdpr must be either 0 or 1\n" } diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-eids-uids-id-empty.json b/endpoints/openrtb2/sample-requests/invalid-whole/user-eids-source-empty.json similarity index 63% rename from endpoints/openrtb2/sample-requests/invalid-whole/user-ext-eids-uids-id-empty.json rename to endpoints/openrtb2/sample-requests/invalid-whole/user-eids-source-empty.json index 910e9650d75..902a2d9c1b6 100644 --- a/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-eids-uids-id-empty.json +++ b/endpoints/openrtb2/sample-requests/invalid-whole/user-eids-source-empty.json @@ -1,5 +1,5 @@ { - "description": "Bid request where a request.user.ext.eids.uids array element is missing its id field", + "description": "Bid request with user.eids array element that does not contain source field", "mockBidRequest": { "id": "anyRequestID", "site": { @@ -29,14 +29,13 @@ }], "tmax": 1000, "user": { - "ext": { - "eids": [{ - "source": "source1", - "uids": [{}] + "eids": [{ + "uids": [{ + "id": "A" }] - } + }] } }, "expectedReturnCode": 400, - "expectedErrorMessage": "Invalid request: request.user.ext.eids[0].uids[0] missing required field: \"id\"\n" + "expectedErrorMessage": "Invalid request: request.user.eids[0] missing required field: \"source\"\n" } \ No newline at end of file diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-eids-source-empty.json b/endpoints/openrtb2/sample-requests/invalid-whole/user-eids-uids-id-empty.json similarity index 62% rename from endpoints/openrtb2/sample-requests/invalid-whole/user-ext-eids-source-empty.json rename to endpoints/openrtb2/sample-requests/invalid-whole/user-eids-uids-id-empty.json index 3a451ecbd76..c8eb07aa335 100644 --- a/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-eids-source-empty.json +++ b/endpoints/openrtb2/sample-requests/invalid-whole/user-eids-uids-id-empty.json @@ -1,5 +1,5 @@ { - "description": "Bid request with user.ext.eids array element array element that does not contain source field", + "description": "Bid request where a request.user.eids.uids array element is missing its id field", "mockBidRequest": { "id": "anyRequestID", "site": { @@ -29,15 +29,12 @@ }], "tmax": 1000, "user": { - "ext": { - "eids": [{ - "uids": [{ - "id": "A" - }] - }] - } + "eids": [{ + "source": "source1", + "uids": [{}] + }] } }, "expectedReturnCode": 400, - "expectedErrorMessage": "Invalid request: request.user.ext.eids[0] missing required field: \"source\"\n" + "expectedErrorMessage": "Invalid request: request.user.eids[0].uids[0] missing required field: \"id\"\n" } \ No newline at end of file diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-eids-uids-missing.json b/endpoints/openrtb2/sample-requests/invalid-whole/user-eids-uids-missing.json similarity index 70% rename from endpoints/openrtb2/sample-requests/invalid-whole/user-ext-eids-uids-missing.json rename to endpoints/openrtb2/sample-requests/invalid-whole/user-eids-uids-missing.json index eed386b4c7d..3e55c33b849 100644 --- a/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-eids-uids-missing.json +++ b/endpoints/openrtb2/sample-requests/invalid-whole/user-eids-uids-missing.json @@ -1,5 +1,5 @@ { - "description": "Bid request with user.ext.eids array element array element that does not contain uids", + "description": "Bid request with user.eids array element array element that does not contain uids", "mockBidRequest": { "id": "b9c97a4b-cbc4-483d-b2c4-58a19ed5cfc5", "site": { @@ -37,13 +37,11 @@ } }, "user": { - "ext": { - "eids": [{ - "source": "source1" - }] - } + "eids": [{ + "source": "source1" + }] } }, "expectedReturnCode": 400, - "expectedErrorMessage": "Invalid request: request.user.ext.eids[0].uids must contain at least one element or be undefined\n" + "expectedErrorMessage": "Invalid request: request.user.eids[0].uids must contain at least one element or be undefined\n" } \ No newline at end of file diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-consent-int.json b/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-consent-int.json index af04627c3a9..222ffb993b7 100644 --- a/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-consent-int.json +++ b/endpoints/openrtb2/sample-requests/invalid-whole/user-ext-consent-int.json @@ -46,5 +46,5 @@ } }, "expectedReturnCode": 400, - "expectedErrorMessage": "Invalid request: request.user.ext object is not valid: expects \" or n, but found 1" + "expectedErrorMessage": "Invalid request: req.user.ext is invalid: expects \" or n, but found 1" } diff --git a/endpoints/openrtb2/sample-requests/invalid-whole/user-gdpr-consent-invalid.json b/endpoints/openrtb2/sample-requests/invalid-whole/user-gdpr-consent-invalid.json index b710d589ea5..ae9d72c8682 100644 --- a/endpoints/openrtb2/sample-requests/invalid-whole/user-gdpr-consent-invalid.json +++ b/endpoints/openrtb2/sample-requests/invalid-whole/user-gdpr-consent-invalid.json @@ -41,5 +41,5 @@ } }, "expectedReturnCode": 400, - "expectedErrorMessage": "Invalid request: request.user.ext object is not valid: expects \" or n, but found 2" + "expectedErrorMessage": "Invalid request: req.user.ext is invalid: expects \" or n, but found 2" } diff --git a/endpoints/openrtb2/sample-requests/valid-whole/exemplary/device-sua.json b/endpoints/openrtb2/sample-requests/valid-whole/exemplary/device-sua.json new file mode 100644 index 00000000000..0f85f904166 --- /dev/null +++ b/endpoints/openrtb2/sample-requests/valid-whole/exemplary/device-sua.json @@ -0,0 +1,100 @@ +{ + "description": "Bid request defines an valid request.device.sua value", + "config": { + "mockBidders": [ + { + "bidderName": "appnexus", + "currency": "USD", + "price": 0.00 + } + ] + }, + "mockBidRequest": { + "id": "some-request-id", + "site": { + "page": "prebid.org", + "publisher": { + "id": "a3de7af2-a86a-4043-a77b-c7e86744155e" + } + }, + "tmax": 1000, + "imp": [ + { + "id": "some-impression-id", + "ext": { + "appnexus": { + "placementId": 12883451 + } + }, + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 300 + } + ] + } + } + ], + "device": { + "ua": "Mozilla", + "geo": { + "lat": 123.456, + "lon": 678.90, + "zip": "90210" + }, + "sua": { + "browsers": [ + { + "brand": "MS", + "ext": {} + }, + { + "brand": "MS", + "ext": {} + } + ], + "platform": { + "brand": "MS", + "ext": {} + }, + "model": "mac" + }, + "dnt": 1, + "lmt": 1 + } + }, + "expectedBidResponse": { + "id": "some-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "appnexus-bid", + "impid": "some-impression-id", + "price": 0, + "ext": { + "origbidcpm": 0, + "origbidcur": "USD", + "prebid": { + "meta": { + "adaptercode": "appnexus" + }, + "type": "banner" + } + } + } + ], + "seat": "appnexus" + } + ], + "bidid": "test bid id", + "cur": "USD", + "nbr": 0 + }, + "expectedReturnCode": 200 +} diff --git a/endpoints/openrtb2/sample-requests/valid-whole/exemplary/ortb-2.5-to-2.6-upconvert.json b/endpoints/openrtb2/sample-requests/valid-whole/exemplary/ortb-2.5-to-2.6-upconvert.json new file mode 100644 index 00000000000..3ff235c4b30 --- /dev/null +++ b/endpoints/openrtb2/sample-requests/valid-whole/exemplary/ortb-2.5-to-2.6-upconvert.json @@ -0,0 +1,393 @@ +{ + "description": "Request with all 2.5 ext fields that were moved into 2.6 ortb fields", + "config": { + "mockBidders": [ + { + "bidderName": "appnexus", + "currency": "USD", + "price": 15 + }, + { + "bidderName": "rubicon", + "currency": "USD", + "price": 1.00 + } + ], + "bidderInfoOverrides": { + "appnexus": { + "openrtb": { + "version": "2.5" + } + }, + "rubicon": { + "openrtb": { + "version": "2.6" + } + } + } + }, + "mockBidRequest": { + "id": "some-request-id", + "site": { + "page": "prebid.org" + }, + "imp": [ + { + "id": "some-impression-id", + "banner": { + "format": [ + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "prebid": { + "bidder": { + "appnexus": { + "placementId": 12883451 + }, + "rubicon": { + "accountId": 1, + "siteId": 2, + "zoneId": 3 + } + }, + "is_rewarded_inventory": 1 + } + } + } + ], + "regs": { + "ext": { + "gdpr": 1, + "us_privacy": "1YYY" + } + }, + "user": { + "ext": { + "consent": "some-consent-string", + "eids": [ + { + "source": "source", + "uids": [ + { + "id": "1", + "atype": 1, + "ext": {} + }, + { + "id": "1", + "atype": 1, + "ext": {} + } + ], + "ext": {} + } + ] + } + }, + "source": { + "ext": { + "schain": { + "complete": 1, + "nodes": [ + { + "asi": "whatever.com", + "sid": "1234", + "rid": "123-456-7890", + "hp": 1 + } + ], + "ver": "2.0" + } + } + }, + "ext": {} + }, + "expectedValidatedBidRequest": { + "id": "some-request-id", + "site": { + "page": "prebid.org", + "ext": { + "amp": 0 + } + }, + "at": 1, + "device": { + "ip": "192.0.2.1" + }, + "imp": [ + { + "id": "some-impression-id", + "banner": { + "format": [ + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "prebid": { + "bidder": { + "appnexus": { + "placementId": 12883451 + }, + "rubicon": { + "accountId": 1, + "siteId": 2, + "zoneId": 3 + } + } + } + }, + "secure": 1, + "rwdd": 1 + } + ], + "regs": { + "gdpr": 1, + "us_privacy": "1YYY" + }, + "user": { + "consent": "some-consent-string", + "eids": [ + { + "source": "source", + "uids": [ + { + "id": "1", + "atype": 1, + "ext": {} + }, + { + "id": "1", + "atype": 1, + "ext": {} + } + ], + "ext": {} + } + ] + }, + "source": { + "schain": { + "complete": 1, + "nodes": [ + { + "asi": "whatever.com", + "sid": "1234", + "rid": "123-456-7890", + "hp": 1 + } + ], + "ver": "2.0" + } + } + }, + "expectedMockBidderRequests": { + "appnexus": { + "id": "some-request-id", + "site": { + "page": "prebid.org", + "ext": { + "amp": 0 + } + }, + "at": 1, + "device": { + "ip": "192.0.2.1" + }, + "imp": [ + { + "id": "some-impression-id", + "banner": { + "format": [ + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": 12883451 + }, + "prebid": { + "is_rewarded_inventory": 1 + } + }, + "secure": 1 + }], + "regs": { + "ext": { + "gdpr": 1, + "us_privacy": "1YYY" + } + }, + "source": { + "ext": { + "schain": { + "complete": 1, + "nodes": [ + { + "asi": "whatever.com", + "sid": "1234", + "rid": "123-456-7890", + "hp": 1 + } + ], + "ver": "2.0" + } + } + }, + "user": { + "ext": { + "consent": "some-consent-string", + "eids": [ + { + "source": "source", + "uids": [ + { + "id": "1", + "atype": 1, + "ext": {} + }, + { + "id": "1", + "atype": 1, + "ext": {} + } + ], + "ext": {} + } + ] + } + } + }, + "rubicon": { + "id": "some-request-id", + "site": { + "page": "prebid.org", + "ext": { + "amp": 0 + } + }, + "at": 1, + "device": { + "ip": "192.0.2.1" + }, + "imp": [ + { + "id": "some-impression-id", + "banner": { + "format": [ + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "accountId": 1, + "siteId": 2, + "zoneId": 3 + } + }, + "secure": 1, + "rwdd": 1 + }], + "regs": { + "gdpr": 1, + "us_privacy": "1YYY" + }, + "source": { + "schain": { + "complete": 1, + "nodes": [ + { + "asi": "whatever.com", + "sid": "1234", + "rid": "123-456-7890", + "hp": 1 + } + ], + "ver": "2.0" + } + }, + "user": { + "consent": "some-consent-string", + "eids": [ + { + "source": "source", + "uids": [ + { + "id": "1", + "atype": 1, + "ext": {} + }, + { + "id": "1", + "atype": 1, + "ext": {} + } + ], + "ext": {} + } + ] + } + } + }, + "expectedBidResponse": { + "id": "some-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "appnexus-bid", + "impid": "some-impression-id", + "price": 15, + "ext": { + "origbidcpm": 15, + "origbidcur": "USD", + "prebid": { + "meta": { + "adaptercode": "appnexus" + }, + "type": "banner" + } + } + } + ], + "seat": "appnexus" + }, + { + "bid": [ + { + "id": "rubicon-bid", + "impid": "some-impression-id", + "price": 1.00, + "ext": { + "origbidcpm": 1.00, + "origbidcur": "USD", + "prebid": { + "meta": { + "adaptercode": "rubicon" + }, + "type": "banner" + } + } + } + ], + "seat": "rubicon" + } + ], + "bidid": "test-bid-id", + "cur": "USD", + "nbr": 0 + }, + "expectedReturnCode": 200 +} \ No newline at end of file diff --git a/endpoints/openrtb2/sample-requests/valid-whole/exemplary/ortb-2.6-to-2.5-downconvert.json b/endpoints/openrtb2/sample-requests/valid-whole/exemplary/ortb-2.6-to-2.5-downconvert.json new file mode 100644 index 00000000000..28ba8a707e0 --- /dev/null +++ b/endpoints/openrtb2/sample-requests/valid-whole/exemplary/ortb-2.6-to-2.5-downconvert.json @@ -0,0 +1,417 @@ +{ + "description": "Request with all 2.5 ext fields that were moved into 2.6 ortb fields", + "config": { + "mockBidders": [ + { + "bidderName": "appnexus", + "currency": "USD", + "price": 15 + }, + { + "bidderName": "rubicon", + "currency": "USD", + "price": 1.00 + } + ], + "bidderInfoOverrides": { + "appnexus": { + "openrtb": { + "version": "2.5" + } + }, + "rubicon": { + "openrtb": { + "version": "2.6" + } + } + } + }, + "mockBidRequest": { + "id": "some-request-id", + "site": { + "page": "prebid.org", + "inventorypartnerdomain": "any-domain" + }, + "imp": [ + { + "id": "some-impression-id", + "banner": { + "format": [ + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "prebid": { + "bidder": { + "appnexus": { + "placementId": 12883451 + }, + "rubicon": { + "accountId": 1, + "siteId": 2, + "zoneId": 3 + } + }, + "is_rewarded_inventory": 1 + } + }, + "refresh": { + "count": 10 + } + } + ], + "regs": { + "ext": { + "gdpr": 1, + "us_privacy": "1YYY" + } + }, + "user": { + "ext": { + "consent": "some-consent-string", + "eids": [ + { + "source": "source", + "uids": [ + { + "id": "1", + "atype": 1, + "ext": {} + }, + { + "id": "1", + "atype": 1, + "ext": {} + } + ], + "ext": {} + } + ] + } + }, + "source": { + "ext": { + "schain": { + "complete": 1, + "nodes": [ + { + "asi": "whatever.com", + "sid": "1234", + "rid": "123-456-7890", + "hp": 1 + } + ], + "ver": "2.0" + } + } + }, + "ext": {}, + "cattax": 20, + "acat": ["any-acat"] + }, + "expectedValidatedBidRequest": { + "id": "some-request-id", + "site": { + "page": "prebid.org", + "inventorypartnerdomain": "any-domain", + "ext": { + "amp": 0 + } + }, + "at": 1, + "device": { + "ip": "192.0.2.1" + }, + "imp": [ + { + "id": "some-impression-id", + "banner": { + "format": [ + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "prebid": { + "bidder": { + "appnexus": { + "placementId": 12883451 + }, + "rubicon": { + "accountId": 1, + "siteId": 2, + "zoneId": 3 + } + } + } + }, + "secure": 1, + "rwdd": 1, + "refresh": { + "count": 10 + } + } + ], + "regs": { + "gdpr": 1, + "us_privacy": "1YYY" + }, + "user": { + "consent": "some-consent-string", + "eids": [ + { + "source": "source", + "uids": [ + { + "id": "1", + "atype": 1, + "ext": {} + }, + { + "id": "1", + "atype": 1, + "ext": {} + } + ], + "ext": {} + } + ] + }, + "source": { + "schain": { + "complete": 1, + "nodes": [ + { + "asi": "whatever.com", + "sid": "1234", + "rid": "123-456-7890", + "hp": 1 + } + ], + "ver": "2.0" + } + }, + "cattax": 20, + "acat": ["any-acat"] + }, + "expectedMockBidderRequests": { + "appnexus": { + "id": "some-request-id", + "site": { + "page": "prebid.org", + "inventorypartnerdomain": "any-domain", + "ext": { + "amp": 0 + } + }, + "at": 1, + "device": { + "ip": "192.0.2.1" + }, + "imp": [ + { + "id": "some-impression-id", + "banner": { + "format": [ + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": 12883451 + }, + "prebid": { + "is_rewarded_inventory": 1 + } + }, + "refresh": { + "count": 10 + }, + "secure": 1 + }], + "regs": { + "ext": { + "gdpr": 1, + "us_privacy": "1YYY" + } + }, + "source": { + "ext": { + "schain": { + "complete": 1, + "nodes": [ + { + "asi": "whatever.com", + "sid": "1234", + "rid": "123-456-7890", + "hp": 1 + } + ], + "ver": "2.0" + } + } + }, + "user": { + "ext": { + "consent": "some-consent-string", + "eids": [ + { + "source": "source", + "uids": [ + { + "id": "1", + "atype": 1, + "ext": {} + }, + { + "id": "1", + "atype": 1, + "ext": {} + } + ], + "ext": {} + } + ] + } + }, + "cattax": 20, + "acat": ["any-acat"] + }, + "rubicon": { + "id": "some-request-id", + "site": { + "page": "prebid.org", + "inventorypartnerdomain": "any-domain", + "ext": { + "amp": 0 + } + }, + "at": 1, + "device": { + "ip": "192.0.2.1" + }, + "imp": [ + { + "id": "some-impression-id", + "banner": { + "format": [ + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "accountId": 1, + "siteId": 2, + "zoneId": 3 + } + }, + "secure": 1, + "refresh": { + "count": 10 + }, + "rwdd": 1 + }], + "regs": { + "gdpr": 1, + "us_privacy": "1YYY" + }, + "source": { + "schain": { + "complete": 1, + "nodes": [ + { + "asi": "whatever.com", + "sid": "1234", + "rid": "123-456-7890", + "hp": 1 + } + ], + "ver": "2.0" + } + }, + "user": { + "consent": "some-consent-string", + "eids": [ + { + "source": "source", + "uids": [ + { + "id": "1", + "atype": 1, + "ext": {} + }, + { + "id": "1", + "atype": 1, + "ext": {} + } + ], + "ext": {} + } + ] + }, + "cattax": 20, + "acat": ["any-acat"] + } + }, + "expectedBidResponse": { + "id": "some-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "appnexus-bid", + "impid": "some-impression-id", + "price": 15, + "ext": { + "origbidcpm": 15, + "origbidcur": "USD", + "prebid": { + "meta": { + "adaptercode": "appnexus" + }, + "type": "banner" + } + } + } + ], + "seat": "appnexus" + }, + { + "bid": [ + { + "id": "rubicon-bid", + "impid": "some-impression-id", + "price": 1.00, + "ext": { + "origbidcpm": 1.00, + "origbidcur": "USD", + "prebid": { + "meta": { + "adaptercode": "rubicon" + }, + "type": "banner" + } + } + } + ], + "seat": "rubicon" + } + ], + "bidid": "test-bid-id", + "cur": "USD", + "nbr": 0 + }, + "expectedReturnCode": 200 +} \ No newline at end of file diff --git a/endpoints/openrtb2/sample-requests/valid-whole/exemplary/source-schain.json b/endpoints/openrtb2/sample-requests/valid-whole/exemplary/source-schain.json new file mode 100644 index 00000000000..c25f7ca1c47 --- /dev/null +++ b/endpoints/openrtb2/sample-requests/valid-whole/exemplary/source-schain.json @@ -0,0 +1,91 @@ +{ + "description": "Bid request defines a valid request.source.schain.nodes value", + "config": { + "mockBidders": [ + { + "bidderName": "appnexus", + "currency": "USD", + "price": 0.00 + } + ] + }, + "mockBidRequest": { + "id": "some-request-id", + "site": { + "page": "prebid.org", + "publisher": { + "id": "a3de7af2-a86a-4043-a77b-c7e86744155e" + } + }, + "tmax": 1000, + "imp": [ + { + "id": "some-impression-id", + "ext": { + "appnexus": { + "placementId": 12883451 + } + }, + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 300 + } + ] + } + } + ], + "source": { + "fd": 1, + "tid": "abc123", + "pchain": "tag_placement", + "schain": { + "complete": 1, + "nodes": [ + { + "asi": "asi", + "sid": "sid", + "rid": "rid", + "ext": {} + } + ], + "ver": "ver", + "ext": {} + } + } + }, + "expectedBidResponse": { + "id": "some-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "appnexus-bid", + "impid": "some-impression-id", + "price": 0, + "ext": { + "origbidcpm": 0, + "origbidcur": "USD", + "prebid": { + "meta": { + "adaptercode": "appnexus" + }, + "type": "banner" + } + } + } + ], + "seat": "appnexus" + } + ], + "bidid": "test bid id", + "cur": "USD", + "nbr": 0 + }, + "expectedReturnCode": 200 +} diff --git a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/gdpr-conflict.json b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/gdpr-conflict.json index 3d6a0774b9d..9565e41af1f 100644 --- a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/gdpr-conflict.json +++ b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/gdpr-conflict.json @@ -37,10 +37,7 @@ "regs": { "gpp": "DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1NYN", "gpp_sid": [6], - "gdpr": 1, - "ext": { - "us_privacy": "1YYY" - } + "gdpr": 1 }, "user": { "consent": "CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA", diff --git a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/gdpr-conflict2.json b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/gdpr-conflict2.json index 2102a8cd44b..54477ed0986 100644 --- a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/gdpr-conflict2.json +++ b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/gdpr-conflict2.json @@ -37,10 +37,7 @@ "regs": { "gpp": "DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1NYN", "gpp_sid": [2,6], - "gdpr": 1, - "ext": { - "us_privacy": "1YYY" - } + "gdpr": 1 }, "user": { "consent": "Invalid", diff --git a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/us-privacy-invalid.json b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/us-privacy-invalid.json index 2ccdfb7ccdc..df2c426d0c3 100644 --- a/endpoints/openrtb2/sample-requests/valid-whole/supplementary/us-privacy-invalid.json +++ b/endpoints/openrtb2/sample-requests/valid-whole/supplementary/us-privacy-invalid.json @@ -35,9 +35,7 @@ } ], "regs": { - "ext": { - "us_privacy": "{invalid}" - } + "us_privacy": "{invalid}" }, "user": { "ext": {} diff --git a/endpoints/openrtb2/test_utils.go b/endpoints/openrtb2/test_utils.go index b2f2826739f..e869ded80b8 100644 --- a/endpoints/openrtb2/test_utils.go +++ b/endpoints/openrtb2/test_utils.go @@ -18,29 +18,29 @@ import ( "github.com/julienschmidt/httprouter" "github.com/prebid/openrtb/v20/openrtb2" "github.com/prebid/openrtb/v20/openrtb3" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/analytics" - analyticsBuild "github.com/prebid/prebid-server/v2/analytics/build" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/currency" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/exchange" - "github.com/prebid/prebid-server/v2/experiment/adscert" - "github.com/prebid/prebid-server/v2/gdpr" - "github.com/prebid/prebid-server/v2/hooks" - "github.com/prebid/prebid-server/v2/hooks/hookexecution" - "github.com/prebid/prebid-server/v2/hooks/hookstage" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/metrics" - metricsConfig "github.com/prebid/prebid-server/v2/metrics/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/ortb" - pbc "github.com/prebid/prebid-server/v2/prebid_cache_client" - "github.com/prebid/prebid-server/v2/stored_requests" - "github.com/prebid/prebid-server/v2/stored_requests/backends/empty_fetcher" - "github.com/prebid/prebid-server/v2/util/iputil" - "github.com/prebid/prebid-server/v2/util/jsonutil" - "github.com/prebid/prebid-server/v2/util/uuidutil" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/analytics" + analyticsBuild "github.com/prebid/prebid-server/v3/analytics/build" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/currency" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/exchange" + "github.com/prebid/prebid-server/v3/experiment/adscert" + "github.com/prebid/prebid-server/v3/gdpr" + "github.com/prebid/prebid-server/v3/hooks" + "github.com/prebid/prebid-server/v3/hooks/hookexecution" + "github.com/prebid/prebid-server/v3/hooks/hookstage" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/metrics" + metricsConfig "github.com/prebid/prebid-server/v3/metrics/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/ortb" + pbc "github.com/prebid/prebid-server/v3/prebid_cache_client" + "github.com/prebid/prebid-server/v3/stored_requests" + "github.com/prebid/prebid-server/v3/stored_requests/backends/empty_fetcher" + "github.com/prebid/prebid-server/v3/util/iputil" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/uuidutil" jsonpatch "gopkg.in/evanphx/json-patch.v4" ) @@ -64,15 +64,16 @@ const ( type testCase struct { // Common - endpointType int - Description string `json:"description"` - Config *testConfigValues `json:"config"` - BidRequest json.RawMessage `json:"mockBidRequest"` - ExpectedValidatedBidReq json.RawMessage `json:"expectedValidatedBidRequest"` - ExpectedReturnCode int `json:"expectedReturnCode,omitempty"` - ExpectedErrorMessage string `json:"expectedErrorMessage"` - Query string `json:"query"` - planBuilder hooks.ExecutionPlanBuilder + endpointType int + Description string `json:"description"` + Config *testConfigValues `json:"config"` + BidRequest json.RawMessage `json:"mockBidRequest"` + ExpectedValidatedBidReq json.RawMessage `json:"expectedValidatedBidRequest"` + ExpectedMockBidderRequests map[string]json.RawMessage `json:"expectedMockBidderRequests"` + ExpectedReturnCode int `json:"expectedReturnCode,omitempty"` + ExpectedErrorMessage string `json:"expectedErrorMessage"` + Query string `json:"query"` + planBuilder hooks.ExecutionPlanBuilder // "/openrtb2/auction" endpoint JSON test info ExpectedBidResponse json.RawMessage `json:"expectedBidResponse"` @@ -84,13 +85,20 @@ type testCase struct { } type testConfigValues struct { - AccountRequired bool `json:"accountRequired"` - AliasJSON string `json:"aliases"` - BlacklistedApps []string `json:"blacklistedApps"` - DisabledAdapters []string `json:"disabledAdapters"` - CurrencyRates map[string]map[string]float64 `json:"currencyRates"` - MockBidders []mockBidderHandler `json:"mockBidders"` - RealParamsValidator bool `json:"realParamsValidator"` + AccountRequired bool `json:"accountRequired"` + AliasJSON string `json:"aliases"` + BlockedApps []string `json:"blockedApps"` + DisabledAdapters []string `json:"disabledAdapters"` + CurrencyRates map[string]map[string]float64 `json:"currencyRates"` + MockBidders []mockBidderHandler `json:"mockBidders"` + RealParamsValidator bool `json:"realParamsValidator"` + BidderInfos map[string]bidderInfoOverrides `json:"bidderInfoOverrides"` +} +type bidderInfoOverrides struct { + OpenRTB *OpenRTBInfo `json:"openrtb"` +} +type OpenRTBInfo struct { + Version string `json:"version"` } type brokenExchange struct{} @@ -1002,6 +1010,7 @@ type mockAdapter struct { mockServerURL string Server config.Server seat string + requestData [][]byte } func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { @@ -1012,7 +1021,7 @@ func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server co return adapter, nil } -func (a mockAdapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { +func (a *mockAdapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { var requests []*adapters.RequestData var errors []error @@ -1032,11 +1041,12 @@ func (a mockAdapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *ada Body: requestJSON, } requests = append(requests, requestData) + a.requestData = append(a.requestData, requestData.Body) } return requests, errors } -func (a mockAdapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { +func (a *mockAdapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { if responseData.StatusCode != http.StatusOK { switch responseData.StatusCode { case http.StatusNoContent: @@ -1159,27 +1169,40 @@ func parseTestData(fileData []byte, testFile string) (testCase, error) { return parsedTestData, fmt.Errorf("Test case %s should come with either a valid expectedBidResponse or a valid expectedErrorMessage, not both.", testFile) } + // Get optional expected validated bid request + parsedTestData.ExpectedValidatedBidReq, _, _, err = jsonparser.Get(fileData, "expectedValidatedBidRequest") + + // Get optional expected mock bidder requests + jsonExpectedMockBidderRequests, _, _, err := jsonparser.Get(fileData, "expectedMockBidderRequests") + if err == nil && jsonExpectedMockBidderRequests != nil { + parsedTestData.ExpectedMockBidderRequests = make(map[string]json.RawMessage) + if err = jsonutil.UnmarshalValid(jsonExpectedMockBidderRequests, &parsedTestData.ExpectedMockBidderRequests); err != nil { + return parsedTestData, fmt.Errorf("Error unmarshaling root.expectedMockBidderRequests from file %s. Desc: %v.", testFile, err) + } + } + parsedTestData.ExpectedReturnCode = int(parsedReturnCode) return parsedTestData, nil } -func (tc *testConfigValues) getBlacklistedAppMap() map[string]bool { - var blacklistedAppMap map[string]bool +func (tc *testConfigValues) getBlockedAppLookup() map[string]bool { + var blockedAppLookup map[string]bool - if len(tc.BlacklistedApps) > 0 { - blacklistedAppMap = make(map[string]bool, len(tc.BlacklistedApps)) - for _, app := range tc.BlacklistedApps { - blacklistedAppMap[app] = true + if len(tc.BlockedApps) > 0 { + blockedAppLookup = make(map[string]bool, len(tc.BlockedApps)) + for _, app := range tc.BlockedApps { + blockedAppLookup[app] = true } } - return blacklistedAppMap + return blockedAppLookup } // exchangeTestWrapper is a wrapper that asserts the openrtb2 bid request just before the HoldAuction call type exchangeTestWrapper struct { ex exchange.Exchange actualValidatedBidReq *openrtb2.BidRequest + adapters map[openrtb_ext.BidderName]exchange.AdaptedBidder } func (te *exchangeTestWrapper) HoldAuction(ctx context.Context, r *exchange.AuctionRequest, debugLog *exchange.DebugLog) (*exchange.AuctionResponse, error) { @@ -1206,7 +1229,7 @@ func buildTestExchange(testCfg *testConfigValues, adapterMap map[openrtb_ext.Bid bidderAdapter := mockAdapter{mockServerURL: bidServer.URL, seat: mockBidder.Seat} bidderName := openrtb_ext.BidderName(mockBidder.BidderName) - adapterMap[bidderName] = exchange.AdaptBidder(bidderAdapter, bidServer.Client(), &config.Configuration{}, &metricsConfig.NilMetricsEngine{}, bidderName, nil, "") + adapterMap[bidderName] = exchange.AdaptBidder(&bidderAdapter, bidServer.Client(), &config.Configuration{}, &metricsConfig.NilMetricsEngine{}, bidderName, nil, "") mockBidServersArray = append(mockBidServersArray, bidServer) } @@ -1218,6 +1241,7 @@ func buildTestExchange(testCfg *testConfigValues, adapterMap map[openrtb_ext.Bid }.Builder testExchange := exchange.NewExchange(adapterMap, + &wellBehavedCache{}, cfg, requestValidator, @@ -1233,7 +1257,8 @@ func buildTestExchange(testCfg *testConfigValues, adapterMap map[openrtb_ext.Bid ) testExchange = &exchangeTestWrapper{ - ex: testExchange, + ex: testExchange, + adapters: adapterMap, } return testExchange, mockBidServersArray @@ -1257,6 +1282,18 @@ func buildTestEndpoint(test testCase, cfg *config.Configuration) (httprouter.Han } bidderInfos, _ := config.LoadBidderInfoFromDisk("../../static/bidder-info") + for bidder, overrides := range test.Config.BidderInfos { + if bi, ok := bidderInfos[bidder]; ok { + if overrides.OpenRTB != nil && len(overrides.OpenRTB.Version) > 0 { + if bi.OpenRTB == nil { + bi.OpenRTB = &config.OpenRTBInfo{} + } + bi.OpenRTB.Version = overrides.OpenRTB.Version + bidderInfos[bidder] = bi + } + } + } + enableBidders(bidderInfos) disableBidders(test.Config.DisabledAdapters, bidderInfos) bidderMap := exchange.GetActiveBidders(bidderInfos) @@ -1429,10 +1466,10 @@ func (p *fakePermissions) BidderSyncAllowed(ctx context.Context, bidder openrtb_ return true, nil } -func (p *fakePermissions) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) (permissions gdpr.AuctionPermissions, err error) { +func (p *fakePermissions) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) gdpr.AuctionPermissions { return gdpr.AuctionPermissions{ AllowBidRequest: true, - }, nil + } } type mockPlanBuilder struct { diff --git a/endpoints/openrtb2/video_auction.go b/endpoints/openrtb2/video_auction.go index 2a9885e2731..cf18840fbd6 100644 --- a/endpoints/openrtb2/video_auction.go +++ b/endpoints/openrtb2/video_auction.go @@ -17,28 +17,28 @@ import ( "github.com/golang/glog" "github.com/julienschmidt/httprouter" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/hooks" - "github.com/prebid/prebid-server/v2/hooks/hookexecution" - "github.com/prebid/prebid-server/v2/ortb" - "github.com/prebid/prebid-server/v2/privacy" + "github.com/prebid/prebid-server/v3/hooks" + "github.com/prebid/prebid-server/v3/hooks/hookexecution" + "github.com/prebid/prebid-server/v3/ortb" + "github.com/prebid/prebid-server/v3/privacy" jsonpatch "gopkg.in/evanphx/json-patch.v4" - accountService "github.com/prebid/prebid-server/v2/account" - "github.com/prebid/prebid-server/v2/analytics" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/exchange" - "github.com/prebid/prebid-server/v2/metrics" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/prebid_cache_client" - "github.com/prebid/prebid-server/v2/stored_requests" - "github.com/prebid/prebid-server/v2/stored_requests/backends/empty_fetcher" - "github.com/prebid/prebid-server/v2/usersync" - "github.com/prebid/prebid-server/v2/util/iputil" - "github.com/prebid/prebid-server/v2/util/jsonutil" - "github.com/prebid/prebid-server/v2/util/ptrutil" - "github.com/prebid/prebid-server/v2/util/uuidutil" - "github.com/prebid/prebid-server/v2/version" + accountService "github.com/prebid/prebid-server/v3/account" + "github.com/prebid/prebid-server/v3/analytics" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/exchange" + "github.com/prebid/prebid-server/v3/metrics" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/prebid_cache_client" + "github.com/prebid/prebid-server/v3/stored_requests" + "github.com/prebid/prebid-server/v3/stored_requests/backends/empty_fetcher" + "github.com/prebid/prebid-server/v3/usersync" + "github.com/prebid/prebid-server/v3/util/iputil" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/ptrutil" + "github.com/prebid/prebid-server/v3/util/uuidutil" + "github.com/prebid/prebid-server/v3/version" ) var defaultRequestTimeout int64 = 5000 @@ -260,6 +260,11 @@ func (deps *endpointDeps) VideoAuctionEndpoint(w http.ResponseWriter, r *http.Re // all code after this line should use the bidReqWrapper instead of bidReq directly bidReqWrapper := &openrtb_ext.RequestWrapper{BidRequest: bidReq} + if err := openrtb_ext.ConvertUpTo26(bidReqWrapper); err != nil { + handleError(&labels, w, []error{err}, &vo, &debugLog) + return + } + if err := ortb.SetDefaults(bidReqWrapper); err != nil { handleError(&labels, w, errL, &vo, &debugLog) return @@ -411,9 +416,9 @@ func handleError(labels *metrics.Labels, w http.ResponseWriter, errL []error, vo var status int = http.StatusInternalServerError for _, er := range errL { erVal := errortypes.ReadCode(er) - if erVal == errortypes.BlacklistedAppErrorCode || erVal == errortypes.AccountDisabledErrorCode { + if erVal == errortypes.BlockedAppErrorCode || erVal == errortypes.AccountDisabledErrorCode { status = http.StatusServiceUnavailable - labels.RequestStatus = metrics.RequestStatusBlacklisted + labels.RequestStatus = metrics.RequestStatusBlockedApp break } else if erVal == errortypes.AcctRequiredErrorCode { status = http.StatusBadRequest @@ -813,8 +818,8 @@ func (deps *endpointDeps) validateVideoRequest(req *openrtb_ext.BidRequestVideo) errL = append(errL, err) } else if req.App != nil { if req.App.ID != "" { - if _, found := deps.cfg.BlacklistedAppMap[req.App.ID]; found { - err := &errortypes.BlacklistedApp{Message: fmt.Sprintf("Prebid-server does not process requests from App ID: %s", req.App.ID)} + if _, found := deps.cfg.BlockedAppsLookup[req.App.ID]; found { + err := &errortypes.BlockedApp{Message: fmt.Sprintf("Prebid-server does not process requests from App ID: %s", req.App.ID)} errL = append(errL, err) return errL, podErrors } diff --git a/endpoints/openrtb2/video_auction_test.go b/endpoints/openrtb2/video_auction_test.go index 55fc7fab957..79eaaab980c 100644 --- a/endpoints/openrtb2/video_auction_test.go +++ b/endpoints/openrtb2/video_auction_test.go @@ -11,21 +11,21 @@ import ( "strings" "testing" - "github.com/prebid/prebid-server/v2/analytics" - analyticsBuild "github.com/prebid/prebid-server/v2/analytics/build" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/exchange" - "github.com/prebid/prebid-server/v2/hooks" - "github.com/prebid/prebid-server/v2/metrics" - metricsConfig "github.com/prebid/prebid-server/v2/metrics/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/ortb" - "github.com/prebid/prebid-server/v2/prebid_cache_client" - "github.com/prebid/prebid-server/v2/privacy" - "github.com/prebid/prebid-server/v2/stored_requests/backends/empty_fetcher" - "github.com/prebid/prebid-server/v2/util/jsonutil" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/analytics" + analyticsBuild "github.com/prebid/prebid-server/v3/analytics/build" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/exchange" + "github.com/prebid/prebid-server/v3/hooks" + "github.com/prebid/prebid-server/v3/metrics" + metricsConfig "github.com/prebid/prebid-server/v3/metrics/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/ortb" + "github.com/prebid/prebid-server/v3/prebid_cache_client" + "github.com/prebid/prebid-server/v3/privacy" + "github.com/prebid/prebid-server/v3/stored_requests/backends/empty_fetcher" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/ptrutil" "github.com/prebid/openrtb/v20/adcom1" "github.com/prebid/openrtb/v20/openrtb2" @@ -814,15 +814,15 @@ func TestHandleError(t *testing.T) { &errortypes.AccountDisabled{}, }, wantCode: 503, - wantMetricsStatus: metrics.RequestStatusBlacklisted, + wantMetricsStatus: metrics.RequestStatusBlockedApp, }, { description: "Blocked app - return 503 with blocked metrics status", giveErrors: []error{ - &errortypes.BlacklistedApp{}, + &errortypes.BlockedApp{}, }, wantCode: 503, - wantMetricsStatus: metrics.RequestStatusBlacklisted, + wantMetricsStatus: metrics.RequestStatusBlockedApp, }, { description: "Account required error - return 400 with bad input metrics status", @@ -1091,14 +1091,11 @@ func TestCCPA(t *testing.T) { if ex.lastRequest == nil { t.Fatalf("%s: The request never made it into the exchange.", test.description) } - extRegs := &openrtb_ext.ExtRegs{} - if err := jsonutil.UnmarshalValid(ex.lastRequest.Regs.Ext, extRegs); err != nil { - t.Fatalf("%s: Failed to unmarshal reg.ext in request to the exchange: %v", test.description, err) - } + if test.expectConsentString { - assert.Len(t, extRegs.USPrivacy, 4, test.description+":consent") + assert.Len(t, ex.lastRequest.Regs.USPrivacy, 4, test.description+":consent") } else if test.expectEmptyConsent { - assert.Empty(t, extRegs.USPrivacy, test.description+":consent") + assert.Empty(t, ex.lastRequest.Regs.USPrivacy, test.description+":consent") } // Validate HTTP Response @@ -1282,6 +1279,8 @@ func (m *mockAnalyticsModule) LogAmpObject(ao *analytics.AmpObject, _ privacy.Ac func (m *mockAnalyticsModule) LogNotificationEventObject(ne *analytics.NotificationEvent, _ privacy.ActivityControl) { } +func (m *mockAnalyticsModule) Shutdown() {} + func mockDeps(t *testing.T, ex *mockExchangeVideo) *endpointDeps { return &endpointDeps{ fakeUUIDGenerator{}, diff --git a/endpoints/setuid.go b/endpoints/setuid.go index 5d91b3c8165..83587610030 100644 --- a/endpoints/setuid.go +++ b/endpoints/setuid.go @@ -12,19 +12,19 @@ import ( "github.com/julienschmidt/httprouter" gpplib "github.com/prebid/go-gpp" gppConstants "github.com/prebid/go-gpp/constants" - accountService "github.com/prebid/prebid-server/v2/account" - "github.com/prebid/prebid-server/v2/analytics" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/gdpr" - "github.com/prebid/prebid-server/v2/metrics" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/privacy" - gppPrivacy "github.com/prebid/prebid-server/v2/privacy/gpp" - "github.com/prebid/prebid-server/v2/stored_requests" - "github.com/prebid/prebid-server/v2/usersync" - "github.com/prebid/prebid-server/v2/util/httputil" - stringutil "github.com/prebid/prebid-server/v2/util/stringutil" + accountService "github.com/prebid/prebid-server/v3/account" + "github.com/prebid/prebid-server/v3/analytics" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/gdpr" + "github.com/prebid/prebid-server/v3/metrics" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/privacy" + gppPrivacy "github.com/prebid/prebid-server/v3/privacy/gpp" + "github.com/prebid/prebid-server/v3/stored_requests" + "github.com/prebid/prebid-server/v3/usersync" + "github.com/prebid/prebid-server/v3/util/httputil" + stringutil "github.com/prebid/prebid-server/v3/util/stringutil" ) const ( diff --git a/endpoints/setuid_test.go b/endpoints/setuid_test.go index d576b8a0093..78944da7c42 100644 --- a/endpoints/setuid_test.go +++ b/endpoints/setuid_test.go @@ -12,18 +12,18 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/v2/analytics" - analyticsBuild "github.com/prebid/prebid-server/v2/analytics/build" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/gdpr" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/metrics" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/usersync" + "github.com/prebid/prebid-server/v3/analytics" + analyticsBuild "github.com/prebid/prebid-server/v3/analytics/build" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/gdpr" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/metrics" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/usersync" "github.com/stretchr/testify/assert" - metricsConf "github.com/prebid/prebid-server/v2/metrics/config" + metricsConf "github.com/prebid/prebid-server/v3/metrics/config" ) func TestSetUIDEndpoint(t *testing.T) { @@ -1701,12 +1701,12 @@ func (g *fakePermsSetUID) BidderSyncAllowed(ctx context.Context, bidder openrtb_ return false, nil } -func (g *fakePermsSetUID) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) (permissions gdpr.AuctionPermissions, err error) { +func (g *fakePermsSetUID) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) gdpr.AuctionPermissions { return gdpr.AuctionPermissions{ AllowBidRequest: g.personalInfoAllowed, PassGeo: g.personalInfoAllowed, PassID: g.personalInfoAllowed, - }, nil + } } type fakeSyncer struct { diff --git a/endpoints/version.go b/endpoints/version.go index f9e07da9a0d..8eb305c3f5e 100644 --- a/endpoints/version.go +++ b/endpoints/version.go @@ -5,7 +5,7 @@ import ( "net/http" "github.com/golang/glog" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) const versionEndpointValueNotSet = "not-set" diff --git a/errortypes/code.go b/errortypes/code.go index 552beffbcb8..49cb6d4bcf9 100644 --- a/errortypes/code.go +++ b/errortypes/code.go @@ -5,7 +5,7 @@ const ( UnknownErrorCode = 999 TimeoutErrorCode = iota BadInputErrorCode - BlacklistedAppErrorCode + BlockedAppErrorCode BadServerResponseErrorCode FailedToRequestBidsErrorCode BidderTemporarilyDisabledErrorCode diff --git a/errortypes/errortypes.go b/errortypes/errortypes.go index f23e1423977..4e51847b5ea 100644 --- a/errortypes/errortypes.go +++ b/errortypes/errortypes.go @@ -59,23 +59,20 @@ func (err *BadInput) Severity() Severity { return SeverityFatal } -// BlacklistedApp should be used when a request App.ID matches an entry in the BlacklistedApps -// environment variable array -// -// These errors will be written to http.ResponseWriter before canceling execution -type BlacklistedApp struct { +// BlockedApp should be used when a request App.ID matches an entry in the BlockedApp configuration. +type BlockedApp struct { Message string } -func (err *BlacklistedApp) Error() string { +func (err *BlockedApp) Error() string { return err.Message } -func (err *BlacklistedApp) Code() int { - return BlacklistedAppErrorCode +func (err *BlockedApp) Code() int { + return BlockedAppErrorCode } -func (err *BlacklistedApp) Severity() Severity { +func (err *BlockedApp) Severity() Severity { return SeverityFatal } diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index f4a2e8ec7fa..aad457beef0 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -1,212 +1,230 @@ package exchange import ( - "github.com/prebid/prebid-server/v2/adapters" - ttx "github.com/prebid/prebid-server/v2/adapters/33across" - "github.com/prebid/prebid-server/v2/adapters/aax" - "github.com/prebid/prebid-server/v2/adapters/aceex" - "github.com/prebid/prebid-server/v2/adapters/acuityads" - "github.com/prebid/prebid-server/v2/adapters/adelement" - "github.com/prebid/prebid-server/v2/adapters/adf" - "github.com/prebid/prebid-server/v2/adapters/adgeneration" - "github.com/prebid/prebid-server/v2/adapters/adhese" - "github.com/prebid/prebid-server/v2/adapters/adkernel" - "github.com/prebid/prebid-server/v2/adapters/adkernelAdn" - "github.com/prebid/prebid-server/v2/adapters/adman" - "github.com/prebid/prebid-server/v2/adapters/admixer" - "github.com/prebid/prebid-server/v2/adapters/adnuntius" - "github.com/prebid/prebid-server/v2/adapters/adocean" - "github.com/prebid/prebid-server/v2/adapters/adoppler" - "github.com/prebid/prebid-server/v2/adapters/adot" - "github.com/prebid/prebid-server/v2/adapters/adpone" - "github.com/prebid/prebid-server/v2/adapters/adprime" - "github.com/prebid/prebid-server/v2/adapters/adquery" - "github.com/prebid/prebid-server/v2/adapters/adrino" - "github.com/prebid/prebid-server/v2/adapters/adsinteractive" - "github.com/prebid/prebid-server/v2/adapters/adtarget" - "github.com/prebid/prebid-server/v2/adapters/adtelligent" - "github.com/prebid/prebid-server/v2/adapters/adtrgtme" - "github.com/prebid/prebid-server/v2/adapters/advangelists" - "github.com/prebid/prebid-server/v2/adapters/adview" - "github.com/prebid/prebid-server/v2/adapters/adxcg" - "github.com/prebid/prebid-server/v2/adapters/adyoulike" - "github.com/prebid/prebid-server/v2/adapters/aidem" - "github.com/prebid/prebid-server/v2/adapters/aja" - "github.com/prebid/prebid-server/v2/adapters/algorix" - "github.com/prebid/prebid-server/v2/adapters/alkimi" - "github.com/prebid/prebid-server/v2/adapters/amx" - "github.com/prebid/prebid-server/v2/adapters/apacdex" - "github.com/prebid/prebid-server/v2/adapters/appnexus" - "github.com/prebid/prebid-server/v2/adapters/appush" - "github.com/prebid/prebid-server/v2/adapters/aso" - "github.com/prebid/prebid-server/v2/adapters/audienceNetwork" - "github.com/prebid/prebid-server/v2/adapters/automatad" - "github.com/prebid/prebid-server/v2/adapters/avocet" - "github.com/prebid/prebid-server/v2/adapters/axis" - "github.com/prebid/prebid-server/v2/adapters/axonix" - "github.com/prebid/prebid-server/v2/adapters/beachfront" - "github.com/prebid/prebid-server/v2/adapters/beintoo" - "github.com/prebid/prebid-server/v2/adapters/bematterfull" - "github.com/prebid/prebid-server/v2/adapters/between" - "github.com/prebid/prebid-server/v2/adapters/beyondmedia" - "github.com/prebid/prebid-server/v2/adapters/bidmachine" - "github.com/prebid/prebid-server/v2/adapters/bidmyadz" - "github.com/prebid/prebid-server/v2/adapters/bidscube" - "github.com/prebid/prebid-server/v2/adapters/bidstack" - "github.com/prebid/prebid-server/v2/adapters/bizzclick" - "github.com/prebid/prebid-server/v2/adapters/bliink" - "github.com/prebid/prebid-server/v2/adapters/blue" - "github.com/prebid/prebid-server/v2/adapters/bluesea" - "github.com/prebid/prebid-server/v2/adapters/bmtm" - "github.com/prebid/prebid-server/v2/adapters/boldwin" - "github.com/prebid/prebid-server/v2/adapters/brave" - "github.com/prebid/prebid-server/v2/adapters/bwx" - cadentaperturemx "github.com/prebid/prebid-server/v2/adapters/cadent_aperture_mx" - "github.com/prebid/prebid-server/v2/adapters/ccx" - "github.com/prebid/prebid-server/v2/adapters/coinzilla" - "github.com/prebid/prebid-server/v2/adapters/colossus" - "github.com/prebid/prebid-server/v2/adapters/compass" - "github.com/prebid/prebid-server/v2/adapters/concert" - "github.com/prebid/prebid-server/v2/adapters/connectad" - "github.com/prebid/prebid-server/v2/adapters/consumable" - "github.com/prebid/prebid-server/v2/adapters/conversant" - "github.com/prebid/prebid-server/v2/adapters/cpmstar" - "github.com/prebid/prebid-server/v2/adapters/criteo" - "github.com/prebid/prebid-server/v2/adapters/cwire" - "github.com/prebid/prebid-server/v2/adapters/datablocks" - "github.com/prebid/prebid-server/v2/adapters/decenterads" - "github.com/prebid/prebid-server/v2/adapters/deepintent" - "github.com/prebid/prebid-server/v2/adapters/definemedia" - "github.com/prebid/prebid-server/v2/adapters/dianomi" - "github.com/prebid/prebid-server/v2/adapters/dmx" - "github.com/prebid/prebid-server/v2/adapters/driftpixel" - "github.com/prebid/prebid-server/v2/adapters/dxkulture" - evolution "github.com/prebid/prebid-server/v2/adapters/e_volution" - "github.com/prebid/prebid-server/v2/adapters/edge226" - "github.com/prebid/prebid-server/v2/adapters/emtv" - "github.com/prebid/prebid-server/v2/adapters/eplanning" - "github.com/prebid/prebid-server/v2/adapters/epom" - "github.com/prebid/prebid-server/v2/adapters/flipp" - "github.com/prebid/prebid-server/v2/adapters/freewheelssp" - "github.com/prebid/prebid-server/v2/adapters/frvradn" - "github.com/prebid/prebid-server/v2/adapters/gamma" - "github.com/prebid/prebid-server/v2/adapters/gamoshi" - "github.com/prebid/prebid-server/v2/adapters/globalsun" - "github.com/prebid/prebid-server/v2/adapters/gothamads" - "github.com/prebid/prebid-server/v2/adapters/grid" - "github.com/prebid/prebid-server/v2/adapters/gumgum" - "github.com/prebid/prebid-server/v2/adapters/huaweiads" - "github.com/prebid/prebid-server/v2/adapters/imds" - "github.com/prebid/prebid-server/v2/adapters/impactify" - "github.com/prebid/prebid-server/v2/adapters/improvedigital" - "github.com/prebid/prebid-server/v2/adapters/infytv" - "github.com/prebid/prebid-server/v2/adapters/inmobi" - "github.com/prebid/prebid-server/v2/adapters/interactiveoffers" - "github.com/prebid/prebid-server/v2/adapters/invibes" - "github.com/prebid/prebid-server/v2/adapters/iqx" - "github.com/prebid/prebid-server/v2/adapters/iqzone" - "github.com/prebid/prebid-server/v2/adapters/ix" - "github.com/prebid/prebid-server/v2/adapters/jixie" - "github.com/prebid/prebid-server/v2/adapters/kargo" - "github.com/prebid/prebid-server/v2/adapters/kayzen" - "github.com/prebid/prebid-server/v2/adapters/kidoz" - "github.com/prebid/prebid-server/v2/adapters/kiviads" - "github.com/prebid/prebid-server/v2/adapters/krushmedia" - "github.com/prebid/prebid-server/v2/adapters/lemmadigital" - "github.com/prebid/prebid-server/v2/adapters/limelightDigital" - lmkiviads "github.com/prebid/prebid-server/v2/adapters/lm_kiviads" - "github.com/prebid/prebid-server/v2/adapters/lockerdome" - "github.com/prebid/prebid-server/v2/adapters/logan" - "github.com/prebid/prebid-server/v2/adapters/logicad" - "github.com/prebid/prebid-server/v2/adapters/loyal" - "github.com/prebid/prebid-server/v2/adapters/lunamedia" - "github.com/prebid/prebid-server/v2/adapters/mabidder" - "github.com/prebid/prebid-server/v2/adapters/madvertise" - "github.com/prebid/prebid-server/v2/adapters/marsmedia" - "github.com/prebid/prebid-server/v2/adapters/medianet" - "github.com/prebid/prebid-server/v2/adapters/mgid" - "github.com/prebid/prebid-server/v2/adapters/mgidX" - "github.com/prebid/prebid-server/v2/adapters/minutemedia" - "github.com/prebid/prebid-server/v2/adapters/mobfoxpb" - "github.com/prebid/prebid-server/v2/adapters/mobilefuse" - "github.com/prebid/prebid-server/v2/adapters/motorik" - "github.com/prebid/prebid-server/v2/adapters/nextmillennium" - "github.com/prebid/prebid-server/v2/adapters/nobid" - "github.com/prebid/prebid-server/v2/adapters/oms" - "github.com/prebid/prebid-server/v2/adapters/onetag" - "github.com/prebid/prebid-server/v2/adapters/openweb" - "github.com/prebid/prebid-server/v2/adapters/openx" - "github.com/prebid/prebid-server/v2/adapters/operaads" - "github.com/prebid/prebid-server/v2/adapters/orbidder" - "github.com/prebid/prebid-server/v2/adapters/outbrain" - "github.com/prebid/prebid-server/v2/adapters/ownadx" - "github.com/prebid/prebid-server/v2/adapters/pangle" - "github.com/prebid/prebid-server/v2/adapters/pgamssp" - "github.com/prebid/prebid-server/v2/adapters/playdigo" - "github.com/prebid/prebid-server/v2/adapters/pubmatic" - "github.com/prebid/prebid-server/v2/adapters/pubnative" - "github.com/prebid/prebid-server/v2/adapters/pulsepoint" - "github.com/prebid/prebid-server/v2/adapters/pwbid" - "github.com/prebid/prebid-server/v2/adapters/readpeak" - "github.com/prebid/prebid-server/v2/adapters/relevantdigital" - "github.com/prebid/prebid-server/v2/adapters/revcontent" - "github.com/prebid/prebid-server/v2/adapters/richaudience" - "github.com/prebid/prebid-server/v2/adapters/rise" - "github.com/prebid/prebid-server/v2/adapters/roulax" - "github.com/prebid/prebid-server/v2/adapters/rtbhouse" - "github.com/prebid/prebid-server/v2/adapters/rubicon" - salunamedia "github.com/prebid/prebid-server/v2/adapters/sa_lunamedia" - "github.com/prebid/prebid-server/v2/adapters/screencore" - "github.com/prebid/prebid-server/v2/adapters/seedingAlliance" - "github.com/prebid/prebid-server/v2/adapters/sharethrough" - "github.com/prebid/prebid-server/v2/adapters/silvermob" - "github.com/prebid/prebid-server/v2/adapters/silverpush" - "github.com/prebid/prebid-server/v2/adapters/smaato" - "github.com/prebid/prebid-server/v2/adapters/smartadserver" - "github.com/prebid/prebid-server/v2/adapters/smarthub" - "github.com/prebid/prebid-server/v2/adapters/smartrtb" - "github.com/prebid/prebid-server/v2/adapters/smartx" - "github.com/prebid/prebid-server/v2/adapters/smartyads" - "github.com/prebid/prebid-server/v2/adapters/smilewanted" - "github.com/prebid/prebid-server/v2/adapters/smrtconnect" - "github.com/prebid/prebid-server/v2/adapters/sonobi" - "github.com/prebid/prebid-server/v2/adapters/sovrn" - "github.com/prebid/prebid-server/v2/adapters/sovrnXsp" - "github.com/prebid/prebid-server/v2/adapters/sspBC" - "github.com/prebid/prebid-server/v2/adapters/stroeerCore" - "github.com/prebid/prebid-server/v2/adapters/taboola" - "github.com/prebid/prebid-server/v2/adapters/tappx" - "github.com/prebid/prebid-server/v2/adapters/teads" - "github.com/prebid/prebid-server/v2/adapters/telaria" - "github.com/prebid/prebid-server/v2/adapters/theadx" - "github.com/prebid/prebid-server/v2/adapters/tpmn" - "github.com/prebid/prebid-server/v2/adapters/trafficgate" - "github.com/prebid/prebid-server/v2/adapters/triplelift" - "github.com/prebid/prebid-server/v2/adapters/triplelift_native" - "github.com/prebid/prebid-server/v2/adapters/trustedstack" - "github.com/prebid/prebid-server/v2/adapters/ucfunnel" - "github.com/prebid/prebid-server/v2/adapters/undertone" - "github.com/prebid/prebid-server/v2/adapters/unicorn" - "github.com/prebid/prebid-server/v2/adapters/unruly" - "github.com/prebid/prebid-server/v2/adapters/videobyte" - "github.com/prebid/prebid-server/v2/adapters/videoheroes" - "github.com/prebid/prebid-server/v2/adapters/vidoomy" - "github.com/prebid/prebid-server/v2/adapters/visiblemeasures" - "github.com/prebid/prebid-server/v2/adapters/visx" - "github.com/prebid/prebid-server/v2/adapters/vox" - "github.com/prebid/prebid-server/v2/adapters/vrtcal" - "github.com/prebid/prebid-server/v2/adapters/vungle" - "github.com/prebid/prebid-server/v2/adapters/xeworks" - "github.com/prebid/prebid-server/v2/adapters/yahooAds" - "github.com/prebid/prebid-server/v2/adapters/yandex" - "github.com/prebid/prebid-server/v2/adapters/yeahmobi" - "github.com/prebid/prebid-server/v2/adapters/yieldlab" - "github.com/prebid/prebid-server/v2/adapters/yieldmo" - "github.com/prebid/prebid-server/v2/adapters/yieldone" - "github.com/prebid/prebid-server/v2/adapters/zeroclickfraud" - "github.com/prebid/prebid-server/v2/adapters/zeta_global_ssp" - "github.com/prebid/prebid-server/v2/adapters/zmaticoo" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + ttx "github.com/prebid/prebid-server/v3/adapters/33across" + "github.com/prebid/prebid-server/v3/adapters/aax" + "github.com/prebid/prebid-server/v3/adapters/aceex" + "github.com/prebid/prebid-server/v3/adapters/acuityads" + "github.com/prebid/prebid-server/v3/adapters/adelement" + "github.com/prebid/prebid-server/v3/adapters/adf" + "github.com/prebid/prebid-server/v3/adapters/adgeneration" + "github.com/prebid/prebid-server/v3/adapters/adhese" + "github.com/prebid/prebid-server/v3/adapters/adkernel" + "github.com/prebid/prebid-server/v3/adapters/adkernelAdn" + "github.com/prebid/prebid-server/v3/adapters/adman" + "github.com/prebid/prebid-server/v3/adapters/admatic" + "github.com/prebid/prebid-server/v3/adapters/admixer" + "github.com/prebid/prebid-server/v3/adapters/adnuntius" + "github.com/prebid/prebid-server/v3/adapters/adocean" + "github.com/prebid/prebid-server/v3/adapters/adoppler" + "github.com/prebid/prebid-server/v3/adapters/adot" + "github.com/prebid/prebid-server/v3/adapters/adpone" + "github.com/prebid/prebid-server/v3/adapters/adprime" + "github.com/prebid/prebid-server/v3/adapters/adquery" + "github.com/prebid/prebid-server/v3/adapters/adrino" + "github.com/prebid/prebid-server/v3/adapters/adsinteractive" + "github.com/prebid/prebid-server/v3/adapters/adtarget" + "github.com/prebid/prebid-server/v3/adapters/adtelligent" + "github.com/prebid/prebid-server/v3/adapters/adtonos" + "github.com/prebid/prebid-server/v3/adapters/adtrgtme" + "github.com/prebid/prebid-server/v3/adapters/advangelists" + "github.com/prebid/prebid-server/v3/adapters/adview" + "github.com/prebid/prebid-server/v3/adapters/adxcg" + "github.com/prebid/prebid-server/v3/adapters/adyoulike" + "github.com/prebid/prebid-server/v3/adapters/aidem" + "github.com/prebid/prebid-server/v3/adapters/aja" + "github.com/prebid/prebid-server/v3/adapters/algorix" + "github.com/prebid/prebid-server/v3/adapters/alkimi" + "github.com/prebid/prebid-server/v3/adapters/amx" + "github.com/prebid/prebid-server/v3/adapters/apacdex" + "github.com/prebid/prebid-server/v3/adapters/appnexus" + "github.com/prebid/prebid-server/v3/adapters/appush" + "github.com/prebid/prebid-server/v3/adapters/aso" + "github.com/prebid/prebid-server/v3/adapters/audienceNetwork" + "github.com/prebid/prebid-server/v3/adapters/automatad" + "github.com/prebid/prebid-server/v3/adapters/avocet" + "github.com/prebid/prebid-server/v3/adapters/axis" + "github.com/prebid/prebid-server/v3/adapters/axonix" + "github.com/prebid/prebid-server/v3/adapters/beachfront" + "github.com/prebid/prebid-server/v3/adapters/beintoo" + "github.com/prebid/prebid-server/v3/adapters/bematterfull" + "github.com/prebid/prebid-server/v3/adapters/between" + "github.com/prebid/prebid-server/v3/adapters/beyondmedia" + "github.com/prebid/prebid-server/v3/adapters/bidmachine" + "github.com/prebid/prebid-server/v3/adapters/bidmatic" + "github.com/prebid/prebid-server/v3/adapters/bidmyadz" + "github.com/prebid/prebid-server/v3/adapters/bidscube" + "github.com/prebid/prebid-server/v3/adapters/bidstack" + "github.com/prebid/prebid-server/v3/adapters/bigoad" + "github.com/prebid/prebid-server/v3/adapters/blasto" + "github.com/prebid/prebid-server/v3/adapters/bliink" + "github.com/prebid/prebid-server/v3/adapters/blue" + "github.com/prebid/prebid-server/v3/adapters/bluesea" + "github.com/prebid/prebid-server/v3/adapters/bmtm" + "github.com/prebid/prebid-server/v3/adapters/boldwin" + "github.com/prebid/prebid-server/v3/adapters/brave" + "github.com/prebid/prebid-server/v3/adapters/bwx" + cadentaperturemx "github.com/prebid/prebid-server/v3/adapters/cadent_aperture_mx" + "github.com/prebid/prebid-server/v3/adapters/ccx" + "github.com/prebid/prebid-server/v3/adapters/cointraffic" + "github.com/prebid/prebid-server/v3/adapters/coinzilla" + "github.com/prebid/prebid-server/v3/adapters/colossus" + "github.com/prebid/prebid-server/v3/adapters/compass" + "github.com/prebid/prebid-server/v3/adapters/concert" + "github.com/prebid/prebid-server/v3/adapters/connectad" + "github.com/prebid/prebid-server/v3/adapters/consumable" + "github.com/prebid/prebid-server/v3/adapters/conversant" + "github.com/prebid/prebid-server/v3/adapters/copper6ssp" + "github.com/prebid/prebid-server/v3/adapters/cpmstar" + "github.com/prebid/prebid-server/v3/adapters/criteo" + "github.com/prebid/prebid-server/v3/adapters/cwire" + "github.com/prebid/prebid-server/v3/adapters/datablocks" + "github.com/prebid/prebid-server/v3/adapters/decenterads" + "github.com/prebid/prebid-server/v3/adapters/deepintent" + "github.com/prebid/prebid-server/v3/adapters/definemedia" + "github.com/prebid/prebid-server/v3/adapters/dianomi" + "github.com/prebid/prebid-server/v3/adapters/displayio" + "github.com/prebid/prebid-server/v3/adapters/dmx" + "github.com/prebid/prebid-server/v3/adapters/driftpixel" + "github.com/prebid/prebid-server/v3/adapters/dxkulture" + evolution "github.com/prebid/prebid-server/v3/adapters/e_volution" + "github.com/prebid/prebid-server/v3/adapters/edge226" + "github.com/prebid/prebid-server/v3/adapters/emtv" + "github.com/prebid/prebid-server/v3/adapters/eplanning" + "github.com/prebid/prebid-server/v3/adapters/epom" + "github.com/prebid/prebid-server/v3/adapters/escalax" + "github.com/prebid/prebid-server/v3/adapters/flipp" + "github.com/prebid/prebid-server/v3/adapters/freewheelssp" + "github.com/prebid/prebid-server/v3/adapters/frvradn" + "github.com/prebid/prebid-server/v3/adapters/gamma" + "github.com/prebid/prebid-server/v3/adapters/gamoshi" + "github.com/prebid/prebid-server/v3/adapters/globalsun" + "github.com/prebid/prebid-server/v3/adapters/gothamads" + "github.com/prebid/prebid-server/v3/adapters/grid" + "github.com/prebid/prebid-server/v3/adapters/gumgum" + "github.com/prebid/prebid-server/v3/adapters/huaweiads" + "github.com/prebid/prebid-server/v3/adapters/imds" + "github.com/prebid/prebid-server/v3/adapters/impactify" + "github.com/prebid/prebid-server/v3/adapters/improvedigital" + "github.com/prebid/prebid-server/v3/adapters/infytv" + "github.com/prebid/prebid-server/v3/adapters/inmobi" + "github.com/prebid/prebid-server/v3/adapters/interactiveoffers" + "github.com/prebid/prebid-server/v3/adapters/invibes" + "github.com/prebid/prebid-server/v3/adapters/iqx" + "github.com/prebid/prebid-server/v3/adapters/iqzone" + "github.com/prebid/prebid-server/v3/adapters/ix" + "github.com/prebid/prebid-server/v3/adapters/jixie" + "github.com/prebid/prebid-server/v3/adapters/kargo" + "github.com/prebid/prebid-server/v3/adapters/kayzen" + "github.com/prebid/prebid-server/v3/adapters/kidoz" + "github.com/prebid/prebid-server/v3/adapters/kiviads" + "github.com/prebid/prebid-server/v3/adapters/krushmedia" + "github.com/prebid/prebid-server/v3/adapters/lemmadigital" + "github.com/prebid/prebid-server/v3/adapters/limelightDigital" + lmkiviads "github.com/prebid/prebid-server/v3/adapters/lm_kiviads" + "github.com/prebid/prebid-server/v3/adapters/lockerdome" + "github.com/prebid/prebid-server/v3/adapters/logan" + "github.com/prebid/prebid-server/v3/adapters/logicad" + "github.com/prebid/prebid-server/v3/adapters/loyal" + "github.com/prebid/prebid-server/v3/adapters/lunamedia" + "github.com/prebid/prebid-server/v3/adapters/mabidder" + "github.com/prebid/prebid-server/v3/adapters/madvertise" + "github.com/prebid/prebid-server/v3/adapters/marsmedia" + "github.com/prebid/prebid-server/v3/adapters/mediago" + "github.com/prebid/prebid-server/v3/adapters/medianet" + "github.com/prebid/prebid-server/v3/adapters/melozen" + "github.com/prebid/prebid-server/v3/adapters/metax" + "github.com/prebid/prebid-server/v3/adapters/mgid" + "github.com/prebid/prebid-server/v3/adapters/mgidX" + "github.com/prebid/prebid-server/v3/adapters/minutemedia" + "github.com/prebid/prebid-server/v3/adapters/missena" + "github.com/prebid/prebid-server/v3/adapters/mobfoxpb" + "github.com/prebid/prebid-server/v3/adapters/mobilefuse" + "github.com/prebid/prebid-server/v3/adapters/motorik" + "github.com/prebid/prebid-server/v3/adapters/nextmillennium" + "github.com/prebid/prebid-server/v3/adapters/nobid" + "github.com/prebid/prebid-server/v3/adapters/oms" + "github.com/prebid/prebid-server/v3/adapters/onetag" + "github.com/prebid/prebid-server/v3/adapters/openweb" + "github.com/prebid/prebid-server/v3/adapters/openx" + "github.com/prebid/prebid-server/v3/adapters/operaads" + "github.com/prebid/prebid-server/v3/adapters/oraki" + "github.com/prebid/prebid-server/v3/adapters/orbidder" + "github.com/prebid/prebid-server/v3/adapters/outbrain" + "github.com/prebid/prebid-server/v3/adapters/ownadx" + "github.com/prebid/prebid-server/v3/adapters/pangle" + "github.com/prebid/prebid-server/v3/adapters/pgamssp" + "github.com/prebid/prebid-server/v3/adapters/playdigo" + "github.com/prebid/prebid-server/v3/adapters/pubmatic" + "github.com/prebid/prebid-server/v3/adapters/pubnative" + "github.com/prebid/prebid-server/v3/adapters/pubrise" + "github.com/prebid/prebid-server/v3/adapters/pulsepoint" + "github.com/prebid/prebid-server/v3/adapters/pwbid" + "github.com/prebid/prebid-server/v3/adapters/qt" + "github.com/prebid/prebid-server/v3/adapters/readpeak" + "github.com/prebid/prebid-server/v3/adapters/relevantdigital" + "github.com/prebid/prebid-server/v3/adapters/resetdigital" + "github.com/prebid/prebid-server/v3/adapters/revcontent" + "github.com/prebid/prebid-server/v3/adapters/richaudience" + "github.com/prebid/prebid-server/v3/adapters/rise" + "github.com/prebid/prebid-server/v3/adapters/roulax" + "github.com/prebid/prebid-server/v3/adapters/rtbhouse" + "github.com/prebid/prebid-server/v3/adapters/rubicon" + salunamedia "github.com/prebid/prebid-server/v3/adapters/sa_lunamedia" + "github.com/prebid/prebid-server/v3/adapters/screencore" + "github.com/prebid/prebid-server/v3/adapters/seedingAlliance" + "github.com/prebid/prebid-server/v3/adapters/sharethrough" + "github.com/prebid/prebid-server/v3/adapters/silvermob" + "github.com/prebid/prebid-server/v3/adapters/silverpush" + "github.com/prebid/prebid-server/v3/adapters/smaato" + "github.com/prebid/prebid-server/v3/adapters/smartadserver" + "github.com/prebid/prebid-server/v3/adapters/smarthub" + "github.com/prebid/prebid-server/v3/adapters/smartrtb" + "github.com/prebid/prebid-server/v3/adapters/smartx" + "github.com/prebid/prebid-server/v3/adapters/smartyads" + "github.com/prebid/prebid-server/v3/adapters/smilewanted" + "github.com/prebid/prebid-server/v3/adapters/smrtconnect" + "github.com/prebid/prebid-server/v3/adapters/sonobi" + "github.com/prebid/prebid-server/v3/adapters/sovrn" + "github.com/prebid/prebid-server/v3/adapters/sovrnXsp" + "github.com/prebid/prebid-server/v3/adapters/sspBC" + "github.com/prebid/prebid-server/v3/adapters/stroeerCore" + "github.com/prebid/prebid-server/v3/adapters/taboola" + "github.com/prebid/prebid-server/v3/adapters/tappx" + "github.com/prebid/prebid-server/v3/adapters/teads" + "github.com/prebid/prebid-server/v3/adapters/telaria" + "github.com/prebid/prebid-server/v3/adapters/theadx" + "github.com/prebid/prebid-server/v3/adapters/thetradedesk" + "github.com/prebid/prebid-server/v3/adapters/tpmn" + "github.com/prebid/prebid-server/v3/adapters/trafficgate" + "github.com/prebid/prebid-server/v3/adapters/triplelift" + "github.com/prebid/prebid-server/v3/adapters/triplelift_native" + "github.com/prebid/prebid-server/v3/adapters/trustedstack" + "github.com/prebid/prebid-server/v3/adapters/ucfunnel" + "github.com/prebid/prebid-server/v3/adapters/undertone" + "github.com/prebid/prebid-server/v3/adapters/unicorn" + "github.com/prebid/prebid-server/v3/adapters/unruly" + "github.com/prebid/prebid-server/v3/adapters/vidazoo" + "github.com/prebid/prebid-server/v3/adapters/videobyte" + "github.com/prebid/prebid-server/v3/adapters/videoheroes" + "github.com/prebid/prebid-server/v3/adapters/vidoomy" + "github.com/prebid/prebid-server/v3/adapters/visiblemeasures" + "github.com/prebid/prebid-server/v3/adapters/visx" + "github.com/prebid/prebid-server/v3/adapters/vox" + "github.com/prebid/prebid-server/v3/adapters/vrtcal" + "github.com/prebid/prebid-server/v3/adapters/vungle" + "github.com/prebid/prebid-server/v3/adapters/xeworks" + "github.com/prebid/prebid-server/v3/adapters/yahooAds" + "github.com/prebid/prebid-server/v3/adapters/yandex" + "github.com/prebid/prebid-server/v3/adapters/yeahmobi" + "github.com/prebid/prebid-server/v3/adapters/yieldlab" + "github.com/prebid/prebid-server/v3/adapters/yieldmo" + "github.com/prebid/prebid-server/v3/adapters/yieldone" + "github.com/prebid/prebid-server/v3/adapters/zeroclickfraud" + "github.com/prebid/prebid-server/v3/adapters/zeta_global_ssp" + "github.com/prebid/prebid-server/v3/adapters/zmaticoo" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // Adapter registration is kept in this separate file for ease of use and to aid @@ -225,6 +243,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderAdkernel: adkernel.Builder, openrtb_ext.BidderAdkernelAdn: adkernelAdn.Builder, openrtb_ext.BidderAdman: adman.Builder, + openrtb_ext.BidderAdmatic: admatic.Builder, openrtb_ext.BidderAdmixer: admixer.Builder, openrtb_ext.BidderAdnuntius: adnuntius.Builder, openrtb_ext.BidderAdOcean: adocean.Builder, @@ -238,6 +257,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderAdtarget: adtarget.Builder, openrtb_ext.BidderAdtrgtme: adtrgtme.Builder, openrtb_ext.BidderAdtelligent: adtelligent.Builder, + openrtb_ext.BidderAdTonos: adtonos.Builder, openrtb_ext.BidderAdvangelists: advangelists.Builder, openrtb_ext.BidderAdView: adview.Builder, openrtb_ext.BidderAdxcg: adxcg.Builder, @@ -262,10 +282,12 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderBetween: between.Builder, openrtb_ext.BidderBeyondMedia: beyondmedia.Builder, openrtb_ext.BidderBidmachine: bidmachine.Builder, + openrtb_ext.BidderBidmatic: bidmatic.Builder, openrtb_ext.BidderBidmyadz: bidmyadz.Builder, openrtb_ext.BidderBidsCube: bidscube.Builder, openrtb_ext.BidderBidstack: bidstack.Builder, - openrtb_ext.BidderBizzclick: bizzclick.Builder, + openrtb_ext.BidderBigoAd: bigoad.Builder, + openrtb_ext.BidderBlasto: blasto.Builder, openrtb_ext.BidderBliink: bliink.Builder, openrtb_ext.BidderBlue: blue.Builder, openrtb_ext.BidderBluesea: bluesea.Builder, @@ -275,6 +297,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderBWX: bwx.Builder, openrtb_ext.BidderCadentApertureMX: cadentaperturemx.Builder, openrtb_ext.BidderCcx: ccx.Builder, + openrtb_ext.BidderCointraffic: cointraffic.Builder, openrtb_ext.BidderCoinzilla: coinzilla.Builder, openrtb_ext.BidderColossus: colossus.Builder, openrtb_ext.BidderCompass: compass.Builder, @@ -282,6 +305,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderConnectAd: connectad.Builder, openrtb_ext.BidderConsumable: consumable.Builder, openrtb_ext.BidderConversant: conversant.Builder, + openrtb_ext.BidderCopper6ssp: copper6ssp.Builder, openrtb_ext.BidderCpmstar: cpmstar.Builder, openrtb_ext.BidderCriteo: criteo.Builder, openrtb_ext.BidderCWire: cwire.Builder, @@ -290,6 +314,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderDeepintent: deepintent.Builder, openrtb_ext.BidderDefinemedia: definemedia.Builder, openrtb_ext.BidderDianomi: dianomi.Builder, + openrtb_ext.BidderDisplayio: displayio.Builder, openrtb_ext.BidderEdge226: edge226.Builder, openrtb_ext.BidderDmx: dmx.Builder, openrtb_ext.BidderDXKulture: dxkulture.Builder, @@ -298,6 +323,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderEmxDigital: cadentaperturemx.Builder, openrtb_ext.BidderEPlanning: eplanning.Builder, openrtb_ext.BidderEpom: epom.Builder, + openrtb_ext.BidderEscalax: escalax.Builder, openrtb_ext.BidderEVolution: evolution.Builder, openrtb_ext.BidderFlipp: flipp.Builder, openrtb_ext.BidderFreewheelSSP: freewheelssp.Builder, @@ -338,10 +364,14 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderMadvertise: madvertise.Builder, openrtb_ext.BidderMarsmedia: marsmedia.Builder, openrtb_ext.BidderMediafuse: appnexus.Builder, + openrtb_ext.BidderMediaGo: mediago.Builder, openrtb_ext.BidderMedianet: medianet.Builder, + openrtb_ext.BidderMeloZen: melozen.Builder, + openrtb_ext.BidderMetaX: metax.Builder, openrtb_ext.BidderMgid: mgid.Builder, openrtb_ext.BidderMgidX: mgidX.Builder, openrtb_ext.BidderMinuteMedia: minutemedia.Builder, + openrtb_ext.BidderMissena: missena.Builder, openrtb_ext.BidderMobfoxpb: mobfoxpb.Builder, openrtb_ext.BidderMobileFuse: mobilefuse.Builder, openrtb_ext.BidderMotorik: motorik.Builder, @@ -352,6 +382,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderOpenWeb: openweb.Builder, openrtb_ext.BidderOpenx: openx.Builder, openrtb_ext.BidderOperaads: operaads.Builder, + openrtb_ext.BidderOraki: oraki.Builder, openrtb_ext.BidderOrbidder: orbidder.Builder, openrtb_ext.BidderOutbrain: outbrain.Builder, openrtb_ext.BidderOwnAdx: ownadx.Builder, @@ -360,11 +391,14 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderPlaydigo: playdigo.Builder, openrtb_ext.BidderPubmatic: pubmatic.Builder, openrtb_ext.BidderPubnative: pubnative.Builder, + openrtb_ext.BidderPubrise: pubrise.Builder, openrtb_ext.BidderPulsepoint: pulsepoint.Builder, openrtb_ext.BidderPWBid: pwbid.Builder, + openrtb_ext.BidderQT: qt.Builder, openrtb_ext.BidderReadpeak: readpeak.Builder, openrtb_ext.BidderRelevantDigital: relevantdigital.Builder, openrtb_ext.BidderRevcontent: revcontent.Builder, + openrtb_ext.BidderResetDigital: resetdigital.Builder, openrtb_ext.BidderRichaudience: richaudience.Builder, openrtb_ext.BidderRise: rise.Builder, openrtb_ext.BidderRoulax: roulax.Builder, @@ -394,6 +428,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderTeads: teads.Builder, openrtb_ext.BidderTelaria: telaria.Builder, openrtb_ext.BidderTheadx: theadx.Builder, + openrtb_ext.BidderTheTradeDesk: thetradedesk.Builder, openrtb_ext.BidderTpmn: tpmn.Builder, openrtb_ext.BidderTrafficGate: trafficgate.Builder, openrtb_ext.BidderTriplelift: triplelift.Builder, @@ -403,6 +438,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderUndertone: undertone.Builder, openrtb_ext.BidderUnicorn: unicorn.Builder, openrtb_ext.BidderUnruly: unruly.Builder, + openrtb_ext.BidderVidazoo: vidazoo.Builder, openrtb_ext.BidderVideoByte: videobyte.Builder, openrtb_ext.BidderVideoHeroes: videoheroes.Builder, openrtb_ext.BidderVidoomy: vidoomy.Builder, diff --git a/exchange/adapter_util.go b/exchange/adapter_util.go index 0d277d15723..e70c32055a0 100644 --- a/exchange/adapter_util.go +++ b/exchange/adapter_util.go @@ -4,10 +4,10 @@ import ( "fmt" "net/http" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/metrics" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/metrics" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func BuildAdapters(client *http.Client, cfg *config.Configuration, infos config.BidderInfos, me metrics.MetricsEngine) (map[openrtb_ext.BidderName]AdaptedBidder, []error) { @@ -120,6 +120,7 @@ func GetDisabledBidderWarningMessages(infos config.BidderInfos) map[string]strin "applogy": `Bidder "applogy" is no longer available in Prebid Server. Please update your configuration.`, "rhythmone": `Bidder "rhythmone" is no longer available in Prebid Server. Please update your configuration.`, "nanointeractive": `Bidder "nanointeractive" is no longer available in Prebid Server. Please update your configuration.`, + "bizzclick": `Bidder "bizzclick" is no longer available in Prebid Server. Please update your configuration. "bizzclick" has been renamed to "blasto".`, "liftoff": `Bidder "liftoff" is no longer available in Prebid Server. If you're looking to use the Vungle Exchange adapter, please rename it to "vungle" in your configuration.`, } diff --git a/exchange/adapter_util_test.go b/exchange/adapter_util_test.go index 053b669961d..3f558af5610 100644 --- a/exchange/adapter_util_test.go +++ b/exchange/adapter_util_test.go @@ -6,12 +6,12 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/adapters/appnexus" - "github.com/prebid/prebid-server/v2/adapters/rubicon" - "github.com/prebid/prebid-server/v2/config" - metrics "github.com/prebid/prebid-server/v2/metrics/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/adapters/appnexus" + "github.com/prebid/prebid-server/v3/adapters/rubicon" + "github.com/prebid/prebid-server/v3/config" + metrics "github.com/prebid/prebid-server/v3/metrics/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/exchange/auction.go b/exchange/auction.go index 8e3c432e48c..4d5b8e00375 100644 --- a/exchange/auction.go +++ b/exchange/auction.go @@ -12,11 +12,11 @@ import ( uuid "github.com/gofrs/uuid" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/exchange/entities" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/prebid_cache_client" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/exchange/entities" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/prebid_cache_client" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) const ( diff --git a/exchange/auction_response.go b/exchange/auction_response.go index 1d0747b0fe5..67ab2dc4bb1 100644 --- a/exchange/auction_response.go +++ b/exchange/auction_response.go @@ -2,7 +2,7 @@ package exchange import ( "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // AuctionResponse contains OpenRTB Bid Response object and its extension (un-marshalled) object diff --git a/exchange/auction_test.go b/exchange/auction_test.go index 17224dcd2fd..188e4d30eaa 100644 --- a/exchange/auction_test.go +++ b/exchange/auction_test.go @@ -12,12 +12,12 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/exchange/entities" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/prebid_cache_client" - "github.com/prebid/prebid-server/v2/util/jsonutil" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/exchange/entities" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/prebid_cache_client" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/exchange/bidder.go b/exchange/bidder.go index fb2c73be5c2..232da470fba 100644 --- a/exchange/bidder.go +++ b/exchange/bidder.go @@ -17,24 +17,24 @@ import ( "time" "github.com/golang/glog" - "github.com/prebid/prebid-server/v2/bidadjustment" - "github.com/prebid/prebid-server/v2/config/util" - "github.com/prebid/prebid-server/v2/currency" - "github.com/prebid/prebid-server/v2/exchange/entities" - "github.com/prebid/prebid-server/v2/experiment/adscert" - "github.com/prebid/prebid-server/v2/hooks/hookexecution" - "github.com/prebid/prebid-server/v2/version" + "github.com/prebid/prebid-server/v3/bidadjustment" + "github.com/prebid/prebid-server/v3/config/util" + "github.com/prebid/prebid-server/v3/currency" + "github.com/prebid/prebid-server/v3/exchange/entities" + "github.com/prebid/prebid-server/v3/experiment/adscert" + "github.com/prebid/prebid-server/v3/hooks/hookexecution" + "github.com/prebid/prebid-server/v3/version" "github.com/prebid/openrtb/v20/adcom1" nativeRequests "github.com/prebid/openrtb/v20/native1/request" nativeResponse "github.com/prebid/openrtb/v20/native1/response" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/metrics" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/metrics" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" "golang.org/x/net/context/ctxhttp" ) @@ -76,12 +76,14 @@ type bidRequestOptions struct { type extraBidderRespInfo struct { respProcessingStartTime time.Time + seatNonBidBuilder SeatNonBidBuilder } type extraAuctionResponseInfo struct { fledge *openrtb_ext.Fledge bidsFound bool bidderResponseStartTime time.Time + seatNonBidBuilder SeatNonBidBuilder } const ImpIdReqBody = "Stored bid response for impression id: " @@ -96,7 +98,7 @@ const ( // The name refers to the "Adapter" architecture pattern, and should not be confused with a Prebid "Adapter" // (which is being phased out and replaced by Bidder for OpenRTB auctions) func AdaptBidder(bidder adapters.Bidder, client *http.Client, cfg *config.Configuration, me metrics.MetricsEngine, name openrtb_ext.BidderName, debugInfo *config.DebugInfo, endpointCompression string) AdaptedBidder { - return &bidderAdapter{ + return &BidderAdapter{ Bidder: bidder, BidderName: name, Client: client, @@ -117,7 +119,7 @@ func parseDebugInfo(info *config.DebugInfo) bool { return info.Allow } -type bidderAdapter struct { +type BidderAdapter struct { Bidder adapters.Bidder BidderName openrtb_ext.BidderName Client *http.Client @@ -132,9 +134,10 @@ type bidderAdapterConfig struct { EndpointCompression string } -func (bidder *bidderAdapter) requestBid(ctx context.Context, bidderRequest BidderRequest, conversions currency.Conversions, reqInfo *adapters.ExtraRequestInfo, adsCertSigner adscert.Signer, bidRequestOptions bidRequestOptions, alternateBidderCodes openrtb_ext.ExtAlternateBidderCodes, hookExecutor hookexecution.StageExecutor, ruleToAdjustments openrtb_ext.AdjustmentsByDealID) ([]*entities.PbsOrtbSeatBid, extraBidderRespInfo, []error) { +func (bidder *BidderAdapter) requestBid(ctx context.Context, bidderRequest BidderRequest, conversions currency.Conversions, reqInfo *adapters.ExtraRequestInfo, adsCertSigner adscert.Signer, bidRequestOptions bidRequestOptions, alternateBidderCodes openrtb_ext.ExtAlternateBidderCodes, hookExecutor hookexecution.StageExecutor, ruleToAdjustments openrtb_ext.AdjustmentsByDealID) ([]*entities.PbsOrtbSeatBid, extraBidderRespInfo, []error) { request := openrtb_ext.RequestWrapper{BidRequest: bidderRequest.BidRequest} reject := hookExecutor.ExecuteBidderRequestStage(&request, string(bidderRequest.BidderName)) + seatNonBidBuilder := SeatNonBidBuilder{} if reject != nil { return nil, extraBidderRespInfo{}, []error{reject} } @@ -398,13 +401,17 @@ func (bidder *bidderAdapter) requestBid(ctx context.Context, bidderRequest Bidde } } else { errs = append(errs, httpInfo.err) + nonBidReason := httpInfoToNonBidReason(httpInfo) + seatNonBidBuilder.rejectImps(httpInfo.request.ImpIDs, nonBidReason, string(bidderRequest.BidderName)) } } + seatBids := make([]*entities.PbsOrtbSeatBid, 0, len(seatBidMap)) for _, seatBid := range seatBidMap { seatBids = append(seatBids, seatBid) } + extraRespInfo.seatNonBidBuilder = seatNonBidBuilder return seatBids, extraRespInfo, errs } @@ -519,11 +526,11 @@ func makeExt(httpInfo *httpCallInfo) *openrtb_ext.ExtHttpCall { // doRequest makes a request, handles the response, and returns the data needed by the // Bidder interface. -func (bidder *bidderAdapter) doRequest(ctx context.Context, req *adapters.RequestData, bidderRequestStartTime time.Time, tmaxAdjustments *TmaxAdjustmentsPreprocessed) *httpCallInfo { +func (bidder *BidderAdapter) doRequest(ctx context.Context, req *adapters.RequestData, bidderRequestStartTime time.Time, tmaxAdjustments *TmaxAdjustmentsPreprocessed) *httpCallInfo { return bidder.doRequestImpl(ctx, req, glog.Warningf, bidderRequestStartTime, tmaxAdjustments) } -func (bidder *bidderAdapter) doRequestImpl(ctx context.Context, req *adapters.RequestData, logger util.LogMsg, bidderRequestStartTime time.Time, tmaxAdjustments *TmaxAdjustmentsPreprocessed) *httpCallInfo { +func (bidder *BidderAdapter) doRequestImpl(ctx context.Context, req *adapters.RequestData, logger util.LogMsg, bidderRequestStartTime time.Time, tmaxAdjustments *TmaxAdjustmentsPreprocessed) *httpCallInfo { requestBody, err := getRequestBody(req, bidder.config.EndpointCompression) if err != nil { return &httpCallInfo{ @@ -610,7 +617,7 @@ func (bidder *bidderAdapter) doRequestImpl(ctx context.Context, req *adapters.Re } } -func (bidder *bidderAdapter) doTimeoutNotification(timeoutBidder adapters.TimeoutBidder, req *adapters.RequestData, logger util.LogMsg) { +func (bidder *BidderAdapter) doTimeoutNotification(timeoutBidder adapters.TimeoutBidder, req *adapters.RequestData, logger util.LogMsg) { ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond) defer cancel() toReq, errL := timeoutBidder.MakeTimeoutNotification(req) @@ -660,7 +667,7 @@ type httpCallInfo struct { // This function adds an httptrace.ClientTrace object to the context so, if connection with the bidder // endpoint is established, we can keep track of whether the connection was newly created, reused, and // the time from the connection request, to the connection creation. -func (bidder *bidderAdapter) addClientTrace(ctx context.Context) context.Context { +func (bidder *BidderAdapter) addClientTrace(ctx context.Context) context.Context { var connStart, dnsStart, tlsStart time.Time trace := &httptrace.ClientTrace{ diff --git a/exchange/bidder_test.go b/exchange/bidder_test.go index 31c497d6f1c..dbb167e053d 100644 --- a/exchange/bidder_test.go +++ b/exchange/bidder_test.go @@ -9,11 +9,15 @@ import ( "errors" "fmt" "io" + "net" "net/http" "net/http/httptest" "net/http/httptrace" + "net/url" + "os" "sort" "strings" + "syscall" "testing" "time" @@ -22,19 +26,19 @@ import ( nativeRequests "github.com/prebid/openrtb/v20/native1/request" nativeResponse "github.com/prebid/openrtb/v20/native1/response" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/currency" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/exchange/entities" - "github.com/prebid/prebid-server/v2/experiment/adscert" - "github.com/prebid/prebid-server/v2/hooks/hookexecution" - "github.com/prebid/prebid-server/v2/metrics" - metricsConfig "github.com/prebid/prebid-server/v2/metrics/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/jsonutil" - "github.com/prebid/prebid-server/v2/util/ptrutil" - "github.com/prebid/prebid-server/v2/version" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/currency" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/exchange/entities" + "github.com/prebid/prebid-server/v3/experiment/adscert" + "github.com/prebid/prebid-server/v3/hooks/hookexecution" + "github.com/prebid/prebid-server/v3/metrics" + metricsConfig "github.com/prebid/prebid-server/v3/metrics/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/ptrutil" + "github.com/prebid/prebid-server/v3/version" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" ) @@ -552,7 +556,7 @@ func TestBidderTimeout(t *testing.T) { server := httptest.NewServer(handler) defer server.Close() - bidder := &bidderAdapter{ + bidder := &BidderAdapter{ Bidder: &mixedMultiBidder{}, BidderName: openrtb_ext.BidderAppnexus, Client: server.Client(), @@ -574,7 +578,7 @@ func TestBidderTimeout(t *testing.T) { // TestInvalidRequest makes sure that bidderAdapter.doRequest returns errors on bad requests. func TestInvalidRequest(t *testing.T) { server := httptest.NewServer(mockHandler(200, "getBody", "postBody")) - bidder := &bidderAdapter{ + bidder := &BidderAdapter{ Bidder: &mixedMultiBidder{}, Client: server.Client(), } @@ -595,7 +599,7 @@ func TestConnectionClose(t *testing.T) { }) server = httptest.NewServer(handler) - bidder := &bidderAdapter{ + bidder := &BidderAdapter{ Bidder: &mixedMultiBidder{}, Client: server.Client(), BidderName: openrtb_ext.BidderAppnexus, @@ -2145,7 +2149,7 @@ func TestCallRecordDNSTime(t *testing.T) { // Instantiate the bidder that will send the request. We'll make sure to use an // http.Client that runs our mock RoundTripper so DNSDone(httptrace.DNSDoneInfo{}) // gets called - bidder := &bidderAdapter{ + bidder := &BidderAdapter{ Bidder: &mixedMultiBidder{}, Client: &http.Client{Transport: DNSDoneTripper{}}, me: metricsMock, @@ -2169,7 +2173,7 @@ func TestCallRecordTLSHandshakeTime(t *testing.T) { // Instantiate the bidder that will send the request. We'll make sure to use an // http.Client that runs our mock RoundTripper so DNSDone(httptrace.DNSDoneInfo{}) // gets called - bidder := &bidderAdapter{ + bidder := &BidderAdapter{ Bidder: &mixedMultiBidder{}, Client: &http.Client{Transport: TLSHandshakeTripper{}}, me: metricsMock, @@ -2197,7 +2201,7 @@ func TestTimeoutNotificationOff(t *testing.T) { Headers: http.Header{}, }, } - bidder := &bidderAdapter{ + bidder := &BidderAdapter{ Bidder: bidderImpl, Client: server.Client(), config: bidderAdapterConfig{Debug: config.Debug{}}, @@ -2231,7 +2235,7 @@ func TestTimeoutNotificationOn(t *testing.T) { // Wrap with BidderInfo to mimic exchange.go flow. bidderWrappedWithInfo := wrapWithBidderInfo(bidder) - bidderAdapter := &bidderAdapter{ + bidderAdapter := &BidderAdapter{ Bidder: bidderWrappedWithInfo, Client: server.Client(), config: bidderAdapterConfig{ @@ -3096,6 +3100,148 @@ func TestGetBidType(t *testing.T) { } } +func TestSeatNonBid(t *testing.T) { + type args struct { + BidRequest *openrtb2.BidRequest + Seat string + SeatRequests []*adapters.RequestData + BidderResponse func() (*http.Response, error) + client *http.Client + } + type expect struct { + seatBids []*entities.PbsOrtbSeatBid + seatNonBids SeatNonBidBuilder + errors []error + } + testCases := []struct { + name string + args args + expect expect + }{ + { + name: "NBR_101_timeout_for_context_deadline_exceeded", + args: args{ + Seat: "pubmatic", + BidRequest: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{ID: "1234"}}, + }, + SeatRequests: []*adapters.RequestData{{ImpIDs: []string{"1234"}}}, + BidderResponse: func() (*http.Response, error) { return nil, context.DeadlineExceeded }, + client: &http.Client{Timeout: time.Nanosecond}, // for timeout + }, + expect: expect{ + seatNonBids: SeatNonBidBuilder{ + "pubmatic": {{ + ImpId: "1234", + StatusCode: int(ErrorTimeout), + }}, + }, + errors: []error{&errortypes.Timeout{Message: context.DeadlineExceeded.Error()}}, + seatBids: []*entities.PbsOrtbSeatBid{{Bids: []*entities.PbsOrtbBid{}, Currency: "USD", Seat: "pubmatic", HttpCalls: []*openrtb_ext.ExtHttpCall{}}}, + }, + }, { + name: "NBR_103_Bidder_Unreachable_Connection_Refused", + args: args{ + Seat: "appnexus", + SeatRequests: []*adapters.RequestData{{ImpIDs: []string{"1234", "4567"}}}, + BidRequest: &openrtb2.BidRequest{Imp: []openrtb2.Imp{{ID: "1234"}, {ID: "4567"}}}, + BidderResponse: func() (*http.Response, error) { + return nil, &net.OpError{Err: os.NewSyscallError(syscall.ECONNREFUSED.Error(), syscall.ECONNREFUSED)} + }, + }, + expect: expect{ + seatNonBids: SeatNonBidBuilder{ + "appnexus": { + {ImpId: "1234", StatusCode: int(ErrorBidderUnreachable)}, + {ImpId: "4567", StatusCode: int(ErrorBidderUnreachable)}, + }, + }, + seatBids: []*entities.PbsOrtbSeatBid{{Bids: []*entities.PbsOrtbBid{}, Currency: "USD", Seat: "appnexus", HttpCalls: []*openrtb_ext.ExtHttpCall{}}}, + errors: []error{&url.Error{Op: "Get", URL: "", Err: &net.OpError{Err: os.NewSyscallError(syscall.ECONNREFUSED.Error(), syscall.ECONNREFUSED)}}}, + }, + }, { + name: "no_impids_populated_in_request_data", + args: args{ + SeatRequests: []*adapters.RequestData{{ + ImpIDs: nil, // no imp ids + }}, + BidRequest: &openrtb2.BidRequest{Imp: []openrtb2.Imp{{ID: "1234"}}}, + BidderResponse: func() (*http.Response, error) { + return nil, errors.New("some_error") + }, + }, + expect: expect{ + seatNonBids: SeatNonBidBuilder{}, + seatBids: []*entities.PbsOrtbSeatBid{{Bids: []*entities.PbsOrtbBid{}, Currency: "USD", HttpCalls: []*openrtb_ext.ExtHttpCall{}}}, + errors: []error{&url.Error{Op: "Get", URL: "", Err: errors.New("some_error")}}, + }, + }, + } + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + mockBidder := &mockBidder{} + mockBidder.On("MakeRequests", mock.Anything, mock.Anything).Return(test.args.SeatRequests, []error(nil)) + mockMetricsEngine := &metrics.MetricsEngineMock{} + mockMetricsEngine.On("RecordOverheadTime", mock.Anything, mock.Anything).Return(nil) + mockMetricsEngine.On("RecordBidderServerResponseTime", mock.Anything).Return(nil) + roundTrip := &mockRoundTripper{} + roundTrip.On("RoundTrip", mock.Anything).Return(test.args.BidderResponse()) + client := &http.Client{ + Transport: roundTrip, + Timeout: 0, + } + if test.args.client != nil { + client.Timeout = test.args.client.Timeout + } + bidder := AdaptBidder(mockBidder, client, &config.Configuration{}, mockMetricsEngine, openrtb_ext.BidderAppnexus, &config.DebugInfo{}, test.args.Seat) + + ctx := context.Background() + if client.Timeout > 0 { + ctxTimeout, cancel := context.WithTimeout(ctx, client.Timeout) + ctx = ctxTimeout + defer cancel() + } + seatBids, responseExtra, errors := bidder.requestBid(ctx, BidderRequest{ + BidRequest: test.args.BidRequest, + BidderName: openrtb_ext.BidderName(test.args.Seat), + }, nil, &adapters.ExtraRequestInfo{}, &MockSigner{}, bidRequestOptions{}, openrtb_ext.ExtAlternateBidderCodes{}, hookexecution.EmptyHookExecutor{}, nil) + assert.Equal(t, test.expect.seatBids, seatBids) + assert.Equal(t, test.expect.seatNonBids, responseExtra.seatNonBidBuilder) + assert.Equal(t, test.expect.errors, errors) + for _, nonBids := range responseExtra.seatNonBidBuilder { + for _, nonBid := range nonBids { + for _, seatBid := range seatBids { + for _, bid := range seatBid.Bids { + // ensure non bids are not present in seat bids + if nonBid.ImpId == bid.Bid.ImpID { + assert.Fail(t, "imp id [%s] present in both seat bid and non seat bid", nonBid.ImpId) + } + } + } + } + } + }) + } +} + +type mockRoundTripper struct { + mock.Mock +} + +func (rt *mockRoundTripper) RoundTrip(request *http.Request) (*http.Response, error) { + args := rt.Called(request) + var response *http.Response + if args.Get(0) != nil { + response = args.Get(0).(*http.Response) + } + var err error + if args.Get(1) != nil { + err = args.Get(1).(error) + } + + return response, err +} + type mockBidderTmaxCtx struct { startTime, deadline, now time.Time ok bool @@ -3235,7 +3381,7 @@ func TestDoRequestImplWithTmax(t *testing.T) { Body: []byte(`{"id":"this-id","app":{"publisher":{"id":"pub-id"}}}`), } - bidderAdapter := bidderAdapter{ + bidderAdapter := BidderAdapter{ me: &metricsConfig.NilMetricsEngine{}, Client: server.Client(), } @@ -3310,7 +3456,7 @@ func TestDoRequestImplWithTmaxTimeout(t *testing.T) { metricsMock.On("RecordOverheadTime", metrics.PreBidder, mock.Anything).Once() metricsMock.On("RecordTMaxTimeout").Once() - bidderAdapter := bidderAdapter{ + bidderAdapter := BidderAdapter{ me: metricsMock, Client: server.Client(), } diff --git a/exchange/bidder_validate_bids.go b/exchange/bidder_validate_bids.go index 0afa32a3321..d028008132d 100644 --- a/exchange/bidder_validate_bids.go +++ b/exchange/bidder_validate_bids.go @@ -7,12 +7,12 @@ import ( "strings" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/currency" - "github.com/prebid/prebid-server/v2/exchange/entities" - "github.com/prebid/prebid-server/v2/experiment/adscert" - "github.com/prebid/prebid-server/v2/hooks/hookexecution" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/currency" + "github.com/prebid/prebid-server/v3/exchange/entities" + "github.com/prebid/prebid-server/v3/experiment/adscert" + "github.com/prebid/prebid-server/v3/hooks/hookexecution" + "github.com/prebid/prebid-server/v3/openrtb_ext" goCurrency "golang.org/x/text/currency" ) diff --git a/exchange/bidder_validate_bids_test.go b/exchange/bidder_validate_bids_test.go index a488bf81150..e14efec4023 100644 --- a/exchange/bidder_validate_bids_test.go +++ b/exchange/bidder_validate_bids_test.go @@ -5,12 +5,12 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/currency" - "github.com/prebid/prebid-server/v2/exchange/entities" - "github.com/prebid/prebid-server/v2/experiment/adscert" - "github.com/prebid/prebid-server/v2/hooks/hookexecution" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/currency" + "github.com/prebid/prebid-server/v3/exchange/entities" + "github.com/prebid/prebid-server/v3/experiment/adscert" + "github.com/prebid/prebid-server/v3/hooks/hookexecution" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/exchange/entities/entities.go b/exchange/entities/entities.go index c764fe82272..808125f1c1c 100644 --- a/exchange/entities/entities.go +++ b/exchange/entities/entities.go @@ -2,7 +2,7 @@ package entities import ( "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // PbsOrtbSeatBid is a SeatBid returned by an AdaptedBidder. diff --git a/exchange/events.go b/exchange/events.go index b20eea328f6..d52db53aac6 100644 --- a/exchange/events.go +++ b/exchange/events.go @@ -3,14 +3,14 @@ package exchange import ( "time" - "github.com/prebid/prebid-server/v2/exchange/entities" + "github.com/prebid/prebid-server/v3/exchange/entities" jsonpatch "gopkg.in/evanphx/json-patch.v4" - "github.com/prebid/prebid-server/v2/analytics" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/endpoints/events" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/analytics" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/endpoints/events" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) // eventTracking has configuration fields needed for adding event tracking to an auction response diff --git a/exchange/events_test.go b/exchange/events_test.go index a4ed587cd67..3f35ef517de 100644 --- a/exchange/events_test.go +++ b/exchange/events_test.go @@ -4,8 +4,8 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/exchange/entities" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/exchange/entities" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/exchange/exchange.go b/exchange/exchange.go index 5c27b0d3c5a..9ab91ee9ea3 100644 --- a/exchange/exchange.go +++ b/exchange/exchange.go @@ -14,31 +14,31 @@ import ( "strings" "time" - "github.com/prebid/prebid-server/v2/ortb" - "github.com/prebid/prebid-server/v2/privacy" - - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/adservertargeting" - "github.com/prebid/prebid-server/v2/bidadjustment" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/currency" - "github.com/prebid/prebid-server/v2/dsa" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/exchange/entities" - "github.com/prebid/prebid-server/v2/experiment/adscert" - "github.com/prebid/prebid-server/v2/firstpartydata" - "github.com/prebid/prebid-server/v2/floors" - "github.com/prebid/prebid-server/v2/gdpr" - "github.com/prebid/prebid-server/v2/hooks/hookexecution" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/metrics" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/prebid_cache_client" - "github.com/prebid/prebid-server/v2/stored_requests" - "github.com/prebid/prebid-server/v2/stored_responses" - "github.com/prebid/prebid-server/v2/usersync" - "github.com/prebid/prebid-server/v2/util/jsonutil" - "github.com/prebid/prebid-server/v2/util/maputil" + "github.com/prebid/prebid-server/v3/ortb" + "github.com/prebid/prebid-server/v3/privacy" + + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/adservertargeting" + "github.com/prebid/prebid-server/v3/bidadjustment" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/currency" + "github.com/prebid/prebid-server/v3/dsa" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/exchange/entities" + "github.com/prebid/prebid-server/v3/experiment/adscert" + "github.com/prebid/prebid-server/v3/firstpartydata" + "github.com/prebid/prebid-server/v3/floors" + "github.com/prebid/prebid-server/v3/gdpr" + "github.com/prebid/prebid-server/v3/hooks/hookexecution" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/metrics" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/prebid_cache_client" + "github.com/prebid/prebid-server/v3/stored_requests" + "github.com/prebid/prebid-server/v3/stored_responses" + "github.com/prebid/prebid-server/v3/usersync" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/maputil" "github.com/buger/jsonparser" "github.com/gofrs/uuid" @@ -95,6 +95,8 @@ type seatResponseExtra struct { // httpCalls is the list of debugging info. It should only be populated if the request.test == 1. // This will become response.ext.debug.httpcalls.{bidder} on the final Response. HttpCalls []*openrtb_ext.ExtHttpCall + // NonBid contains non bid reason information + NonBid *openrtb_ext.NonBid } type bidResponseWrapper struct { @@ -103,6 +105,7 @@ type bidResponseWrapper struct { bidder openrtb_ext.BidderName adapter openrtb_ext.BidderName bidderResponseStartTime time.Time + seatNonBidBuilder SeatNonBidBuilder } type BidIDGenerator interface { @@ -373,7 +376,8 @@ func (e *exchange) HoldAuction(ctx context.Context, r *AuctionRequest, debugLog fledge *openrtb_ext.Fledge anyBidsReturned bool // List of bidders we have requests for. - liveAdapters []openrtb_ext.BidderName + liveAdapters []openrtb_ext.BidderName + seatNonBidBuilder SeatNonBidBuilder = SeatNonBidBuilder{} ) if len(r.StoredAuctionResponses) > 0 { @@ -399,13 +403,15 @@ func (e *exchange) HoldAuction(ctx context.Context, r *AuctionRequest, debugLog fledge = extraRespInfo.fledge anyBidsReturned = extraRespInfo.bidsFound r.BidderResponseStartTime = extraRespInfo.bidderResponseStartTime + if extraRespInfo.seatNonBidBuilder != nil { + seatNonBidBuilder = extraRespInfo.seatNonBidBuilder + } } var ( auc *auction cacheErrs []error bidResponseExt *openrtb_ext.ExtBidResponse - seatNonBids = nonBids{} ) if anyBidsReturned { @@ -423,7 +429,7 @@ func (e *exchange) HoldAuction(ctx context.Context, r *AuctionRequest, debugLog if rejectedBid.Bids[0].Bid.DealID != "" { rejectionReason = ResponseRejectedBelowDealFloor } - seatNonBids.addBid(rejectedBid.Bids[0], int(rejectionReason), rejectedBid.Seat) + seatNonBidBuilder.rejectBid(rejectedBid.Bids[0], int(rejectionReason), rejectedBid.Seat) } } @@ -431,7 +437,7 @@ func (e *exchange) HoldAuction(ctx context.Context, r *AuctionRequest, debugLog //If includebrandcategory is present in ext then CE feature is on. if requestExtPrebid.Targeting != nil && requestExtPrebid.Targeting.IncludeBrandCategory != nil { var rejections []string - bidCategory, adapterBids, rejections, err = applyCategoryMapping(ctx, *requestExtPrebid.Targeting, adapterBids, e.categoriesFetcher, targData, &randomDeduplicateBidBooleanGenerator{}, &seatNonBids) + bidCategory, adapterBids, rejections, err = applyCategoryMapping(ctx, *requestExtPrebid.Targeting, adapterBids, e.categoriesFetcher, targData, &randomDeduplicateBidBooleanGenerator{}, &seatNonBidBuilder) if err != nil { return nil, fmt.Errorf("Error in category mapping : %s", err.Error()) } @@ -526,14 +532,14 @@ func (e *exchange) HoldAuction(ctx context.Context, r *AuctionRequest, debugLog e.bidValidationEnforcement.SetBannerCreativeMaxSize(r.Account.Validations) // Build the response - bidResponse := e.buildBidResponse(ctx, liveAdapters, adapterBids, r.BidRequestWrapper, adapterExtra, auc, bidResponseExt, cacheInstructions.returnCreative, r.ImpExtInfoMap, r.PubID, errs, &seatNonBids) + bidResponse := e.buildBidResponse(ctx, liveAdapters, adapterBids, r.BidRequestWrapper, adapterExtra, auc, bidResponseExt, cacheInstructions.returnCreative, r.ImpExtInfoMap, r.PubID, errs, &seatNonBidBuilder) bidResponse = adservertargeting.Apply(r.BidRequestWrapper, r.ResolvedBidRequest, bidResponse, r.QueryParams, bidResponseExt, r.Account.TruncateTargetAttribute) bidResponse.Ext, err = encodeBidResponseExt(bidResponseExt) if err != nil { return nil, err } - bidResponseExt = setSeatNonBid(bidResponseExt, seatNonBids) + bidResponseExt = setSeatNonBid(bidResponseExt, seatNonBidBuilder) return &AuctionResponse{ BidResponse: bidResponse, @@ -713,7 +719,7 @@ func (e *exchange) getAllBids( adapterBids := make(map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid, len(bidderRequests)) adapterExtra := make(map[openrtb_ext.BidderName]*seatResponseExtra, len(bidderRequests)) chBids := make(chan *bidResponseWrapper, len(bidderRequests)) - extraRespInfo := extraAuctionResponseInfo{} + extraRespInfo := extraAuctionResponseInfo{seatNonBidBuilder: SeatNonBidBuilder{}} e.me.RecordOverheadTime(metrics.MakeBidderRequests, time.Since(pbsRequestStartTime)) @@ -753,6 +759,7 @@ func (e *exchange) getAllBids( // Add in time reporting elapsed := time.Since(start) brw.adapterSeatBids = seatBids + brw.seatNonBidBuilder = extraBidderRespInfo.seatNonBidBuilder // Structure to record extra tracking data generated during bidding ae := new(seatResponseExtra) ae.ResponseTimeMillis = int(elapsed / time.Millisecond) @@ -805,6 +812,10 @@ 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 + + // collect adapter non bids + extraRespInfo.seatNonBidBuilder.append(brw.seatNonBidBuilder) + } return adapterBids, adapterExtra, extraRespInfo @@ -922,7 +933,7 @@ func errsToBidderWarnings(errs []error) []openrtb_ext.ExtBidderMessage { } // This piece takes all the bids supplied by the adapters and crafts an openRTB response to send back to the requester -func (e *exchange) buildBidResponse(ctx context.Context, liveAdapters []openrtb_ext.BidderName, adapterSeatBids map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid, bidRequest *openrtb_ext.RequestWrapper, adapterExtra map[openrtb_ext.BidderName]*seatResponseExtra, auc *auction, bidResponseExt *openrtb_ext.ExtBidResponse, returnCreative bool, impExtInfoMap map[string]ImpExtInfo, pubID string, errList []error, seatNonBids *nonBids) *openrtb2.BidResponse { +func (e *exchange) buildBidResponse(ctx context.Context, liveAdapters []openrtb_ext.BidderName, adapterSeatBids map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid, bidRequest *openrtb_ext.RequestWrapper, adapterExtra map[openrtb_ext.BidderName]*seatResponseExtra, auc *auction, bidResponseExt *openrtb_ext.ExtBidResponse, returnCreative bool, impExtInfoMap map[string]ImpExtInfo, pubID string, errList []error, seatNonBidBuilder *SeatNonBidBuilder) *openrtb2.BidResponse { bidResponse := new(openrtb2.BidResponse) bidResponse.ID = bidRequest.ID @@ -937,7 +948,7 @@ func (e *exchange) buildBidResponse(ctx context.Context, liveAdapters []openrtb_ for a, adapterSeatBids := range adapterSeatBids { //while processing every single bib, do we need to handle categories here? if adapterSeatBids != nil && len(adapterSeatBids.Bids) > 0 { - sb := e.makeSeatBid(adapterSeatBids, a, adapterExtra, auc, returnCreative, impExtInfoMap, bidRequest, bidResponseExt, pubID, seatNonBids) + sb := e.makeSeatBid(adapterSeatBids, a, adapterExtra, auc, returnCreative, impExtInfoMap, bidRequest, bidResponseExt, pubID, seatNonBidBuilder) seatBids = append(seatBids, *sb) bidResponse.Cur = adapterSeatBids.Currency } @@ -957,7 +968,7 @@ func encodeBidResponseExt(bidResponseExt *openrtb_ext.ExtBidResponse) ([]byte, e return buffer.Bytes(), err } -func applyCategoryMapping(ctx context.Context, targeting openrtb_ext.ExtRequestTargeting, seatBids map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid, categoriesFetcher stored_requests.CategoryFetcher, targData *targetData, booleanGenerator deduplicateChanceGenerator, seatNonBids *nonBids) (map[string]string, map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid, []string, error) { +func applyCategoryMapping(ctx context.Context, targeting openrtb_ext.ExtRequestTargeting, seatBids map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid, categoriesFetcher stored_requests.CategoryFetcher, targData *targetData, booleanGenerator deduplicateChanceGenerator, seatNonBidBuilder *SeatNonBidBuilder) (map[string]string, map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid, []string, error) { res := make(map[string]string) type bidDedupe struct { @@ -1019,7 +1030,7 @@ func applyCategoryMapping(ctx context.Context, targeting openrtb_ext.ExtRequestT //on receiving bids from adapters if no unique IAB category is returned or if no ad server category is returned discard the bid bidsToRemove = append(bidsToRemove, bidInd) rejections = updateRejections(rejections, bidID, "Bid did not contain a category") - seatNonBids.addBid(bid, int(ResponseRejectedCategoryMappingInvalid), string(bidderName)) + seatNonBidBuilder.rejectBid(bid, int(ResponseRejectedCategoryMappingInvalid), string(bidderName)) continue } if translateCategories { @@ -1256,14 +1267,14 @@ func (e *exchange) makeExtBidResponse(adapterBids map[openrtb_ext.BidderName]*en // Return an openrtb seatBid for a bidder // buildBidResponse is responsible for ensuring nil bid seatbids are not included -func (e *exchange) makeSeatBid(adapterBid *entities.PbsOrtbSeatBid, adapter openrtb_ext.BidderName, adapterExtra map[openrtb_ext.BidderName]*seatResponseExtra, auc *auction, returnCreative bool, impExtInfoMap map[string]ImpExtInfo, bidRequest *openrtb_ext.RequestWrapper, bidResponseExt *openrtb_ext.ExtBidResponse, pubID string, seatNonBids *nonBids) *openrtb2.SeatBid { +func (e *exchange) makeSeatBid(adapterBid *entities.PbsOrtbSeatBid, adapter openrtb_ext.BidderName, adapterExtra map[openrtb_ext.BidderName]*seatResponseExtra, auc *auction, returnCreative bool, impExtInfoMap map[string]ImpExtInfo, bidRequest *openrtb_ext.RequestWrapper, bidResponseExt *openrtb_ext.ExtBidResponse, pubID string, seatNonBidBuilder *SeatNonBidBuilder) *openrtb2.SeatBid { seatBid := &openrtb2.SeatBid{ Seat: adapter.String(), Group: 0, // Prebid cannot support roadblocking } var errList []error - seatBid.Bid, errList = e.makeBid(adapterBid.Bids, auc, returnCreative, impExtInfoMap, bidRequest, bidResponseExt, adapter, pubID, seatNonBids) + seatBid.Bid, errList = e.makeBid(adapterBid.Bids, auc, returnCreative, impExtInfoMap, bidRequest, bidResponseExt, adapter, pubID, seatNonBidBuilder) if len(errList) > 0 { adapterExtra[adapter].Errors = append(adapterExtra[adapter].Errors, errsToBidderErrors(errList)...) } @@ -1271,7 +1282,7 @@ func (e *exchange) makeSeatBid(adapterBid *entities.PbsOrtbSeatBid, adapter open return seatBid } -func (e *exchange) makeBid(bids []*entities.PbsOrtbBid, auc *auction, returnCreative bool, impExtInfoMap map[string]ImpExtInfo, bidRequest *openrtb_ext.RequestWrapper, bidResponseExt *openrtb_ext.ExtBidResponse, adapter openrtb_ext.BidderName, pubID string, seatNonBids *nonBids) ([]openrtb2.Bid, []error) { +func (e *exchange) makeBid(bids []*entities.PbsOrtbBid, auc *auction, returnCreative bool, impExtInfoMap map[string]ImpExtInfo, bidRequest *openrtb_ext.RequestWrapper, bidResponseExt *openrtb_ext.ExtBidResponse, adapter openrtb_ext.BidderName, pubID string, seatNonBidBuilder *SeatNonBidBuilder) ([]openrtb2.Bid, []error) { result := make([]openrtb2.Bid, 0, len(bids)) errs := make([]error, 0, 1) @@ -1283,12 +1294,12 @@ func (e *exchange) makeBid(bids []*entities.PbsOrtbBid, auc *auction, returnCrea } bidResponseExt.Warnings[adapter] = append(bidResponseExt.Warnings[adapter], dsaMessage) - seatNonBids.addBid(bid, int(ResponseRejectedGeneral), adapter.String()) + seatNonBidBuilder.rejectBid(bid, int(ResponseRejectedGeneral), adapter.String()) continue // Don't add bid to result } if e.bidValidationEnforcement.BannerCreativeMaxSize == config.ValidationEnforce && bid.BidType == openrtb_ext.BidTypeBanner { if !e.validateBannerCreativeSize(bid, bidResponseExt, adapter, pubID, e.bidValidationEnforcement.BannerCreativeMaxSize) { - seatNonBids.addBid(bid, int(ResponseRejectedCreativeSizeNotAllowed), adapter.String()) + seatNonBidBuilder.rejectBid(bid, int(ResponseRejectedCreativeSizeNotAllowed), adapter.String()) continue // Don't add bid to result } } else if e.bidValidationEnforcement.BannerCreativeMaxSize == config.ValidationWarn && bid.BidType == openrtb_ext.BidTypeBanner { @@ -1297,7 +1308,7 @@ func (e *exchange) makeBid(bids []*entities.PbsOrtbBid, auc *auction, returnCrea if _, ok := impExtInfoMap[bid.Bid.ImpID]; ok { if e.bidValidationEnforcement.SecureMarkup == config.ValidationEnforce && (bid.BidType == openrtb_ext.BidTypeBanner || bid.BidType == openrtb_ext.BidTypeVideo) { if !e.validateBidAdM(bid, bidResponseExt, adapter, pubID, e.bidValidationEnforcement.SecureMarkup) { - seatNonBids.addBid(bid, int(ResponseRejectedCreativeNotSecure), adapter.String()) + seatNonBidBuilder.rejectBid(bid, int(ResponseRejectedCreativeNotSecure), adapter.String()) continue // Don't add bid to result } } else if e.bidValidationEnforcement.SecureMarkup == config.ValidationWarn && (bid.BidType == openrtb_ext.BidTypeBanner || bid.BidType == openrtb_ext.BidTypeVideo) { @@ -1597,8 +1608,8 @@ func setErrorMessageSecureMarkup(validationType string) string { } // setSeatNonBid adds SeatNonBids within bidResponse.Ext.Prebid.SeatNonBid -func setSeatNonBid(bidResponseExt *openrtb_ext.ExtBidResponse, seatNonBids nonBids) *openrtb_ext.ExtBidResponse { - if len(seatNonBids.seatNonBidsMap) == 0 { +func setSeatNonBid(bidResponseExt *openrtb_ext.ExtBidResponse, seatNonBidBuilder SeatNonBidBuilder) *openrtb_ext.ExtBidResponse { + if len(seatNonBidBuilder) == 0 { return bidResponseExt } if bidResponseExt == nil { @@ -1608,6 +1619,6 @@ func setSeatNonBid(bidResponseExt *openrtb_ext.ExtBidResponse, seatNonBids nonBi bidResponseExt.Prebid = &openrtb_ext.ExtResponsePrebid{} } - bidResponseExt.Prebid.SeatNonBid = seatNonBids.get() + bidResponseExt.Prebid.SeatNonBid = seatNonBidBuilder.Slice() return bidResponseExt } diff --git a/exchange/exchange_test.go b/exchange/exchange_test.go index bab8dded1c5..87b53b101e0 100644 --- a/exchange/exchange_test.go +++ b/exchange/exchange_test.go @@ -20,30 +20,30 @@ import ( "github.com/buger/jsonparser" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/currency" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/exchange/entities" - "github.com/prebid/prebid-server/v2/experiment/adscert" - "github.com/prebid/prebid-server/v2/gdpr" - "github.com/prebid/prebid-server/v2/hooks" - "github.com/prebid/prebid-server/v2/hooks/hookexecution" - "github.com/prebid/prebid-server/v2/hooks/hookstage" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/metrics" - metricsConf "github.com/prebid/prebid-server/v2/metrics/config" - metricsConfig "github.com/prebid/prebid-server/v2/metrics/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/ortb" - pbc "github.com/prebid/prebid-server/v2/prebid_cache_client" - "github.com/prebid/prebid-server/v2/privacy" - "github.com/prebid/prebid-server/v2/stored_requests" - "github.com/prebid/prebid-server/v2/stored_requests/backends/file_fetcher" - "github.com/prebid/prebid-server/v2/stored_responses" - "github.com/prebid/prebid-server/v2/usersync" - "github.com/prebid/prebid-server/v2/util/jsonutil" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/currency" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/exchange/entities" + "github.com/prebid/prebid-server/v3/experiment/adscert" + "github.com/prebid/prebid-server/v3/gdpr" + "github.com/prebid/prebid-server/v3/hooks" + "github.com/prebid/prebid-server/v3/hooks/hookexecution" + "github.com/prebid/prebid-server/v3/hooks/hookstage" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/metrics" + metricsConf "github.com/prebid/prebid-server/v3/metrics/config" + metricsConfig "github.com/prebid/prebid-server/v3/metrics/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/ortb" + pbc "github.com/prebid/prebid-server/v3/prebid_cache_client" + "github.com/prebid/prebid-server/v3/privacy" + "github.com/prebid/prebid-server/v3/stored_requests" + "github.com/prebid/prebid-server/v3/stored_requests/backends/file_fetcher" + "github.com/prebid/prebid-server/v3/stored_responses" + "github.com/prebid/prebid-server/v3/usersync" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/ptrutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" jsonpatch "gopkg.in/evanphx/json-patch.v4" @@ -172,7 +172,7 @@ func TestCharacterEscape(t *testing.T) { var errList []error // 4) Build bid response - bidResp := e.buildBidResponse(context.Background(), liveAdapters, adapterBids, bidRequest, adapterExtra, nil, nil, true, nil, "", errList, &nonBids{}) + bidResp := e.buildBidResponse(context.Background(), liveAdapters, adapterBids, bidRequest, adapterExtra, nil, nil, true, nil, "", errList, &SeatNonBidBuilder{}) // 5) Assert we have no errors and one '&' character as we are supposed to if len(errList) > 0 { @@ -1343,7 +1343,7 @@ func TestGetBidCacheInfoEndToEnd(t *testing.T) { var errList []error // 4) Build bid response - bid_resp := e.buildBidResponse(context.Background(), liveAdapters, adapterBids, bidRequest, adapterExtra, auc, nil, true, nil, "", errList, &nonBids{}) + bid_resp := e.buildBidResponse(context.Background(), liveAdapters, adapterBids, bidRequest, adapterExtra, auc, nil, true, nil, "", errList, &SeatNonBidBuilder{}) expectedBidResponse := &openrtb2.BidResponse{ SeatBid: []openrtb2.SeatBid{ @@ -1433,7 +1433,7 @@ func TestBidReturnsCreative(t *testing.T) { //Run tests for _, test := range testCases { - resultingBids, resultingErrs := e.makeBid(sampleBids, sampleAuction, test.inReturnCreative, nil, &openrtb_ext.RequestWrapper{}, nil, "", "", &nonBids{}) + resultingBids, resultingErrs := e.makeBid(sampleBids, sampleAuction, test.inReturnCreative, nil, &openrtb_ext.RequestWrapper{}, nil, "", "", &SeatNonBidBuilder{}) assert.Equal(t, 0, len(resultingErrs), "%s. Test should not return errors \n", test.description) assert.Equal(t, test.expectedCreativeMarkup, resultingBids[0].AdM, "%s. Ad markup string doesn't match expected \n", test.description) @@ -1718,7 +1718,7 @@ func TestBidResponseCurrency(t *testing.T) { } // Run tests for i := range testCases { - actualBidResp := e.buildBidResponse(context.Background(), liveAdapters, testCases[i].adapterBids, bidRequest, adapterExtra, nil, bidResponseExt, true, nil, "", errList, &nonBids{}) + actualBidResp := e.buildBidResponse(context.Background(), liveAdapters, testCases[i].adapterBids, bidRequest, adapterExtra, nil, bidResponseExt, true, nil, "", errList, &SeatNonBidBuilder{}) assert.Equalf(t, testCases[i].expectedBidResponse, actualBidResp, fmt.Sprintf("[TEST_FAILED] Objects must be equal for test: %s \n Expected: >>%s<< \n Actual: >>%s<< ", testCases[i].description, testCases[i].expectedBidResponse.Ext, actualBidResp.Ext)) } } @@ -1786,7 +1786,7 @@ func TestBidResponseImpExtInfo(t *testing.T) { expectedBidResponseExt := `{"origbidcpm":0,"prebid":{"meta":{"adaptercode":"appnexus"},"type":"video","passthrough":{"imp_passthrough_val":1}},"storedrequestattributes":{"h":480,"mimes":["video/mp4"]}}` - actualBidResp := e.buildBidResponse(context.Background(), liveAdapters, adapterBids, bidRequest, nil, nil, nil, true, impExtInfo, "", errList, &nonBids{}) + actualBidResp := e.buildBidResponse(context.Background(), liveAdapters, adapterBids, bidRequest, nil, nil, nil, true, impExtInfo, "", errList, &SeatNonBidBuilder{}) resBidExt := string(actualBidResp.SeatBid[0].Bid[0].Ext) assert.Equalf(t, expectedBidResponseExt, resBidExt, "Expected bid response extension is incorrect") @@ -2146,7 +2146,7 @@ func runSpec(t *testing.T, filename string, spec *exchangeSpec) { if spec.BidIDGenerator != nil { bidIdGenerator = spec.BidIDGenerator } - ex := newExchangeForTests(t, filename, spec.OutgoingRequests, aliases, privacyConfig, bidIdGenerator, spec.HostSChainFlag, spec.FloorsEnabled, spec.HostConfigBidValidation, spec.Server) + ex := newExchangeForTests(t, filename, aliases, privacyConfig, bidIdGenerator, spec) biddersInAuction := findBiddersInAuction(t, filename, &spec.IncomingRequest.OrtbRequest) debugLog := &DebugLog{} if spec.DebugLog != nil { @@ -2374,11 +2374,11 @@ func extractResponseTimes(t *testing.T, context string, bid *openrtb2.BidRespons } } -func newExchangeForTests(t *testing.T, filename string, expectations map[string]*bidderSpec, aliases map[string]string, privacyConfig config.Privacy, bidIDGenerator BidIDGenerator, hostSChainFlag, floorsFlag bool, hostBidValidation config.Validations, server exchangeServer) Exchange { - bidderAdapters := make(map[openrtb_ext.BidderName]AdaptedBidder, len(expectations)) - bidderInfos := make(config.BidderInfos, len(expectations)) +func newExchangeForTests(t *testing.T, filename string, aliases map[string]string, privacyConfig config.Privacy, bidIDGenerator BidIDGenerator, exSpec *exchangeSpec) Exchange { + bidderAdapters := make(map[openrtb_ext.BidderName]AdaptedBidder, len(exSpec.OutgoingRequests)) + bidderInfos := make(config.BidderInfos, len(exSpec.OutgoingRequests)) for _, bidderName := range openrtb_ext.CoreBidderNames() { - if spec, ok := expectations[string(bidderName)]; ok { + if spec, ok := exSpec.OutgoingRequests[string(bidderName)]; ok { bidderAdapters[bidderName] = &validatingBidder{ t: t, fileName: filename, @@ -2386,14 +2386,18 @@ func newExchangeForTests(t *testing.T, filename string, expectations map[string] expectations: map[string]*bidderRequest{string(bidderName): spec.ExpectedRequest}, mockResponses: map[string]bidderResponse{string(bidderName): spec.MockResponse}, } - bidderInfos[string(bidderName)] = config.BidderInfo{ModifyingVastXmlAllowed: spec.ModifyingVastXmlAllowed} + ortbVersion, _ := exSpec.ORTBVersion[string(bidderName)] + bidderInfos[string(bidderName)] = config.BidderInfo{ + ModifyingVastXmlAllowed: spec.ModifyingVastXmlAllowed, + OpenRTB: &config.OpenRTBInfo{Version: ortbVersion}, + } } else { bidderInfos[string(bidderName)] = config.BidderInfo{} } } for alias, coreBidder := range aliases { - if spec, ok := expectations[alias]; ok { + if spec, ok := exSpec.OutgoingRequests[alias]; ok { if bidder, ok := bidderAdapters[openrtb_ext.BidderName(coreBidder)]; ok { bidder.(*validatingBidder).expectations[alias] = spec.ExpectedRequest bidder.(*validatingBidder).mockResponses[alias] = spec.MockResponse @@ -2431,7 +2435,7 @@ func newExchangeForTests(t *testing.T, filename string, expectations map[string] } var hostSChainNode *openrtb2.SupplyChainNode - if hostSChainFlag { + if exSpec.HostSChainFlag { hostSChainNode = &openrtb2.SupplyChainNode{ ASI: "pbshostcompany.com", SID: "00001", RID: "BidRequest", HP: openrtb2.Int8Ptr(1), } @@ -2469,10 +2473,10 @@ func newExchangeForTests(t *testing.T, filename string, expectations map[string] externalURL: "http://localhost", bidIDGenerator: bidIDGenerator, hostSChainNode: hostSChainNode, - server: config.Server{ExternalUrl: server.ExternalUrl, GvlID: server.GvlID, DataCenter: server.DataCenter}, - bidValidationEnforcement: hostBidValidation, + server: config.Server{ExternalUrl: exSpec.Server.ExternalUrl, GvlID: exSpec.Server.GvlID, DataCenter: exSpec.Server.DataCenter}, + bidValidationEnforcement: exSpec.HostConfigBidValidation, requestSplitter: requestSplitter, - priceFloorEnabled: floorsFlag, + priceFloorEnabled: exSpec.FloorsEnabled, priceFloorFetcher: &mockPriceFloorFetcher{}, } } @@ -2607,7 +2611,7 @@ func TestCategoryMapping(t *testing.T) { adapterBids[bidderName1] = &seatBid - bidCategory, adapterBids, rejections, err := applyCategoryMapping(context.TODO(), *requestExt.Prebid.Targeting, adapterBids, categoriesFetcher, targData, &randomDeduplicateBidBooleanGenerator{}, &nonBids{}) + bidCategory, adapterBids, rejections, err := applyCategoryMapping(context.TODO(), *requestExt.Prebid.Targeting, adapterBids, categoriesFetcher, targData, &randomDeduplicateBidBooleanGenerator{}, &SeatNonBidBuilder{}) assert.Equal(t, nil, err, "Category mapping error should be empty") assert.Equal(t, 1, len(rejections), "There should be 1 bid rejection message") @@ -2662,7 +2666,7 @@ func TestCategoryMappingNoIncludeBrandCategory(t *testing.T) { adapterBids[bidderName1] = &seatBid - bidCategory, adapterBids, rejections, err := applyCategoryMapping(context.TODO(), *requestExt.Prebid.Targeting, adapterBids, categoriesFetcher, targData, &randomDeduplicateBidBooleanGenerator{}, &nonBids{}) + bidCategory, adapterBids, rejections, err := applyCategoryMapping(context.TODO(), *requestExt.Prebid.Targeting, adapterBids, categoriesFetcher, targData, &randomDeduplicateBidBooleanGenerator{}, &SeatNonBidBuilder{}) assert.Equal(t, nil, err, "Category mapping error should be empty") assert.Empty(t, rejections, "There should be no bid rejection messages") @@ -2714,7 +2718,7 @@ func TestCategoryMappingTranslateCategoriesNil(t *testing.T) { adapterBids[bidderName1] = &seatBid - bidCategory, adapterBids, rejections, err := applyCategoryMapping(context.TODO(), *requestExt.Prebid.Targeting, adapterBids, categoriesFetcher, targData, &randomDeduplicateBidBooleanGenerator{}, &nonBids{}) + bidCategory, adapterBids, rejections, err := applyCategoryMapping(context.TODO(), *requestExt.Prebid.Targeting, adapterBids, categoriesFetcher, targData, &randomDeduplicateBidBooleanGenerator{}, &SeatNonBidBuilder{}) assert.Equal(t, nil, err, "Category mapping error should be empty") assert.Equal(t, 1, len(rejections), "There should be 1 bid rejection message") @@ -2796,7 +2800,7 @@ func TestCategoryMappingTranslateCategoriesFalse(t *testing.T) { adapterBids[bidderName1] = &seatBid - bidCategory, adapterBids, rejections, err := applyCategoryMapping(context.TODO(), *requestExt.Prebid.Targeting, adapterBids, categoriesFetcher, targData, &randomDeduplicateBidBooleanGenerator{}, &nonBids{}) + bidCategory, adapterBids, rejections, err := applyCategoryMapping(context.TODO(), *requestExt.Prebid.Targeting, adapterBids, categoriesFetcher, targData, &randomDeduplicateBidBooleanGenerator{}, &SeatNonBidBuilder{}) assert.Equal(t, nil, err, "Category mapping error should be empty") assert.Empty(t, rejections, "There should be no bid rejection messages") @@ -2874,7 +2878,7 @@ func TestCategoryDedupe(t *testing.T) { }, } deduplicateGenerator := fakeBooleanGenerator{value: tt.dedupeGeneratorValue} - bidCategory, adapterBids, rejections, err := applyCategoryMapping(context.TODO(), *requestExt.Prebid.Targeting, adapterBids, categoriesFetcher, targData, &deduplicateGenerator, &nonBids{}) + bidCategory, adapterBids, rejections, err := applyCategoryMapping(context.TODO(), *requestExt.Prebid.Targeting, adapterBids, categoriesFetcher, targData, &deduplicateGenerator, &SeatNonBidBuilder{}) assert.Nil(t, err) assert.Equal(t, 3, len(rejections)) @@ -2943,7 +2947,7 @@ func TestNoCategoryDedupe(t *testing.T) { adapterBids[bidderName1] = &seatBid - bidCategory, adapterBids, rejections, err := applyCategoryMapping(context.TODO(), *requestExt.Prebid.Targeting, adapterBids, categoriesFetcher, targData, &randomDeduplicateBidBooleanGenerator{}, &nonBids{}) + bidCategory, adapterBids, rejections, err := applyCategoryMapping(context.TODO(), *requestExt.Prebid.Targeting, adapterBids, categoriesFetcher, targData, &randomDeduplicateBidBooleanGenerator{}, &SeatNonBidBuilder{}) assert.Equal(t, nil, err, "Category mapping error should be empty") assert.Equal(t, 2, len(rejections), "There should be 2 bid rejection messages") @@ -3008,7 +3012,7 @@ func TestCategoryMappingBidderName(t *testing.T) { adapterBids[bidderName1] = &seatBid1 adapterBids[bidderName2] = &seatBid2 - bidCategory, adapterBids, rejections, err := applyCategoryMapping(context.TODO(), *requestExt.Prebid.Targeting, adapterBids, categoriesFetcher, targData, &randomDeduplicateBidBooleanGenerator{}, &nonBids{}) + bidCategory, adapterBids, rejections, err := applyCategoryMapping(context.TODO(), *requestExt.Prebid.Targeting, adapterBids, categoriesFetcher, targData, &randomDeduplicateBidBooleanGenerator{}, &SeatNonBidBuilder{}) assert.NoError(t, err, "Category mapping error should be empty") assert.Empty(t, rejections, "There should be 0 bid rejection messages") @@ -3062,7 +3066,7 @@ func TestCategoryMappingBidderNameNoCategories(t *testing.T) { adapterBids[bidderName1] = &seatBid1 adapterBids[bidderName2] = &seatBid2 - bidCategory, adapterBids, rejections, err := applyCategoryMapping(context.TODO(), *requestExt.Prebid.Targeting, adapterBids, categoriesFetcher, targData, &randomDeduplicateBidBooleanGenerator{}, &nonBids{}) + bidCategory, adapterBids, rejections, err := applyCategoryMapping(context.TODO(), *requestExt.Prebid.Targeting, adapterBids, categoriesFetcher, targData, &randomDeduplicateBidBooleanGenerator{}, &SeatNonBidBuilder{}) assert.NoError(t, err, "Category mapping error should be empty") assert.Empty(t, rejections, "There should be 0 bid rejection messages") @@ -3163,7 +3167,7 @@ func TestBidRejectionErrors(t *testing.T) { adapterBids[bidderName] = &seatBid - bidCategory, adapterBids, rejections, err := applyCategoryMapping(context.TODO(), *test.reqExt.Prebid.Targeting, adapterBids, categoriesFetcher, targData, &randomDeduplicateBidBooleanGenerator{}, &nonBids{}) + bidCategory, adapterBids, rejections, err := applyCategoryMapping(context.TODO(), *test.reqExt.Prebid.Targeting, adapterBids, categoriesFetcher, targData, &randomDeduplicateBidBooleanGenerator{}, &SeatNonBidBuilder{}) if len(test.expectedCatDur) > 0 { // Bid deduplication case @@ -3226,7 +3230,7 @@ func TestCategoryMappingTwoBiddersOneBidEachNoCategorySamePrice(t *testing.T) { adapterBids[bidderNameApn1] = &seatBidApn1 adapterBids[bidderNameApn2] = &seatBidApn2 - bidCategory, _, rejections, err := applyCategoryMapping(context.TODO(), *requestExt.Prebid.Targeting, adapterBids, categoriesFetcher, targData, &randomDeduplicateBidBooleanGenerator{}, &nonBids{}) + bidCategory, _, rejections, err := applyCategoryMapping(context.TODO(), *requestExt.Prebid.Targeting, adapterBids, categoriesFetcher, targData, &randomDeduplicateBidBooleanGenerator{}, &SeatNonBidBuilder{}) assert.NoError(t, err, "Category mapping error should be empty") assert.Len(t, rejections, 1, "There should be 1 bid rejection message") @@ -3310,7 +3314,7 @@ func TestCategoryMappingTwoBiddersManyBidsEachNoCategorySamePrice(t *testing.T) adapterBids[bidderNameApn1] = &seatBidApn1 adapterBids[bidderNameApn2] = &seatBidApn2 - _, adapterBids, rejections, err := applyCategoryMapping(context.TODO(), *requestExt.Prebid.Targeting, adapterBids, categoriesFetcher, targData, &fakeBooleanGenerator{value: true}, &nonBids{}) + _, adapterBids, rejections, err := applyCategoryMapping(context.TODO(), *requestExt.Prebid.Targeting, adapterBids, categoriesFetcher, targData, &fakeBooleanGenerator{value: true}, &SeatNonBidBuilder{}) assert.NoError(t, err, "Category mapping error should be empty") @@ -4774,7 +4778,7 @@ func TestMakeBidWithValidation(t *testing.T) { givenBids []*entities.PbsOrtbBid givenSeat openrtb_ext.BidderName expectedNumOfBids int - expectedNonBids *nonBids + expectedNonBids *SeatNonBidBuilder expectedNumDebugErrors int expectedNumDebugWarnings int }{ @@ -4785,15 +4789,13 @@ func TestMakeBidWithValidation(t *testing.T) { givenBids: []*entities.PbsOrtbBid{{Bid: &openrtb2.Bid{Ext: json.RawMessage(`{"dsa": {"adrender":1}}`)}}, {Bid: &openrtb2.Bid{}}}, givenSeat: "pubmatic", expectedNumOfBids: 1, - expectedNonBids: &nonBids{ - seatNonBidsMap: map[string][]openrtb_ext.NonBid{ - "pubmatic": { - { - StatusCode: 300, - Ext: openrtb_ext.NonBidExt{ - Prebid: openrtb_ext.ExtResponseNonBidPrebid{ - Bid: openrtb_ext.NonBidObject{}, - }, + expectedNonBids: &SeatNonBidBuilder{ + "pubmatic": { + { + StatusCode: 300, + Ext: &openrtb_ext.NonBidExt{ + Prebid: openrtb_ext.ExtResponseNonBidPrebid{ + Bid: openrtb_ext.NonBidObject{}, }, }, }, @@ -4807,17 +4809,15 @@ func TestMakeBidWithValidation(t *testing.T) { givenBids: []*entities.PbsOrtbBid{{Bid: &openrtb2.Bid{W: 200, H: 200}, BidType: openrtb_ext.BidTypeBanner}, {Bid: &openrtb2.Bid{W: 50, H: 50}, BidType: openrtb_ext.BidTypeBanner}}, givenSeat: "pubmatic", expectedNumOfBids: 1, - expectedNonBids: &nonBids{ - seatNonBidsMap: map[string][]openrtb_ext.NonBid{ - "pubmatic": { - { - StatusCode: 351, - Ext: openrtb_ext.NonBidExt{ - Prebid: openrtb_ext.ExtResponseNonBidPrebid{ - Bid: openrtb_ext.NonBidObject{ - W: 200, - H: 200, - }, + expectedNonBids: &SeatNonBidBuilder{ + "pubmatic": { + { + StatusCode: 351, + Ext: &openrtb_ext.NonBidExt{ + Prebid: openrtb_ext.ExtResponseNonBidPrebid{ + Bid: openrtb_ext.NonBidObject{ + W: 200, + H: 200, }, }, }, @@ -4832,7 +4832,7 @@ func TestMakeBidWithValidation(t *testing.T) { givenBids: []*entities.PbsOrtbBid{{Bid: &openrtb2.Bid{W: 200, H: 200}, BidType: openrtb_ext.BidTypeBanner}, {Bid: &openrtb2.Bid{W: 50, H: 50}, BidType: openrtb_ext.BidTypeBanner}}, givenSeat: "pubmatic", expectedNumOfBids: 2, - expectedNonBids: &nonBids{}, + expectedNonBids: &SeatNonBidBuilder{}, expectedNumDebugErrors: 1, }, { @@ -4841,12 +4841,15 @@ func TestMakeBidWithValidation(t *testing.T) { givenBids: []*entities.PbsOrtbBid{{Bid: &openrtb2.Bid{AdM: "http://domain.com/invalid", ImpID: "1"}, BidType: openrtb_ext.BidTypeBanner}, {Bid: &openrtb2.Bid{AdM: "https://domain.com/valid", ImpID: "2"}, BidType: openrtb_ext.BidTypeBanner}}, givenSeat: "pubmatic", expectedNumOfBids: 1, - expectedNonBids: &nonBids{ - seatNonBidsMap: map[string][]openrtb_ext.NonBid{ - "pubmatic": { - { - ImpId: "1", - StatusCode: 352, + expectedNonBids: &SeatNonBidBuilder{ + "pubmatic": { + { + ImpId: "1", + StatusCode: 352, + Ext: &openrtb_ext.NonBidExt{ + Prebid: openrtb_ext.ExtResponseNonBidPrebid{ + Bid: openrtb_ext.NonBidObject{}, + }, }, }, }, @@ -4859,7 +4862,7 @@ func TestMakeBidWithValidation(t *testing.T) { givenBids: []*entities.PbsOrtbBid{{Bid: &openrtb2.Bid{AdM: "http://domain.com/invalid", ImpID: "1"}, BidType: openrtb_ext.BidTypeBanner}, {Bid: &openrtb2.Bid{AdM: "https://domain.com/valid", ImpID: "2"}, BidType: openrtb_ext.BidTypeBanner}}, givenSeat: "pubmatic", expectedNumOfBids: 2, - expectedNonBids: &nonBids{}, + expectedNonBids: &SeatNonBidBuilder{}, expectedNumDebugErrors: 1, }, { @@ -4868,7 +4871,7 @@ func TestMakeBidWithValidation(t *testing.T) { givenBids: []*entities.PbsOrtbBid{{Bid: &openrtb2.Bid{AdM: "http://domain.com/invalid"}, BidType: openrtb_ext.BidTypeBanner}, {Bid: &openrtb2.Bid{AdM: "https://domain.com/valid"}, BidType: openrtb_ext.BidTypeBanner}}, givenSeat: "pubmatic", expectedNumOfBids: 2, - expectedNonBids: &nonBids{}, + expectedNonBids: &SeatNonBidBuilder{}, }, { name: "Creative_size_validation_skipped,_Adm_Validation_enforced,_one_of_two_bids_has_invalid_dimensions", @@ -4876,7 +4879,7 @@ func TestMakeBidWithValidation(t *testing.T) { givenBids: []*entities.PbsOrtbBid{{Bid: &openrtb2.Bid{W: 200, H: 200}, BidType: openrtb_ext.BidTypeBanner}, {Bid: &openrtb2.Bid{W: 50, H: 50}, BidType: openrtb_ext.BidTypeBanner}}, givenSeat: "pubmatic", expectedNumOfBids: 2, - expectedNonBids: &nonBids{}, + expectedNonBids: &SeatNonBidBuilder{}, }, } @@ -4925,7 +4928,7 @@ func TestMakeBidWithValidation(t *testing.T) { } e.bidValidationEnforcement = test.givenValidations sampleBids := test.givenBids - nonBids := &nonBids{} + nonBids := &SeatNonBidBuilder{} resultingBids, resultingErrs := e.makeBid(sampleBids, sampleAuction, true, ImpExtInfoMap, bidRequest, bidExtResponse, test.givenSeat, "", nonBids) assert.Equal(t, 0, len(resultingErrs)) @@ -5514,6 +5517,7 @@ type exchangeSpec struct { MultiBid *multiBidSpec `json:"multiBid,omitempty"` Server exchangeServer `json:"server,omitempty"` AccountPrivacy config.AccountPrivacy `json:"accountPrivacy,omitempty"` + ORTBVersion map[string]string `json:"ortbversion"` } type multiBidSpec struct { @@ -5568,9 +5572,10 @@ type bidderSeatBid struct { // bidderBid is basically a subset of entities.PbsOrtbBid from exchange/bidder.go. // See the comment on bidderSeatBid for more info. type bidderBid struct { - Bid *openrtb2.Bid `json:"ortbBid,omitempty"` - Type string `json:"bidType,omitempty"` - Meta *openrtb_ext.ExtBidPrebidMeta `json:"bidMeta,omitempty"` + Bid *openrtb2.Bid `json:"ortbBid,omitempty"` + Type string `json:"bidType,omitempty"` + BidVideo *openrtb_ext.ExtBidPrebidVideo `json:"bidVideo,omitempty"` + Meta *openrtb_ext.ExtBidPrebidMeta `json:"bidMeta,omitempty"` } type mockIdFetcher map[string]string @@ -5617,6 +5622,7 @@ func (b *validatingBidder) requestBid(ctx context.Context, bidderRequest BidderR bids[i] = &entities.PbsOrtbBid{ OriginalBidCPM: mockSeatBid.Bids[i].Bid.Price, Bid: mockSeatBid.Bids[i].Bid, + BidVideo: mockSeatBid.Bids[i].BidVideo, BidType: openrtb_ext.BidType(mockSeatBid.Bids[i].Type), BidMeta: mockSeatBid.Bids[i].Meta, } @@ -6058,7 +6064,7 @@ func TestSelectNewDuration(t *testing.T) { func TestSetSeatNonBid(t *testing.T) { type args struct { bidResponseExt *openrtb_ext.ExtBidResponse - seatNonBids nonBids + seatNonBids SeatNonBidBuilder } tests := []struct { name string @@ -6067,12 +6073,12 @@ func TestSetSeatNonBid(t *testing.T) { }{ { name: "empty-seatNonBidsMap", - args: args{seatNonBids: nonBids{}, bidResponseExt: nil}, + args: args{seatNonBids: SeatNonBidBuilder{}, bidResponseExt: nil}, want: nil, }, { name: "nil-bidResponseExt", - args: args{seatNonBids: nonBids{seatNonBidsMap: map[string][]openrtb_ext.NonBid{"key": nil}}, bidResponseExt: nil}, + args: args{seatNonBids: SeatNonBidBuilder{"key": nil}, bidResponseExt: nil}, want: &openrtb_ext.ExtBidResponse{ Prebid: &openrtb_ext.ExtResponsePrebid{ SeatNonBid: []openrtb_ext.SeatNonBid{{ diff --git a/exchange/exchangetest/append-bidder-names.json b/exchange/exchangetest/append-bidder-names.json index bc45321303f..0be1fdca522 100644 --- a/exchange/exchangetest/append-bidder-names.json +++ b/exchange/exchangetest/append-bidder-names.json @@ -148,10 +148,14 @@ "hb_cache_path_appnex": "/pbcache/endpoint", "hb_pb": "0.20", "hb_pb_appnexus": "0.20", - "hb_pb_cat_dur": "0.20_VideoGames_0s_appnexus", - "hb_pb_cat_dur_appnex": "0.20_VideoGames_0s_appnexus", + "hb_pb_cat_dur": "0.20_VideoGames_30s_appnexus", + "hb_pb_cat_dur_appnex": "0.20_VideoGames_30s_appnexus", "hb_size": "200x250", "hb_size_appnexus": "200x250" + }, + "video": { + "duration": 30, + "primary_category": "" } } } diff --git a/exchange/exchangetest/ccpa-featureflag-on.json b/exchange/exchangetest/ccpa-featureflag-on.json index 0c452098da8..c6d37ed91e4 100644 --- a/exchange/exchangetest/ccpa-featureflag-on.json +++ b/exchange/exchangetest/ccpa-featureflag-on.json @@ -1,5 +1,8 @@ { "enforceCcpa": true, + "ortbversion": { + "appnexus":"2.6" + }, "incomingRequest": { "ortbRequest": { "id": "some-request-id", @@ -26,9 +29,7 @@ } ], "regs": { - "ext": { - "us_privacy": "1-Y-" - } + "us_privacy": "1-Y-" }, "user": { "buyeruid": "some-buyer-id" @@ -59,9 +60,7 @@ } ], "regs": { - "ext": { - "us_privacy": "1-Y-" - } + "us_privacy": "1-Y-" }, "user": {} } diff --git a/exchange/exchangetest/debuglog_disabled.json b/exchange/exchangetest/debuglog_disabled.json index ce0669cf6fb..4b1ad744be4 100644 --- a/exchange/exchangetest/debuglog_disabled.json +++ b/exchange/exchangetest/debuglog_disabled.json @@ -157,10 +157,14 @@ "hb_cache_path_appnex": "/pbcache/endpoint", "hb_pb": "0.20", "hb_pb_appnexus": "0.20", - "hb_pb_cat_dur": "0.20_VideoGames_0s", - "hb_pb_cat_dur_appnex": "0.20_VideoGames_0s", + "hb_pb_cat_dur": "0.20_VideoGames_30s", + "hb_pb_cat_dur_appnex": "0.20_VideoGames_30s", "hb_size": "200x250", "hb_size_appnexus": "200x250" + }, + "video": { + "duration": 30, + "primary_category": "" } } } diff --git a/exchange/exchangetest/debuglog_enabled.json b/exchange/exchangetest/debuglog_enabled.json index 71a0bc06e96..faf3834a655 100644 --- a/exchange/exchangetest/debuglog_enabled.json +++ b/exchange/exchangetest/debuglog_enabled.json @@ -159,10 +159,14 @@ "hb_cache_path_appnex": "/pbcache/endpoint", "hb_pb": "0.20", "hb_pb_appnexus": "0.20", - "hb_pb_cat_dur": "0.20_VideoGames_0s", - "hb_pb_cat_dur_appnex": "0.20_VideoGames_0s", + "hb_pb_cat_dur": "0.20_VideoGames_30s", + "hb_pb_cat_dur_appnex": "0.20_VideoGames_30s", "hb_size": "200x250", "hb_size_appnexus": "200x250" + }, + "video": { + "duration": 30, + "primary_category": "" } } } diff --git a/exchange/exchangetest/eidpermissions-denied.json b/exchange/exchangetest/eidpermissions-denied.json index eb3e216ecba..d7b5eeea43d 100644 --- a/exchange/exchangetest/eidpermissions-denied.json +++ b/exchange/exchangetest/eidpermissions-denied.json @@ -6,18 +6,16 @@ "page": "test.somepage.com" }, "user": { - "ext": { - "eids": [ - { - "source": "source1", - "uids": [ - { - "id": "id1" - } - ] - } - ] - } + "eids": [ + { + "source": "source1", + "uids": [ + { + "id": "id1" + } + ] + } + ] }, "ext": { "prebid": { diff --git a/exchange/exchangetest/firstpartydata-multibidder-user-eids.json b/exchange/exchangetest/firstpartydata-multibidder-user-eids.json new file mode 100644 index 00000000000..f16907dcdb2 --- /dev/null +++ b/exchange/exchangetest/firstpartydata-multibidder-user-eids.json @@ -0,0 +1,239 @@ +{ + "requestType": "openrtb2-web", + "ortbversion": { + "appnexus":"2.6", + "rubicon":"2.6" + }, + "incomingRequest": { + "ortbRequest": { + "id": "some-request-id", + "site": { + "page": "test.somepage.com" + }, + "user": { + "id": "reqUserID", + "keywords": "userKeyword!", + "eids": [ + { + "source": "reqeid1", + "uids": [ + { + "id": "reqeiduid1" + } + ] + }, + { + "source": "reqieid2", + "uids": [ + { + "id": "reqeiduid2" + } + ] + } + ] + }, + "imp": [ + { + "id": "some-imp-id", + "banner": { + "format": [ + { + "w": 600, + "h": 500 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "prebid": { + "bidder": { + "appnexus": { + "placementId": 1 + }, + "rubicon": { + "accountId": 1, + "siteId": 2, + "zoneId": 3 + } + } + } + } + } + ], + "ext": { + "prebid": { + "data": { + "eidpermissions": [ + { + "source": "reqeid1", + "bidders": [ + "rubicon" + ] + } + ], + "bidders": [ + "appnexus", + "rubicon" + ] + }, + "bidderconfig": [ + { + "bidders": [ + "appnexus" + ], + "config": { + "ortb2": { + "site": { + "domain": "fpd_appnexus_site_domain", + "page": "fpd_appnexus_site_page" + } + } + } + }, + { + "bidders": [ + "rubicon" + ], + "config": { + "ortb2": { + "user": { + "id": "fpdSiteId!4", + "yob": 2000, + "keywords": "fpd keywords", + "eids": [ + { + "source": "fpdeid1", + "uids": [ + { + "id": "fpdeiduid1" + } + ] + }, + { + "source": "fpdeid2", + "uids": [ + { + "id": "fpdeiduid1" + } + ] + } + ] + } + } + } + } + ] + } + } + } + }, + "outgoingRequests": { + "appnexus": { + "expectRequest": { + "ortbRequest": { + "id": "some-request-id", + "imp": [ + { + "id": "some-imp-id", + "banner": { + "format": [ + { + "w": 600, + "h": 500 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": 1 + } + } + } + ], + "site": { + "domain": "fpd_appnexus_site_domain", + "page": "fpd_appnexus_site_page" + }, + "user": { + "id": "reqUserID", + "keywords": "userKeyword!", + "eids": [ + { + "source": "reqieid2", + "uids": [ + { + "id": "reqeiduid2" + } + ] + } + ] + } + } + } + }, + "rubicon": { + "expectRequest": { + "ortbRequest": { + "id": "some-request-id", + "imp": [ + { + "id": "some-imp-id", + "banner": { + "format": [ + { + "w": 600, + "h": 500 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "accountId": 1, + "siteId": 2, + "zoneId": 3 + } + } + } + ], + "site": { + "page": "test.somepage.com" + }, + "user": { + "id": "fpdSiteId!4", + "yob": 2000, + "keywords": "fpd keywords", + "eids": [ + { + "source": "fpdeid1", + "uids": [ + { + "id": "fpdeiduid1" + } + ] + }, + { + "source": "fpdeid2", + "uids": [ + { + "id": "fpdeiduid1" + } + ] + } + ] + } + } + } + } + } +} \ No newline at end of file diff --git a/exchange/exchangetest/firstpartydata-user-eids-req-user-nil.json b/exchange/exchangetest/firstpartydata-user-eids-req-user-nil.json new file mode 100644 index 00000000000..2c3b47dc76e --- /dev/null +++ b/exchange/exchangetest/firstpartydata-user-eids-req-user-nil.json @@ -0,0 +1,203 @@ +{ + "requestType": "openrtb2-web", + "ortbversion": { + "appnexus":"2.6", + "rubicon":"2.6" + }, + "incomingRequest": { + "ortbRequest": { + "id": "some-request-id", + "site": { + "page": "test.somepage.com" + }, + "imp": [ + { + "id": "some-imp-id", + "banner": { + "format": [ + { + "w": 600, + "h": 500 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "prebid": { + "bidder": { + "appnexus": { + "placementId": 1 + }, + "rubicon": { + "accountId": 1, + "siteId": 2, + "zoneId": 3 + } + } + } + } + } + ], + "ext": { + "prebid": { + "data": { + "eidpermissions": [ + { + "source": "reqeid1", + "bidders": [ + "rubicon" + ] + } + ], + "bidders": [ + "appnexus", + "rubicon" + ] + }, + "bidderconfig": [ + { + "bidders": [ + "appnexus" + ], + "config": { + "ortb2": { + "site": { + "domain": "fpd_appnexus_site_domain", + "page": "fpd_appnexus_site_page" + } + } + } + }, + { + "bidders": [ + "rubicon" + ], + "config": { + "ortb2": { + "user": { + "id": "fpdSiteId!4", + "yob": 2000, + "keywords": "fpd keywords", + "eids": [ + { + "source": "fpdeid1", + "uids": [ + { + "id": "fpdeiduid1" + } + ] + }, + { + "source": "fpdeid2", + "uids": [ + { + "id": "fpdeiduid1" + } + ] + } + ] + } + } + } + } + ] + } + } + } + }, + "outgoingRequests": { + "appnexus": { + "expectRequest": { + "ortbRequest": { + "id": "some-request-id", + "imp": [ + { + "id": "some-imp-id", + "banner": { + "format": [ + { + "w": 600, + "h": 500 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": 1 + } + } + } + ], + "site": { + "domain": "fpd_appnexus_site_domain", + "page": "fpd_appnexus_site_page" + } + } + } + }, + "rubicon": { + "expectRequest": { + "ortbRequest": { + "id": "some-request-id", + "imp": [ + { + "id": "some-imp-id", + "banner": { + "format": [ + { + "w": 600, + "h": 500 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "accountId": 1, + "siteId": 2, + "zoneId": 3 + } + } + } + ], + "site": { + "page": "test.somepage.com" + }, + "user": { + "id": "fpdSiteId!4", + "yob": 2000, + "keywords": "fpd keywords", + "eids": [ + { + "source": "fpdeid1", + "uids": [ + { + "id": "fpdeiduid1" + } + ] + }, + { + "source": "fpdeid2", + "uids": [ + { + "id": "fpdeiduid1" + } + ] + } + ] + } + } + } + } + } +} \ No newline at end of file diff --git a/exchange/exchangetest/firstpartydata-user-nileids-req-user-nil.json b/exchange/exchangetest/firstpartydata-user-nileids-req-user-nil.json new file mode 100644 index 00000000000..3ea8382176c --- /dev/null +++ b/exchange/exchangetest/firstpartydata-user-nileids-req-user-nil.json @@ -0,0 +1,163 @@ +{ + "requestType": "openrtb2-web", + "incomingRequest": { + "ortbRequest": { + "id": "some-request-id", + "site": { + "page": "test.somepage.com" + }, + "imp": [ + { + "id": "some-imp-id", + "banner": { + "format": [ + { + "w": 600, + "h": 500 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "prebid": { + "bidder": { + "appnexus": { + "placementId": 1 + }, + "rubicon": { + "accountId": 1, + "siteId": 2, + "zoneId": 3 + } + } + } + } + } + ], + "ext": { + "prebid": { + "data": { + "eidpermissions": [ + { + "source": "reqeid1", + "bidders": [ + "rubicon" + ] + } + ], + "bidders": [ + "appnexus", + "rubicon" + ] + }, + "bidderconfig": [ + { + "bidders": [ + "appnexus" + ], + "config": { + "ortb2": { + "site": { + "domain": "fpd_appnexus_site_domain", + "page": "fpd_appnexus_site_page" + } + } + } + }, + { + "bidders": [ + "rubicon" + ], + "config": { + "ortb2": { + "user": { + "id": "fpdSiteId!4", + "yob": 2000, + "keywords": "fpd keywords" + } + } + } + } + ] + } + } + } + }, + "outgoingRequests": { + "appnexus": { + "expectRequest": { + "ortbRequest": { + "id": "some-request-id", + "imp": [ + { + "id": "some-imp-id", + "banner": { + "format": [ + { + "w": 600, + "h": 500 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": 1 + } + } + } + ], + "site": { + "domain": "fpd_appnexus_site_domain", + "page": "fpd_appnexus_site_page" + } + } + } + }, + "rubicon": { + "expectRequest": { + "ortbRequest": { + "id": "some-request-id", + "imp": [ + { + "id": "some-imp-id", + "banner": { + "format": [ + { + "w": 600, + "h": 500 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "accountId": 1, + "siteId": 2, + "zoneId": 3 + } + } + } + ], + "site": { + "page": "test.somepage.com" + }, + "user": { + "id": "fpdSiteId!4", + "yob": 2000, + "keywords": "fpd keywords" + } + } + } + } + } +} \ No newline at end of file diff --git a/exchange/exchangetest/generate-bid-id-error.json b/exchange/exchangetest/generate-bid-id-error.json index c38d0c97e3b..3536f38b3d1 100644 --- a/exchange/exchangetest/generate-bid-id-error.json +++ b/exchange/exchangetest/generate-bid-id-error.json @@ -121,10 +121,14 @@ "hb_cache_path_appnex": "/pbcache/endpoint", "hb_pb": "0.20", "hb_pb_appnexus": "0.20", - "hb_pb_cat_dur": "0.20_VideoGames_0s_appnexus", - "hb_pb_cat_dur_appnex": "0.20_VideoGames_0s_appnexus", + "hb_pb_cat_dur": "0.20_VideoGames_30s_appnexus", + "hb_pb_cat_dur_appnex": "0.20_VideoGames_30s_appnexus", "hb_size": "200x250", "hb_size_appnexus": "200x250" + }, + "video": { + "duration": 30, + "primary_category": "" } } } diff --git a/exchange/exchangetest/generate-bid-id-many.json b/exchange/exchangetest/generate-bid-id-many.json index 8a55d1976d4..ecdefbaa71b 100644 --- a/exchange/exchangetest/generate-bid-id-many.json +++ b/exchange/exchangetest/generate-bid-id-many.json @@ -67,7 +67,8 @@ }, "bidType": "video", "bidVideo": { - "duration": 30 + "duration": 30, + "PrimaryCategory": "" } } ], @@ -100,7 +101,11 @@ "meta": { }, "bidid": "bid-appnexus-1", - "type": "video" + "type": "video", + "video": { + "duration": 30, + "primary_category": "" + } } } }, @@ -120,7 +125,11 @@ "meta": { }, "bidid": "bid-appnexus-2", - "type": "video" + "type": "video", + "video": { + "duration": 30, + "primary_category": "" + } } } } diff --git a/exchange/exchangetest/generate-bid-id-one.json b/exchange/exchangetest/generate-bid-id-one.json index e14e5db22b9..ccd6abd05f2 100644 --- a/exchange/exchangetest/generate-bid-id-one.json +++ b/exchange/exchangetest/generate-bid-id-one.json @@ -50,7 +50,8 @@ }, "bidType": "video", "bidVideo": { - "duration": 30 + "duration": 30, + "primary_category": "" } } ], @@ -83,7 +84,11 @@ "meta": { }, "bidid": "bid-appnexus-1", - "type": "video" + "type": "video", + "video": { + "duration": 30, + "primary_category": "" + } } } } diff --git a/exchange/exchangetest/include-brand-category.json b/exchange/exchangetest/include-brand-category.json index 74950598ec2..7334cf1a6c1 100644 --- a/exchange/exchangetest/include-brand-category.json +++ b/exchange/exchangetest/include-brand-category.json @@ -146,10 +146,14 @@ "hb_cache_path_appnex": "/pbcache/endpoint", "hb_pb": "0.20", "hb_pb_appnexus": "0.20", - "hb_pb_cat_dur": "0.20_VideoGames_0s", - "hb_pb_cat_dur_appnex": "0.20_VideoGames_0s", + "hb_pb_cat_dur": "0.20_VideoGames_30s", + "hb_pb_cat_dur_appnex": "0.20_VideoGames_30s", "hb_size": "200x250", "hb_size_appnexus": "200x250" + }, + "video": { + "duration": 30, + "primary_category": "" } } } diff --git a/exchange/exchangetest/multi-bids-different-ortb-versions.json b/exchange/exchangetest/multi-bids-different-ortb-versions.json new file mode 100644 index 00000000000..37e7fc582c7 --- /dev/null +++ b/exchange/exchangetest/multi-bids-different-ortb-versions.json @@ -0,0 +1,276 @@ +{ + "requestType": "openrtb2-web", + "ortbversion": { + "appnexus":"2.6", + "rubicon":"2.5" + }, + "incomingRequest": { + "ortbRequest": { + "id": "some-request-id", + "site": { + "page": "test.somepage.com" + }, + "user": { + "id": "my-user-id", + "buyeruid": "my-buyer-uid", + "geo": { + "lat": 123.456, + "lon": 678.90, + "zip": "90210" + }, + "consent": "AAAA", + "eids": [ + { + "source": "source", + "uids": [ + { + "id": "1", + "atype": 1, + "ext": {} + }, + { + "id": "1", + "atype": 1, + "ext": {} + } + ], + "ext": {} + } + ], + "ext": {} + }, + "imp": [ + { + "rwdd": 1, + "id": "some-imp-id", + "banner": { + "format": [ + { + "w": 600, + "h": 500 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "prebid": { + "bidder": { + "appnexus": { + "placementId": 1 + }, + "rubicon": { + "accountId": 1, + "siteId": 2, + "zoneId": 3 + } + } + } + } + } + ], + "source": { + "fd": 1, + "tid": "abc123", + "pchain": "tag_placement", + "schain": { + "complete": 1, + "nodes": [ + { + "asi": "asi", + "sid": "sid", + "rid": "rid", + "ext": {} + } + ], + "ver": "ver", + "ext": {} + }, + "ext": {} + }, + "regs": { + "coppa": 1, + "gdpr": 1, + "us_privacy": "1YYY", + "gpp": "DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1NYN", + "gppsid": [ + 6 + ] + } + } + }, + "outgoingRequests": { + "appnexus": { + "expectRequest": { + "ortbRequest": { + "id": "some-request-id", + "site": { + "page": "test.somepage.com" + }, + "user": { + "geo": {}, + "consent": "AAAA", + "eids": [ + { + "source": "source", + "uids": [ + { + "id": "1", + "atype": 1, + "ext": {} + }, + { + "id": "1", + "atype": 1, + "ext": {} + } + ], + "ext": {} + } + ], + "ext": {} + }, + "imp": [ + { + "rwdd": 1, + "id": "some-imp-id", + "banner": { + "format": [ + { + "w": 600, + "h": 500 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "placementId": 1 + } + } + } + ], + "source": { + "fd": 1, + "tid": "abc123", + "pchain": "tag_placement", + "schain": { + "complete": 1, + "nodes": [ + { + "asi": "asi", + "sid": "sid", + "rid": "rid", + "ext": {} + } + ], + "ver": "ver", + "ext": {} + }, + "ext": {} + }, + "regs": { + "coppa": 1, + "gdpr": 1, + "us_privacy": "1YYY", + "gpp": "DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1NYN" + } + } + } + }, + "rubicon": { + "expectRequest": { + "ortbRequest": { + "id": "some-request-id", + "site": { + "page": "test.somepage.com" + }, + "user": { + "geo": {}, + "ext": { + "consent": "AAAA", + "eids": [ + { + "source": "source", + "uids": [ + { + "id": "1", + "atype": 1, + "ext": {} + }, + { + "id": "1", + "atype": 1, + "ext": {} + } + ], + "ext": {} + } + ] + } + }, + "imp": [ + { + "id": "some-imp-id", + "banner": { + "format": [ + { + "w": 600, + "h": 500 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "accountId": 1, + "siteId": 2, + "zoneId": 3 + }, + "prebid": { + "is_rewarded_inventory":1 + } + } + } + ], + "source": { + "fd": 1, + "tid": "abc123", + "pchain": "tag_placement", + "ext": { + "schain": { + "complete": 1, + "nodes": [ + { + "asi": "asi", + "sid": "sid", + "rid": "rid", + "ext": {} + } + ], + "ver": "ver", + "ext": {} + } + } + }, + "regs": { + "coppa": 1, + "gpp":"DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1NYN", + "ext": { + "gdpr": 1, + "us_privacy": "1YYY" + } + } + } + } + } + } +} \ No newline at end of file diff --git a/exchange/exchangetest/schain-host-and-request.json b/exchange/exchangetest/schain-host-and-request.json index 5bfcd1c3527..0552bb09b30 100644 --- a/exchange/exchangetest/schain-host-and-request.json +++ b/exchange/exchangetest/schain-host-and-request.json @@ -1,5 +1,8 @@ { "host_schain_flag": true, + "ortbversion": { + "appnexus":"2.6" + }, "incomingRequest": { "ortbRequest": { "id": "some-request-id", @@ -84,25 +87,23 @@ } }, "source": { - "ext": { - "schain": { - "complete": 1, - "nodes": [ - { - "asi": "whatever.com", - "sid": "1234", - "rid": "123-456-7890", - "hp": 1 - }, - { - "asi": "pbshostcompany.com", - "sid": "00001", - "rid": "BidRequest", - "hp": 1 - } - ], - "ver": "2.0" - } + "schain": { + "complete": 1, + "nodes": [ + { + "asi": "whatever.com", + "sid": "1234", + "rid": "123-456-7890", + "hp": 1 + }, + { + "asi": "pbshostcompany.com", + "sid": "00001", + "rid": "BidRequest", + "hp": 1 + } + ], + "ver": "2.0" } } }, diff --git a/exchange/exchangetest/schain-host-only.json b/exchange/exchangetest/schain-host-only.json index 0cc077e2fdb..89fb70c3676 100644 --- a/exchange/exchangetest/schain-host-only.json +++ b/exchange/exchangetest/schain-host-only.json @@ -1,5 +1,8 @@ { "host_schain_flag": true, + "ortbversion": { + "appnexus":"2.6" + }, "incomingRequest": { "ortbRequest": { "id": "some-request-id", @@ -64,19 +67,17 @@ } }, "source": { - "ext": { - "schain": { - "complete": 0, - "nodes": [ - { - "asi": "pbshostcompany.com", - "sid": "00001", - "rid": "BidRequest", - "hp": 1 - } - ], - "ver": "1.0" - } + "schain": { + "complete": 0, + "nodes": [ + { + "asi": "pbshostcompany.com", + "sid": "00001", + "rid": "BidRequest", + "hp": 1 + } + ], + "ver": "1.0" } } }, diff --git a/exchange/gdpr.go b/exchange/gdpr.go index 2f94eefdaef..866f33baed2 100644 --- a/exchange/gdpr.go +++ b/exchange/gdpr.go @@ -3,9 +3,9 @@ package exchange import ( gpplib "github.com/prebid/go-gpp" gppConstants "github.com/prebid/go-gpp/constants" - "github.com/prebid/prebid-server/v2/gdpr" - "github.com/prebid/prebid-server/v2/openrtb_ext" - gppPolicy "github.com/prebid/prebid-server/v2/privacy/gpp" + "github.com/prebid/prebid-server/v3/gdpr" + "github.com/prebid/prebid-server/v3/openrtb_ext" + gppPolicy "github.com/prebid/prebid-server/v3/privacy/gpp" ) // getGDPR will pull the gdpr flag from an openrtb request @@ -16,11 +16,11 @@ func getGDPR(req *openrtb_ext.RequestWrapper) (gdpr.Signal, error) { } return gdpr.SignalNo, nil } - re, err := req.GetRegExt() - if re == nil || re.GetGDPR() == nil || err != nil { - return gdpr.SignalAmbiguous, err + if req.Regs != nil && req.Regs.GDPR != nil { + return gdpr.IntSignalParse(int(*req.Regs.GDPR)) } - return gdpr.Signal(*re.GetGDPR()), nil + return gdpr.SignalAmbiguous, nil + } // getConsent will pull the consent string from an openrtb request @@ -29,11 +29,10 @@ func getConsent(req *openrtb_ext.RequestWrapper, gpp gpplib.GppContainer) (conse consent = gpp.Sections[i].GetValue() return } - ue, err := req.GetUserExt() - if ue == nil || ue.GetConsent() == nil || err != nil { - return + if req.User != nil { + return req.User.Consent, nil } - return *ue.GetConsent(), nil + return } // enforceGDPR determines if GDPR should be enforced based on the request signal and whether the channel is enabled diff --git a/exchange/gdpr_test.go b/exchange/gdpr_test.go index c73112be6f3..b2d175c2ad0 100644 --- a/exchange/gdpr_test.go +++ b/exchange/gdpr_test.go @@ -1,14 +1,14 @@ package exchange import ( - "encoding/json" "testing" gpplib "github.com/prebid/go-gpp" gppConstants "github.com/prebid/go-gpp/constants" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/gdpr" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/gdpr" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/ptrutil" "github.com/stretchr/testify/assert" ) @@ -21,17 +21,17 @@ func TestGetGDPR(t *testing.T) { }{ { description: "Regs Ext GDPR = 0", - giveRegs: &openrtb2.Regs{Ext: json.RawMessage(`{"gdpr": 0}`)}, + giveRegs: &openrtb2.Regs{GDPR: ptrutil.ToPtr[int8](0)}, wantGDPR: gdpr.SignalNo, }, { description: "Regs Ext GDPR = 1", - giveRegs: &openrtb2.Regs{Ext: json.RawMessage(`{"gdpr": 1}`)}, + giveRegs: &openrtb2.Regs{GDPR: ptrutil.ToPtr[int8](1)}, wantGDPR: gdpr.SignalYes, }, { description: "Regs Ext GDPR = null", - giveRegs: &openrtb2.Regs{Ext: json.RawMessage(`{"gdpr": null}`)}, + giveRegs: &openrtb2.Regs{GDPR: nil}, wantGDPR: gdpr.SignalAmbiguous, }, { @@ -39,30 +39,19 @@ func TestGetGDPR(t *testing.T) { giveRegs: nil, wantGDPR: gdpr.SignalAmbiguous, }, - { - description: "Regs Ext is nil", - giveRegs: &openrtb2.Regs{Ext: nil}, - wantGDPR: gdpr.SignalAmbiguous, - }, - { - description: "JSON unmarshal error", - giveRegs: &openrtb2.Regs{Ext: json.RawMessage(`{"`)}, - wantGDPR: gdpr.SignalAmbiguous, - wantError: true, - }, { description: "Regs Ext GDPR = null, GPPSID has tcf2", - giveRegs: &openrtb2.Regs{Ext: json.RawMessage(`{"gdpr": null}`), GPPSID: []int8{2}}, + giveRegs: &openrtb2.Regs{GDPR: nil, GPPSID: []int8{2}}, wantGDPR: gdpr.SignalYes, }, { description: "Regs Ext GDPR = 1, GPPSID has uspv1", - giveRegs: &openrtb2.Regs{Ext: json.RawMessage(`{"gdpr": 1}`), GPPSID: []int8{6}}, + giveRegs: &openrtb2.Regs{GDPR: ptrutil.ToPtr[int8](1), GPPSID: []int8{6}}, wantGDPR: gdpr.SignalNo, }, { description: "Regs Ext GDPR = 0, GPPSID has tcf2", - giveRegs: &openrtb2.Regs{Ext: json.RawMessage(`{"gdpr": 0}`), GPPSID: []int8{2}}, + giveRegs: &openrtb2.Regs{GDPR: ptrutil.ToPtr[int8](0), GPPSID: []int8{2}}, wantGDPR: gdpr.SignalYes, }, { @@ -105,18 +94,13 @@ func TestGetConsent(t *testing.T) { wantError bool }{ { - description: "User Ext Consent is not empty", - giveUser: &openrtb2.User{Ext: json.RawMessage(`{"consent": "BOS2bx5OS2bx5ABABBAAABoAAAAAFA"}`)}, + description: "User Consent is not empty", + giveUser: &openrtb2.User{Consent: "BOS2bx5OS2bx5ABABBAAABoAAAAAFA"}, wantConsent: "BOS2bx5OS2bx5ABABBAAABoAAAAAFA", }, { - description: "User Ext Consent is empty", - giveUser: &openrtb2.User{Ext: json.RawMessage(`{"consent": ""}`)}, - wantConsent: "", - }, - { - description: "User Ext is nil", - giveUser: &openrtb2.User{Ext: nil}, + description: "User Consent is empty", + giveUser: &openrtb2.User{Consent: ""}, wantConsent: "", }, { @@ -125,26 +109,20 @@ func TestGetConsent(t *testing.T) { wantConsent: "", }, { - description: "JSON unmarshal error", - giveUser: &openrtb2.User{Ext: json.RawMessage(`{`)}, - wantConsent: "", - wantError: true, - }, - { - description: "User Ext is nil, GPP has no GDPR", - giveUser: &openrtb2.User{Ext: nil}, + description: "User is nil, GPP has no GDPR", + giveUser: nil, giveGPP: gpplib.GppContainer{Version: 1, SectionTypes: []gppConstants.SectionID{6}, Sections: []gpplib.Section{&upsv1Section}}, wantConsent: "", }, { - description: "User Ext is nil, GPP has GDPR", - giveUser: &openrtb2.User{Ext: nil}, + description: "User is nil, GPP has GDPR", + giveUser: nil, giveGPP: gpplib.GppContainer{Version: 1, SectionTypes: []gppConstants.SectionID{2}, Sections: []gpplib.Section{&tcf1Section}}, wantConsent: "BOS2bx5OS2bx5ABABBAAABoAAAAAFA", }, { - description: "User Ext has GDPR, GPP has GDPR", - giveUser: &openrtb2.User{Ext: json.RawMessage(`{"consent": "BSOMECONSENT"}`)}, + description: "User has GDPR, GPP has GDPR", + giveUser: &openrtb2.User{Consent: "BSOMECONSENT"}, giveGPP: gpplib.GppContainer{Version: 1, SectionTypes: []gppConstants.SectionID{2}, Sections: []gpplib.Section{&tcf1Section}}, wantConsent: "BOS2bx5OS2bx5ABABBAAABoAAAAAFA", }, diff --git a/exchange/non_bid_reason.go b/exchange/non_bid_reason.go index fe9a8e26c48..05d4ea3ee66 100644 --- a/exchange/non_bid_reason.go +++ b/exchange/non_bid_reason.go @@ -1,12 +1,22 @@ package exchange +import ( + "errors" + "net" + "syscall" + + "github.com/prebid/prebid-server/v3/errortypes" +) + // SeatNonBid list the reasons why bid was not resulted in positive bid // reason could be either No bid, Error, Request rejection or Response rejection -// Reference: https://github.com/InteractiveAdvertisingBureau/openrtb/blob/master/extensions/community_extensions/seat-non-bid.md -type NonBidReason int +// Reference: https://github.com/InteractiveAdvertisingBureau/openrtb/blob/master/extensions/community_extensions/seat-non-bid.md#list-non-bid-status-codes +type NonBidReason int64 const ( - NoBidUnknownError NonBidReason = 0 // No Bid - General + ErrorGeneral NonBidReason = 100 // Error - General + ErrorTimeout NonBidReason = 101 // Error - Timeout + ErrorBidderUnreachable NonBidReason = 103 // Error - Bidder Unreachable ResponseRejectedGeneral NonBidReason = 300 ResponseRejectedBelowFloor NonBidReason = 301 // Response Rejected - Below Floor ResponseRejectedCategoryMappingInvalid NonBidReason = 303 // Response Rejected - Category Mapping Invalid @@ -15,15 +25,33 @@ const ( ResponseRejectedCreativeNotSecure NonBidReason = 352 // Response Rejected - Invalid Creative (Not Secure) ) -// Ptr returns pointer to own value. -func (n NonBidReason) Ptr() *NonBidReason { - return &n +func errorToNonBidReason(err error) NonBidReason { + switch errortypes.ReadCode(err) { + case errortypes.TimeoutErrorCode: + return ErrorTimeout + default: + return ErrorGeneral + } } -// Val safely dereferences pointer, returning default value (NoBidUnknownError) for nil. -func (n *NonBidReason) Val() NonBidReason { - if n == nil { - return NoBidUnknownError +// httpInfoToNonBidReason determines NoBidReason code (NBR) +// It will first try to resolve the NBR based on prebid's proprietary error code. +// If proprietary error code not found then it will try to determine NBR using +// system call level error code +func httpInfoToNonBidReason(httpInfo *httpCallInfo) NonBidReason { + nonBidReason := errorToNonBidReason(httpInfo.err) + if nonBidReason != ErrorGeneral { + return nonBidReason } - return *n + if isBidderUnreachableError(httpInfo) { + return ErrorBidderUnreachable + } + return ErrorGeneral +} + +// isBidderUnreachableError checks if the error is due to connection refused or no such host +func isBidderUnreachableError(httpInfo *httpCallInfo) bool { + var dnsErr *net.DNSError + isNoSuchHost := errors.As(httpInfo.err, &dnsErr) && dnsErr.IsNotFound + return errors.Is(httpInfo.err, syscall.ECONNREFUSED) || isNoSuchHost } diff --git a/exchange/non_bid_reason_test.go b/exchange/non_bid_reason_test.go new file mode 100644 index 00000000000..fb9c5e434fc --- /dev/null +++ b/exchange/non_bid_reason_test.go @@ -0,0 +1,65 @@ +package exchange + +import ( + "errors" + "net" + "syscall" + "testing" + + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/stretchr/testify/assert" +) + +func Test_httpInfoToNonBidReason(t *testing.T) { + type args struct { + httpInfo *httpCallInfo + } + tests := []struct { + name string + args args + want NonBidReason + }{ + { + name: "error-timeout", + args: args{ + httpInfo: &httpCallInfo{ + err: &errortypes.Timeout{}, + }, + }, + want: ErrorTimeout, + }, + { + name: "error-general", + args: args{ + httpInfo: &httpCallInfo{ + err: errors.New("some_error"), + }, + }, + want: ErrorGeneral, + }, + { + name: "error-bidderUnreachable", + args: args{ + httpInfo: &httpCallInfo{ + err: syscall.ECONNREFUSED, + }, + }, + want: ErrorBidderUnreachable, + }, + { + name: "error-biddersUnreachable-no-such-host", + args: args{ + httpInfo: &httpCallInfo{ + err: &net.DNSError{IsNotFound: true}, + }, + }, + want: ErrorBidderUnreachable, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + actual := httpInfoToNonBidReason(tt.args.httpInfo) + assert.Equal(t, tt.want, actual) + }) + } +} diff --git a/exchange/price_granularity.go b/exchange/price_granularity.go index 9c16a0d3aef..ba62c1aa4ab 100644 --- a/exchange/price_granularity.go +++ b/exchange/price_granularity.go @@ -5,7 +5,7 @@ import ( "strconv" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // GetPriceBucket is the externally facing function for computing CPM buckets diff --git a/exchange/price_granularity_test.go b/exchange/price_granularity_test.go index 82152acb9d2..bb0e5e7d73b 100644 --- a/exchange/price_granularity_test.go +++ b/exchange/price_granularity_test.go @@ -6,8 +6,8 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/exchange/seat_non_bids.go b/exchange/seat_non_bids.go index 78c1b23e3f3..fd6fd1da3ff 100644 --- a/exchange/seat_non_bids.go +++ b/exchange/seat_non_bids.go @@ -1,26 +1,22 @@ package exchange import ( - "github.com/prebid/prebid-server/v2/exchange/entities" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/exchange/entities" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) -type nonBids struct { - seatNonBidsMap map[string][]openrtb_ext.NonBid -} +type SeatNonBidBuilder map[string][]openrtb_ext.NonBid -// addBid is not thread safe as we are initializing and writing to map -func (snb *nonBids) addBid(bid *entities.PbsOrtbBid, nonBidReason int, seat string) { - if bid == nil || bid.Bid == nil { +// rejectBid appends a non bid object to the builder based on a bid +func (b SeatNonBidBuilder) rejectBid(bid *entities.PbsOrtbBid, nonBidReason int, seat string) { + if b == nil || bid == nil || bid.Bid == nil { return } - if snb.seatNonBidsMap == nil { - snb.seatNonBidsMap = make(map[string][]openrtb_ext.NonBid) - } + nonBid := openrtb_ext.NonBid{ ImpId: bid.Bid.ImpID, StatusCode: nonBidReason, - Ext: openrtb_ext.NonBidExt{ + Ext: &openrtb_ext.NonBidExt{ Prebid: openrtb_ext.ExtResponseNonBidPrebid{Bid: openrtb_ext.NonBidObject{ Price: bid.Bid.Price, ADomain: bid.Bid.ADomain, @@ -36,16 +32,29 @@ func (snb *nonBids) addBid(bid *entities.PbsOrtbBid, nonBidReason int, seat stri }}, }, } - - snb.seatNonBidsMap[seat] = append(snb.seatNonBidsMap[seat], nonBid) + b[seat] = append(b[seat], nonBid) } -func (snb *nonBids) get() []openrtb_ext.SeatNonBid { - if snb == nil { - return nil +// rejectImps appends a non bid object to the builder for every specified imp +func (b SeatNonBidBuilder) rejectImps(impIds []string, nonBidReason NonBidReason, seat string) { + nonBids := []openrtb_ext.NonBid{} + for _, impId := range impIds { + nonBid := openrtb_ext.NonBid{ + ImpId: impId, + StatusCode: int(nonBidReason), + } + nonBids = append(nonBids, nonBid) } - var seatNonBid []openrtb_ext.SeatNonBid - for seat, nonBids := range snb.seatNonBidsMap { + + if len(nonBids) > 0 { + b[seat] = append(b[seat], nonBids...) + } +} + +// slice transforms the seat non bid map into a slice of SeatNonBid objects representing the non-bids for each seat +func (b SeatNonBidBuilder) Slice() []openrtb_ext.SeatNonBid { + seatNonBid := make([]openrtb_ext.SeatNonBid, 0) + for seat, nonBids := range b { seatNonBid = append(seatNonBid, openrtb_ext.SeatNonBid{ Seat: seat, NonBid: nonBids, @@ -53,3 +62,16 @@ func (snb *nonBids) get() []openrtb_ext.SeatNonBid { } return seatNonBid } + +// append adds the nonBids from the input nonBids to the current nonBids. +// This method is not thread safe as we are initializing and writing to map +func (b SeatNonBidBuilder) append(nonBids ...SeatNonBidBuilder) { + if b == nil { + return + } + for _, nonBid := range nonBids { + for seat, nonBids := range nonBid { + b[seat] = append(b[seat], nonBids...) + } + } +} diff --git a/exchange/seat_non_bids_test.go b/exchange/seat_non_bids_test.go index 103c0939496..4a8f9e8f784 100644 --- a/exchange/seat_non_bids_test.go +++ b/exchange/seat_non_bids_test.go @@ -4,14 +4,14 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/exchange/entities" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/exchange/entities" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) -func TestSeatNonBidsAdd(t *testing.T) { +func TestRejectBid(t *testing.T) { type fields struct { - seatNonBidsMap map[string][]openrtb_ext.NonBid + builder SeatNonBidBuilder } type args struct { bid *entities.PbsOrtbBid @@ -22,89 +22,512 @@ func TestSeatNonBidsAdd(t *testing.T) { name string fields fields args args - want map[string][]openrtb_ext.NonBid + want SeatNonBidBuilder }{ { - name: "nil-seatNonBidsMap", - fields: fields{seatNonBidsMap: nil}, - args: args{}, - want: nil, + name: "nil_builder", + fields: fields{ + builder: nil, + }, + args: args{}, + want: nil, }, { - name: "nil-seatNonBidsMap-with-bid-object", - fields: fields{seatNonBidsMap: nil}, - args: args{bid: &entities.PbsOrtbBid{Bid: &openrtb2.Bid{}}, seat: "bidder1"}, - want: sampleSeatNonBidMap("bidder1", 1), + name: "nil_pbsortbid", + fields: fields{ + builder: SeatNonBidBuilder{}, + }, + args: args{ + bid: nil, + }, + want: SeatNonBidBuilder{}, }, { - name: "multiple-nonbids-for-same-seat", - fields: fields{seatNonBidsMap: sampleSeatNonBidMap("bidder2", 1)}, - args: args{bid: &entities.PbsOrtbBid{Bid: &openrtb2.Bid{}}, seat: "bidder2"}, - want: sampleSeatNonBidMap("bidder2", 2), + name: "nil_bid", + fields: fields{ + builder: SeatNonBidBuilder{}, + }, + args: args{ + bid: &entities.PbsOrtbBid{ + Bid: nil, + }, + }, + want: SeatNonBidBuilder{}, + }, + { + name: "append_nonbids_new_seat", + fields: fields{ + builder: SeatNonBidBuilder{}, + }, + args: args{ + bid: &entities.PbsOrtbBid{ + Bid: &openrtb2.Bid{ + ImpID: "Imp1", + Price: 10, + }, + }, + nonBidReason: int(ErrorGeneral), + seat: "seat1", + }, + want: SeatNonBidBuilder{ + "seat1": []openrtb_ext.NonBid{ + { + ImpId: "Imp1", + StatusCode: int(ErrorGeneral), + Ext: &openrtb_ext.NonBidExt{ + Prebid: openrtb_ext.ExtResponseNonBidPrebid{ + Bid: openrtb_ext.NonBidObject{ + Price: 10, + }, + }, + }, + }, + }, + }, + }, + { + name: "append_nonbids_for_different_seat", + fields: fields{ + builder: SeatNonBidBuilder{ + "seat1": []openrtb_ext.NonBid{ + { + ImpId: "Imp1", + StatusCode: int(ErrorGeneral), + }, + }, + }, + }, + args: args{ + bid: &entities.PbsOrtbBid{ + Bid: &openrtb2.Bid{ + ImpID: "Imp2", + Price: 10, + }, + }, + nonBidReason: int(ErrorGeneral), + seat: "seat2", + }, + want: SeatNonBidBuilder{ + "seat1": []openrtb_ext.NonBid{ + { + ImpId: "Imp1", + StatusCode: int(ErrorGeneral), + }, + }, + "seat2": []openrtb_ext.NonBid{ + { + ImpId: "Imp2", + StatusCode: int(ErrorGeneral), + Ext: &openrtb_ext.NonBidExt{ + Prebid: openrtb_ext.ExtResponseNonBidPrebid{ + Bid: openrtb_ext.NonBidObject{ + Price: 10, + }, + }, + }, + }, + }, + }, + }, + { + name: "append_nonbids_for_existing_seat", + fields: fields{ + builder: SeatNonBidBuilder{ + "seat1": []openrtb_ext.NonBid{ + { + ImpId: "Imp1", + StatusCode: int(ErrorGeneral), + }, + }, + }, + }, + args: args{ + bid: &entities.PbsOrtbBid{ + Bid: &openrtb2.Bid{ + ImpID: "Imp2", + Price: 10, + }, + }, + nonBidReason: int(ErrorGeneral), + seat: "seat1", + }, + want: SeatNonBidBuilder{ + "seat1": []openrtb_ext.NonBid{ + { + ImpId: "Imp1", + StatusCode: int(ErrorGeneral), + }, + { + ImpId: "Imp2", + StatusCode: int(ErrorGeneral), + Ext: &openrtb_ext.NonBidExt{ + Prebid: openrtb_ext.ExtResponseNonBidPrebid{ + Bid: openrtb_ext.NonBidObject{ + Price: 10, + }, + }, + }, + }, + }, + }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - snb := &nonBids{ - seatNonBidsMap: tt.fields.seatNonBidsMap, - } - snb.addBid(tt.args.bid, tt.args.nonBidReason, tt.args.seat) - assert.Equalf(t, tt.want, snb.seatNonBidsMap, "expected seatNonBidsMap not nil") + snb := tt.fields.builder + snb.rejectBid(tt.args.bid, tt.args.nonBidReason, tt.args.seat) + assert.Equal(t, tt.want, snb) }) } } -func TestSeatNonBidsGet(t *testing.T) { - type fields struct { - snb *nonBids - } +func TestAppend(t *testing.T) { tests := []struct { - name string - fields fields - want []openrtb_ext.SeatNonBid + name string + builder SeatNonBidBuilder + toAppend []SeatNonBidBuilder + expected SeatNonBidBuilder }{ { - name: "get-seat-nonbids", - fields: fields{&nonBids{sampleSeatNonBidMap("bidder1", 2)}}, - want: sampleSeatBids("bidder1", 2), + name: "nil_buider", + builder: nil, + toAppend: []SeatNonBidBuilder{{"seat1": []openrtb_ext.NonBid{{ImpId: "imp1"}}}}, + expected: nil, + }, + { + name: "empty_builder", + builder: SeatNonBidBuilder{}, + toAppend: []SeatNonBidBuilder{{"seat1": []openrtb_ext.NonBid{{ImpId: "imp1"}}}}, + expected: SeatNonBidBuilder{"seat1": []openrtb_ext.NonBid{{ImpId: "imp1"}}}, + }, + { + name: "append_one_different_seat", + builder: SeatNonBidBuilder{"seat1": []openrtb_ext.NonBid{{ImpId: "imp1"}}}, + toAppend: []SeatNonBidBuilder{{"seat2": []openrtb_ext.NonBid{{ImpId: "imp2"}}}}, + expected: SeatNonBidBuilder{"seat1": []openrtb_ext.NonBid{{ImpId: "imp1"}}, "seat2": []openrtb_ext.NonBid{{ImpId: "imp2"}}}, + }, + { + name: "append_multiple_different_seats", + builder: SeatNonBidBuilder{"seat1": []openrtb_ext.NonBid{{ImpId: "imp1"}}}, + toAppend: []SeatNonBidBuilder{{"seat2": []openrtb_ext.NonBid{{ImpId: "imp2"}}}, {"seat3": []openrtb_ext.NonBid{{ImpId: "imp3"}}}}, + expected: SeatNonBidBuilder{"seat1": []openrtb_ext.NonBid{{ImpId: "imp1"}}, "seat2": []openrtb_ext.NonBid{{ImpId: "imp2"}}, "seat3": []openrtb_ext.NonBid{{ImpId: "imp3"}}}, + }, + { + name: "nil_append", + builder: SeatNonBidBuilder{"seat1": []openrtb_ext.NonBid{{ImpId: "imp1"}}}, + toAppend: nil, + expected: SeatNonBidBuilder{"seat1": []openrtb_ext.NonBid{{ImpId: "imp1"}}}, + }, + { + name: "empty_append", + builder: SeatNonBidBuilder{"seat1": []openrtb_ext.NonBid{{ImpId: "imp1"}}}, + toAppend: []SeatNonBidBuilder{}, + expected: SeatNonBidBuilder{"seat1": []openrtb_ext.NonBid{{ImpId: "imp1"}}}, }, { - name: "nil-seat-nonbids", - fields: fields{nil}, + name: "append_multiple_same_seat", + builder: SeatNonBidBuilder{ + "seat1": []openrtb_ext.NonBid{ + {ImpId: "imp1"}, + }, + }, + toAppend: []SeatNonBidBuilder{ + { + "seat1": []openrtb_ext.NonBid{ + {ImpId: "imp2"}, + }, + }, + }, + expected: SeatNonBidBuilder{ + "seat1": []openrtb_ext.NonBid{ + {ImpId: "imp1"}, + {ImpId: "imp2"}, + }, + }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := tt.fields.snb.get(); !assert.Equal(t, tt.want, got) { - t.Errorf("seatNonBids.get() = %v, want %v", got, tt.want) - } + tt.builder.append(tt.toAppend...) + assert.Equal(t, tt.expected, tt.builder) }) } } -var sampleSeatNonBidMap = func(seat string, nonBidCount int) map[string][]openrtb_ext.NonBid { - nonBids := make([]openrtb_ext.NonBid, 0) - for i := 0; i < nonBidCount; i++ { - nonBids = append(nonBids, openrtb_ext.NonBid{ - Ext: openrtb_ext.NonBidExt{Prebid: openrtb_ext.ExtResponseNonBidPrebid{Bid: openrtb_ext.NonBidObject{}}}, - }) +func TestRejectImps(t *testing.T) { + tests := []struct { + name string + impIDs []string + builder SeatNonBidBuilder + want SeatNonBidBuilder + }{ + { + name: "nil_imps", + impIDs: nil, + builder: SeatNonBidBuilder{}, + want: SeatNonBidBuilder{}, + }, + { + name: "empty_imps", + impIDs: []string{}, + builder: SeatNonBidBuilder{}, + want: SeatNonBidBuilder{}, + }, + { + name: "one_imp", + impIDs: []string{"imp1"}, + builder: SeatNonBidBuilder{}, + want: SeatNonBidBuilder{ + "seat1": []openrtb_ext.NonBid{ + { + ImpId: "imp1", + StatusCode: 300, + }, + }, + }, + }, + { + name: "many_imps", + impIDs: []string{"imp1", "imp2"}, + builder: SeatNonBidBuilder{}, + want: SeatNonBidBuilder{ + "seat1": []openrtb_ext.NonBid{ + { + ImpId: "imp1", + StatusCode: 300, + }, + { + ImpId: "imp2", + StatusCode: 300, + }, + }, + }, + }, + { + name: "many_imps_appended_to_prepopulated_list", + impIDs: []string{"imp1", "imp2"}, + builder: SeatNonBidBuilder{ + "seat0": []openrtb_ext.NonBid{ + { + ImpId: "imp0", + StatusCode: 0, + }, + }, + }, + want: SeatNonBidBuilder{ + "seat0": []openrtb_ext.NonBid{ + { + ImpId: "imp0", + StatusCode: 0, + }, + }, + "seat1": []openrtb_ext.NonBid{ + { + ImpId: "imp1", + StatusCode: 300, + }, + { + ImpId: "imp2", + StatusCode: 300, + }, + }, + }, + }, + { + name: "many_imps_appended_to_prepopulated_list_same_seat", + impIDs: []string{"imp1", "imp2"}, + builder: SeatNonBidBuilder{ + "seat1": []openrtb_ext.NonBid{ + { + ImpId: "imp0", + StatusCode: 300, + }, + }, + }, + want: SeatNonBidBuilder{ + "seat1": []openrtb_ext.NonBid{ + { + ImpId: "imp0", + StatusCode: 300, + }, + { + ImpId: "imp1", + StatusCode: 300, + }, + { + ImpId: "imp2", + StatusCode: 300, + }, + }, + }, + }, } - return map[string][]openrtb_ext.NonBid{ - seat: nonBids, + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + test.builder.rejectImps(test.impIDs, 300, "seat1") + + assert.Equal(t, len(test.builder), len(test.want)) + for seat := range test.want { + assert.ElementsMatch(t, test.want[seat], test.builder[seat]) + } + }) } } -var sampleSeatBids = func(seat string, nonBidCount int) []openrtb_ext.SeatNonBid { - seatNonBids := make([]openrtb_ext.SeatNonBid, 0) - seatNonBid := openrtb_ext.SeatNonBid{ - Seat: seat, - NonBid: make([]openrtb_ext.NonBid, 0), +func TestSlice(t *testing.T) { + tests := []struct { + name string + builder SeatNonBidBuilder + want []openrtb_ext.SeatNonBid + }{ + { + name: "nil", + builder: nil, + want: []openrtb_ext.SeatNonBid{}, + }, + { + name: "empty", + builder: SeatNonBidBuilder{}, + want: []openrtb_ext.SeatNonBid{}, + }, + { + name: "one_no_nonbids", + builder: SeatNonBidBuilder{ + "a": []openrtb_ext.NonBid{}, + }, + want: []openrtb_ext.SeatNonBid{ + { + NonBid: []openrtb_ext.NonBid{}, + Seat: "a", + }, + }, + }, + { + name: "one_with_nonbids", + builder: SeatNonBidBuilder{ + "a": []openrtb_ext.NonBid{ + { + ImpId: "imp1", + StatusCode: 100, + }, + { + ImpId: "imp2", + StatusCode: 200, + }, + }, + }, + want: []openrtb_ext.SeatNonBid{ + { + NonBid: []openrtb_ext.NonBid{ + { + ImpId: "imp1", + StatusCode: 100, + }, + { + ImpId: "imp2", + StatusCode: 200, + }, + }, + Seat: "a", + }, + }, + }, + { + name: "many_no_nonbids", + builder: SeatNonBidBuilder{ + "a": []openrtb_ext.NonBid{}, + "b": []openrtb_ext.NonBid{}, + "c": []openrtb_ext.NonBid{}, + }, + want: []openrtb_ext.SeatNonBid{ + { + NonBid: []openrtb_ext.NonBid{}, + Seat: "a", + }, + { + NonBid: []openrtb_ext.NonBid{}, + Seat: "b", + }, + { + NonBid: []openrtb_ext.NonBid{}, + Seat: "c", + }, + }, + }, + { + name: "many_with_nonbids", + builder: SeatNonBidBuilder{ + "a": []openrtb_ext.NonBid{ + { + ImpId: "imp1", + StatusCode: 100, + }, + { + ImpId: "imp2", + StatusCode: 200, + }, + }, + "b": []openrtb_ext.NonBid{ + { + ImpId: "imp3", + StatusCode: 300, + }, + }, + "c": []openrtb_ext.NonBid{ + { + ImpId: "imp4", + StatusCode: 400, + }, + { + ImpId: "imp5", + StatusCode: 500, + }, + }, + }, + want: []openrtb_ext.SeatNonBid{ + { + NonBid: []openrtb_ext.NonBid{ + { + ImpId: "imp1", + StatusCode: 100, + }, + { + ImpId: "imp2", + StatusCode: 200, + }, + }, + Seat: "a", + }, + { + NonBid: []openrtb_ext.NonBid{ + { + ImpId: "imp3", + StatusCode: 300, + }, + }, + Seat: "b", + }, + { + NonBid: []openrtb_ext.NonBid{ + { + ImpId: "imp4", + StatusCode: 400, + }, + { + ImpId: "imp5", + StatusCode: 500, + }, + }, + Seat: "c", + }, + }, + }, } - for i := 0; i < nonBidCount; i++ { - seatNonBid.NonBid = append(seatNonBid.NonBid, openrtb_ext.NonBid{ - Ext: openrtb_ext.NonBidExt{Prebid: openrtb_ext.ExtResponseNonBidPrebid{Bid: openrtb_ext.NonBidObject{}}}, + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + result := test.builder.Slice() + assert.ElementsMatch(t, test.want, result) }) } - seatNonBids = append(seatNonBids, seatNonBid) - return seatNonBids } diff --git a/exchange/targeting.go b/exchange/targeting.go index d5ce7152a77..4f48d70c164 100644 --- a/exchange/targeting.go +++ b/exchange/targeting.go @@ -5,7 +5,7 @@ import ( "strconv" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) const MaxKeyLength = 20 diff --git a/exchange/targeting_test.go b/exchange/targeting_test.go index 13a7572a182..8bfe67475d2 100644 --- a/exchange/targeting_test.go +++ b/exchange/targeting_test.go @@ -8,16 +8,16 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/currency" - "github.com/prebid/prebid-server/v2/exchange/entities" - "github.com/prebid/prebid-server/v2/gdpr" - "github.com/prebid/prebid-server/v2/hooks/hookexecution" - metricsConfig "github.com/prebid/prebid-server/v2/metrics/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/jsonutil" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/currency" + "github.com/prebid/prebid-server/v3/exchange/entities" + "github.com/prebid/prebid-server/v3/gdpr" + "github.com/prebid/prebid-server/v3/hooks/hookexecution" + metricsConfig "github.com/prebid/prebid-server/v3/metrics/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/ptrutil" "github.com/prebid/openrtb/v20/openrtb2" "github.com/stretchr/testify/assert" diff --git a/exchange/tmax_adjustments.go b/exchange/tmax_adjustments.go index 55e2b18ad01..0d0fa31fdc6 100644 --- a/exchange/tmax_adjustments.go +++ b/exchange/tmax_adjustments.go @@ -4,7 +4,7 @@ import ( "context" "time" - "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v3/config" ) type TmaxAdjustmentsPreprocessed struct { diff --git a/exchange/tmax_adjustments_test.go b/exchange/tmax_adjustments_test.go index ce6f1736adf..79252339877 100644 --- a/exchange/tmax_adjustments_test.go +++ b/exchange/tmax_adjustments_test.go @@ -4,7 +4,7 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v3/config" "github.com/stretchr/testify/assert" ) diff --git a/exchange/utils.go b/exchange/utils.go index 9b4ffd21f3e..8c8e63a0147 100644 --- a/exchange/utils.go +++ b/exchange/utils.go @@ -1,7 +1,6 @@ package exchange import ( - "bytes" "context" "encoding/json" "errors" @@ -14,20 +13,20 @@ import ( gppConstants "github.com/prebid/go-gpp/constants" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/firstpartydata" - "github.com/prebid/prebid-server/v2/gdpr" - "github.com/prebid/prebid-server/v2/metrics" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/ortb" - "github.com/prebid/prebid-server/v2/privacy" - "github.com/prebid/prebid-server/v2/privacy/ccpa" - "github.com/prebid/prebid-server/v2/privacy/lmt" - "github.com/prebid/prebid-server/v2/schain" - "github.com/prebid/prebid-server/v2/stored_responses" - "github.com/prebid/prebid-server/v2/util/jsonutil" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/firstpartydata" + "github.com/prebid/prebid-server/v3/gdpr" + "github.com/prebid/prebid-server/v3/metrics" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/ortb" + "github.com/prebid/prebid-server/v3/privacy" + "github.com/prebid/prebid-server/v3/privacy/ccpa" + "github.com/prebid/prebid-server/v3/privacy/lmt" + "github.com/prebid/prebid-server/v3/schain" + "github.com/prebid/prebid-server/v3/stored_responses" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/ptrutil" ) var errInvalidRequestExt = errors.New("request.ext is invalid") @@ -63,18 +62,18 @@ func (rs *requestSplitter) cleanOpenRTBRequests(ctx context.Context, gdprSignal gdpr.Signal, gdprEnforced bool, bidAdjustmentFactors map[string]float64, -) (allowedBidderRequests []BidderRequest, privacyLabels metrics.PrivacyLabels, errs []error) { +) (bidderRequests []BidderRequest, privacyLabels metrics.PrivacyLabels, errs []error) { req := auctionReq.BidRequestWrapper + if err := PreloadExts(req); err != nil { + return + } requestAliases, requestAliasesGVLIDs, errs := getRequestAliases(req) if len(errs) > 0 { return } - allowedBidderRequests = make([]BidderRequest, 0) - bidderImpWithBidResp := stored_responses.InitStoredBidResponses(req.BidRequest, auctionReq.StoredBidResponses) - hasStoredAuctionResponses := len(auctionReq.StoredAuctionResponses) > 0 impsByBidder, err := splitImps(req.BidRequest.Imp, rs.requestValidator, requestAliases, hasStoredAuctionResponses, auctionReq.StoredBidResponses) @@ -83,16 +82,28 @@ func (rs *requestSplitter) cleanOpenRTBRequests(ctx context.Context, return } - var allBidderRequests []BidderRequest - var allBidderRequestErrs []error - allBidderRequests, allBidderRequestErrs = getAuctionBidderRequests(auctionReq, requestExt, rs.bidderToSyncerKey, impsByBidder, requestAliases, rs.hostSChainNode) - if allBidderRequestErrs != nil { - errs = append(errs, allBidderRequestErrs...) + explicitBuyerUIDs, err := extractBuyerUIDs(req.BidRequest.User) + if err != nil { + errs = []error{err} + return + } + lowerCaseExplicitBuyerUIDs := make(map[string]string) + for bidder, uid := range explicitBuyerUIDs { + lowerKey := strings.ToLower(bidder) + lowerCaseExplicitBuyerUIDs[lowerKey] = uid } - bidderNameToBidderReq := buildBidResponseRequest(req.BidRequest, bidderImpWithBidResp, requestAliases, auctionReq.BidderImpReplaceImpID) - //this function should be executed after getAuctionBidderRequests - allBidderRequests = mergeBidderRequests(allBidderRequests, bidderNameToBidderReq) + bidderParamsInReqExt, err := ExtractReqExtBidderParamsMap(req.BidRequest) + if err != nil { + errs = []error{err} + return + } + + sChainWriter, err := schain.NewSChainWriter(requestExt, rs.hostSChainNode) + if err != nil { + errs = []error{err} + return + } var gpp gpplib.GppContainer if req.BidRequest.Regs != nil && len(req.BidRequest.Regs.GPP) > 0 { @@ -103,11 +114,6 @@ func (rs *requestSplitter) cleanOpenRTBRequests(ctx context.Context, } } - if auctionReq.Account.PriceFloors.IsAdjustForBidAdjustmentEnabled() { - //Apply BidAdjustmentFactor to imp.BidFloor - applyBidAdjustmentToFloor(allBidderRequests, bidAdjustmentFactors) - } - consent, err := getConsent(req, gpp) if err != nil { errs = append(errs, err) @@ -148,102 +154,270 @@ func (rs *requestSplitter) cleanOpenRTBRequests(ctx context.Context, gdprPerms = rs.gdprPermsBuilder(auctionReq.TCF2Config, gdprRequestInfo) } - // bidder level privacy policies - for _, bidderRequest := range allBidderRequests { - // fetchBids activity - scopedName := privacy.Component{Type: privacy.ComponentTypeBidder, Name: bidderRequest.BidderName.String()} - fetchBidsActivityAllowed := auctionReq.Activities.Allow(privacy.ActivityFetchBids, scopedName, privacy.NewRequestFromBidRequest(*req)) - if !fetchBidsActivityAllowed { - // skip the call to a bidder if fetchBids activity is not allowed - // do not add this bidder to allowedBidderRequests + bidderRequests = make([]BidderRequest, 0, len(impsByBidder)) + + for bidder, imps := range impsByBidder { + fpdUserEIDsPresent := fpdUserEIDExists(req, auctionReq.FirstPartyData, bidder) + reqWrapperCopy := req.CloneAndClearImpWrappers() + bidRequestCopy := *req.BidRequest + reqWrapperCopy.BidRequest = &bidRequestCopy + reqWrapperCopy.Imp = imps + + coreBidder, isRequestAlias := resolveBidder(bidder, requestAliases) + + // apply bidder-specific schains + sChainWriter.Write(reqWrapperCopy, bidder) + + // eid scrubbing + if err := removeUnpermissionedEids(reqWrapperCopy, bidder); err != nil { + errs = append(errs, fmt.Errorf("unable to enforce request.ext.prebid.data.eidpermissions because %v", err)) continue } - var auctionPermissions gdpr.AuctionPermissions - var gdprErr error + // generate bidder-specific request ext + err = buildRequestExtForBidder(bidder, reqWrapperCopy, bidderParamsInReqExt, auctionReq.Account.AlternateBidderCodes) + if err != nil { + errs = append(errs, err) + continue + } - if gdprEnforced { - auctionPermissions, gdprErr = gdprPerms.AuctionActivitiesAllowed(ctx, bidderRequest.BidderCoreName, bidderRequest.BidderName) - if !auctionPermissions.AllowBidRequest { - // auction request is not permitted by GDPR - // do not add this bidder to allowedBidderRequests - rs.me.RecordAdapterGDPRRequestBlocked(bidderRequest.BidderCoreName) - continue - } + // apply bid adjustments + if auctionReq.Account.PriceFloors.IsAdjustForBidAdjustmentEnabled() { + applyBidAdjustmentToFloor(reqWrapperCopy, bidder, bidAdjustmentFactors) } - ipConf := privacy.IPConf{IPV6: auctionReq.Account.Privacy.IPv6Config, IPV4: auctionReq.Account.Privacy.IPv4Config} + // prepare user + syncerKey := rs.bidderToSyncerKey[string(coreBidder)] + hadSync := prepareUser(reqWrapperCopy, bidder, syncerKey, lowerCaseExplicitBuyerUIDs, auctionReq.UserSyncs) + + auctionPermissions := gdprPerms.AuctionActivitiesAllowed(ctx, coreBidder, openrtb_ext.BidderName(bidder)) - // FPD should be applied before policies, otherwise it overrides policies and activities restricted data - applyFPD(auctionReq.FirstPartyData, bidderRequest) + // privacy blocking + if rs.isBidderBlockedByPrivacy(reqWrapperCopy, auctionReq.Activities, auctionPermissions, coreBidder, openrtb_ext.BidderName(bidder)) { + continue + } - reqWrapper := &openrtb_ext.RequestWrapper{ - BidRequest: ortb.CloneBidRequestPartial(bidderRequest.BidRequest), + // fpd + applyFPD(auctionReq.FirstPartyData, coreBidder, openrtb_ext.BidderName(bidder), isRequestAlias, reqWrapperCopy, fpdUserEIDsPresent) + + // privacy scrubbing + if err := rs.applyPrivacy(reqWrapperCopy, coreBidder, bidder, auctionReq, auctionPermissions, ccpaEnforcer, lmt, coppa); err != nil { + errs = append(errs, err) + continue } - passIDActivityAllowed := auctionReq.Activities.Allow(privacy.ActivityTransmitUserFPD, scopedName, privacy.NewRequestFromBidRequest(*req)) - buyerUIDSet := reqWrapper.User != nil && reqWrapper.User.BuyerUID != "" - buyerUIDRemoved := false - if !passIDActivityAllowed { - privacy.ScrubUserFPD(reqWrapper) - buyerUIDRemoved = true - } else { - // run existing policies (GDPR, CCPA, COPPA, LMT) - // potentially block passing IDs based on GDPR - if gdprEnforced && (gdprErr != nil || !auctionPermissions.PassID) { - privacy.ScrubGdprID(reqWrapper) - buyerUIDRemoved = true - } - // potentially block passing IDs based on CCPA - if ccpaEnforcer.ShouldEnforce(bidderRequest.BidderName.String()) { - privacy.ScrubDeviceIDsIPsUserDemoExt(reqWrapper, ipConf, "eids", false) - buyerUIDRemoved = true + // GPP downgrade: always downgrade unless we can confirm GPP is supported + if shouldSetLegacyPrivacy(rs.bidderInfo, string(coreBidder)) { + setLegacyGDPRFromGPP(reqWrapperCopy, gpp) + setLegacyUSPFromGPP(reqWrapperCopy, gpp) + } + + // remove imps with stored responses so they aren't sent to the bidder + if impResponses, ok := bidderImpWithBidResp[openrtb_ext.BidderName(bidder)]; ok { + removeImpsWithStoredResponses(reqWrapperCopy, impResponses) + } + + // down convert + info, ok := rs.bidderInfo[bidder] + if !ok || info.OpenRTB == nil || info.OpenRTB.Version != "2.6" { + reqWrapperCopy.Regs = ortb.CloneRegs(reqWrapperCopy.Regs) + if err := openrtb_ext.ConvertDownTo25(reqWrapperCopy); err != nil { + errs = append(errs, err) + continue } } - if buyerUIDSet && buyerUIDRemoved { - rs.me.RecordAdapterBuyerUIDScrubbed(bidderRequest.BidderCoreName) + + // sync wrapper + if err := reqWrapperCopy.RebuildRequest(); err != nil { + errs = append(errs, err) + continue } - passGeoActivityAllowed := auctionReq.Activities.Allow(privacy.ActivityTransmitPreciseGeo, scopedName, privacy.NewRequestFromBidRequest(*req)) - if !passGeoActivityAllowed { - privacy.ScrubGeoAndDeviceIP(reqWrapper, ipConf) + // choose labels + bidderLabels := metrics.AdapterLabels{ + Adapter: coreBidder, + } + if !hadSync && req.BidRequest.App == nil { + bidderLabels.CookieFlag = metrics.CookieFlagNo } else { - // run existing policies (GDPR, CCPA, COPPA, LMT) - // potentially block passing geo based on GDPR - if gdprEnforced && (gdprErr != nil || !auctionPermissions.PassGeo) { - privacy.ScrubGeoAndDeviceIP(reqWrapper, ipConf) - } - // potentially block passing geo based on CCPA - if ccpaEnforcer.ShouldEnforce(bidderRequest.BidderName.String()) { - privacy.ScrubDeviceIDsIPsUserDemoExt(reqWrapper, ipConf, "eids", false) - } + bidderLabels.CookieFlag = metrics.CookieFlagYes + } + if len(reqWrapperCopy.Imp) > 0 { + bidderLabels.Source = auctionReq.LegacyLabels.Source + bidderLabels.RType = auctionReq.LegacyLabels.RType + bidderLabels.PubID = auctionReq.LegacyLabels.PubID + bidderLabels.CookieFlag = auctionReq.LegacyLabels.CookieFlag + bidderLabels.AdapterBids = metrics.AdapterBidPresent } - if lmt || coppa { - privacy.ScrubDeviceIDsIPsUserDemoExt(reqWrapper, ipConf, "eids", coppa) + bidderRequest := BidderRequest{ + BidderName: openrtb_ext.BidderName(bidder), + BidderCoreName: coreBidder, + BidRequest: reqWrapperCopy.BidRequest, + IsRequestAlias: isRequestAlias, + BidderStoredResponses: bidderImpWithBidResp[openrtb_ext.BidderName(bidder)], + ImpReplaceImpId: auctionReq.BidderImpReplaceImpID[bidder], + BidderLabels: bidderLabels, } + bidderRequests = append(bidderRequests, bidderRequest) + } + + return +} + +// fpdUserEIDExists determines if req fpd config had User.EIDs +func fpdUserEIDExists(req *openrtb_ext.RequestWrapper, fpd map[openrtb_ext.BidderName]*firstpartydata.ResolvedFirstPartyData, bidder string) bool { + fpdToApply, exists := fpd[openrtb_ext.BidderName(bidder)] + if !exists || fpdToApply == nil { + return false + } + if fpdToApply.User == nil { + return false + } + fpdUserEIDs := fpdToApply.User.EIDs + + if len(fpdUserEIDs) == 0 { + return false + } + if req.User == nil { + return true + } - passTIDAllowed := auctionReq.Activities.Allow(privacy.ActivityTransmitTIDs, scopedName, privacy.NewRequestFromBidRequest(*req)) - if !passTIDAllowed { - privacy.ScrubTID(reqWrapper) + reqUserEIDs := req.User.EIDs + + if len(reqUserEIDs) != len(fpdUserEIDs) { + return true + } + + // if bidder fpd didn't have user.eids then user.eids will remain the same + // hence we can use the same index to compare elements + for i := range reqUserEIDs { + pReqUserEID := &reqUserEIDs[i] + pFpdUserEID := &fpdUserEIDs[i] + if pReqUserEID != pFpdUserEID { + return true } + } + return false +} - err := reqWrapper.RebuildRequest() - if err != nil { - errs = append(errs, err) +// removeImpsWithStoredResponses deletes imps with stored bid resp +func removeImpsWithStoredResponses(req *openrtb_ext.RequestWrapper, impBidResponses map[string]json.RawMessage) { + if len(impBidResponses) == 0 { + return + } + + imps := req.Imp + req.Imp = nil //to indicate this bidder doesn't have real requests + for _, imp := range imps { + if _, ok := impBidResponses[imp.ID]; !ok { + //add real imp back to request + req.Imp = append(req.Imp, imp) } - bidderRequest.BidRequest = reqWrapper.BidRequest + } +} - allowedBidderRequests = append(allowedBidderRequests, bidderRequest) +// PreloadExts ensures all exts have been unmarshalled into wrapper ext objects +func PreloadExts(req *openrtb_ext.RequestWrapper) error { + if req == nil { + return nil + } + if _, err := req.GetRequestExt(); err != nil { + return err + } + if _, err := req.GetUserExt(); err != nil { + return err + } + if _, err := req.GetDeviceExt(); err != nil { + return err + } + if _, err := req.GetRegExt(); err != nil { + return err + } + if _, err := req.GetSiteExt(); err != nil { + return err + } + if _, err := req.GetDOOHExt(); err != nil { + return err + } + if _, err := req.GetSourceExt(); err != nil { + return err + } + return nil +} - // GPP downgrade: always downgrade unless we can confirm GPP is supported - if shouldSetLegacyPrivacy(rs.bidderInfo, string(bidderRequest.BidderCoreName)) { - setLegacyGDPRFromGPP(bidderRequest.BidRequest, gpp) - setLegacyUSPFromGPP(bidderRequest.BidRequest, gpp) +func (rs *requestSplitter) isBidderBlockedByPrivacy(r *openrtb_ext.RequestWrapper, activities privacy.ActivityControl, auctionPermissions gdpr.AuctionPermissions, coreBidder, bidderName openrtb_ext.BidderName) bool { + // activities control + scope := privacy.Component{Type: privacy.ComponentTypeBidder, Name: bidderName.String()} + fetchBidsActivityAllowed := activities.Allow(privacy.ActivityFetchBids, scope, privacy.NewRequestFromBidRequest(*r)) + if !fetchBidsActivityAllowed { + return true + } + + // gdpr + if !auctionPermissions.AllowBidRequest { + rs.me.RecordAdapterGDPRRequestBlocked(coreBidder) + return true + } + + return false +} + +func (rs *requestSplitter) applyPrivacy(reqWrapper *openrtb_ext.RequestWrapper, coreBidderName openrtb_ext.BidderName, bidderName string, auctionReq AuctionRequest, auctionPermissions gdpr.AuctionPermissions, ccpaEnforcer privacy.PolicyEnforcer, lmt bool, coppa bool) error { + scope := privacy.Component{Type: privacy.ComponentTypeBidder, Name: bidderName} + ipConf := privacy.IPConf{IPV6: auctionReq.Account.Privacy.IPv6Config, IPV4: auctionReq.Account.Privacy.IPv4Config} + + bidRequest := ortb.CloneBidRequestPartial(reqWrapper.BidRequest) + reqWrapper.BidRequest = bidRequest + + passIDActivityAllowed := auctionReq.Activities.Allow(privacy.ActivityTransmitUserFPD, scope, privacy.NewRequestFromBidRequest(*reqWrapper)) + buyerUIDSet := reqWrapper.User != nil && reqWrapper.User.BuyerUID != "" + buyerUIDRemoved := false + if !passIDActivityAllowed { + privacy.ScrubUserFPD(reqWrapper) + buyerUIDRemoved = true + } else { + if !auctionPermissions.PassID { + privacy.ScrubGdprID(reqWrapper) + buyerUIDRemoved = true + } + + if ccpaEnforcer.ShouldEnforce(bidderName) { + privacy.ScrubDeviceIDsIPsUserDemoExt(reqWrapper, ipConf, "eids", false) + buyerUIDRemoved = true } } + if buyerUIDSet && buyerUIDRemoved { + rs.me.RecordAdapterBuyerUIDScrubbed(coreBidderName) + } - return + passGeoActivityAllowed := auctionReq.Activities.Allow(privacy.ActivityTransmitPreciseGeo, scope, privacy.NewRequestFromBidRequest(*reqWrapper)) + if !passGeoActivityAllowed { + privacy.ScrubGeoAndDeviceIP(reqWrapper, ipConf) + } else { + if !auctionPermissions.PassGeo { + privacy.ScrubGeoAndDeviceIP(reqWrapper, ipConf) + } + if ccpaEnforcer.ShouldEnforce(bidderName) { + privacy.ScrubDeviceIDsIPsUserDemoExt(reqWrapper, ipConf, "eids", false) + } + } + + if lmt || coppa { + privacy.ScrubDeviceIDsIPsUserDemoExt(reqWrapper, ipConf, "eids", coppa) + } + + passTIDAllowed := auctionReq.Activities.Allow(privacy.ActivityTransmitTIDs, scope, privacy.NewRequestFromBidRequest(*reqWrapper)) + if !passTIDAllowed { + privacy.ScrubTID(reqWrapper) + } + + if err := reqWrapper.RebuildRequest(); err != nil { + return err + } + + // *bidRequest = *reqWrapper.BidRequest + return nil } func shouldSetLegacyPrivacy(bidderInfo config.BidderInfos, bidder string) bool { @@ -316,147 +490,47 @@ func ExtractReqExtBidderParamsMap(bidRequest *openrtb2.BidRequest) (map[string]j return bidderParams, nil } -func getAuctionBidderRequests(auctionRequest AuctionRequest, - requestExt *openrtb_ext.ExtRequest, - bidderToSyncerKey map[string]string, - impsByBidder map[string][]openrtb2.Imp, - requestAliases map[string]string, - hostSChainNode *openrtb2.SupplyChainNode) ([]BidderRequest, []error) { - - bidderRequests := make([]BidderRequest, 0, len(impsByBidder)) - req := auctionRequest.BidRequestWrapper - explicitBuyerUIDs, err := extractBuyerUIDs(req.BidRequest.User) - if err != nil { - return nil, []error{err} - } - - bidderParamsInReqExt, err := ExtractReqExtBidderParamsMap(req.BidRequest) - if err != nil { - return nil, []error{err} - } - - sChainWriter, err := schain.NewSChainWriter(requestExt, hostSChainNode) +func buildRequestExtForBidder(bidder string, req *openrtb_ext.RequestWrapper, reqExtBidderParams map[string]json.RawMessage, cfgABC *openrtb_ext.ExtAlternateBidderCodes) error { + reqExt, err := req.GetRequestExt() if err != nil { - return nil, []error{err} - } - - lowerCaseExplicitBuyerUIDs := make(map[string]string) - for bidder, uid := range explicitBuyerUIDs { - lowerKey := strings.ToLower(bidder) - lowerCaseExplicitBuyerUIDs[lowerKey] = uid - } - - var errs []error - for bidder, imps := range impsByBidder { - coreBidder, isRequestAlias := resolveBidder(bidder, requestAliases) - - reqCopy := *req.BidRequest - reqCopy.Imp = imps - - sChainWriter.Write(&reqCopy, bidder) - - reqCopy.Ext, err = buildRequestExtForBidder(bidder, req.BidRequest.Ext, requestExt, bidderParamsInReqExt, auctionRequest.Account.AlternateBidderCodes) - if err != nil { - return nil, []error{err} - } - - if err := removeUnpermissionedEids(&reqCopy, bidder, requestExt); err != nil { - errs = append(errs, fmt.Errorf("unable to enforce request.ext.prebid.data.eidpermissions because %v", err)) - continue - } - - bidderRequest := BidderRequest{ - BidderName: openrtb_ext.BidderName(bidder), - BidderCoreName: coreBidder, - IsRequestAlias: isRequestAlias, - BidRequest: &reqCopy, - BidderLabels: metrics.AdapterLabels{ - Source: auctionRequest.LegacyLabels.Source, - RType: auctionRequest.LegacyLabels.RType, - Adapter: coreBidder, - PubID: auctionRequest.LegacyLabels.PubID, - CookieFlag: auctionRequest.LegacyLabels.CookieFlag, - AdapterBids: metrics.AdapterBidPresent, - }, - } - - syncerKey := bidderToSyncerKey[string(coreBidder)] - if hadSync := prepareUser(&reqCopy, bidder, syncerKey, lowerCaseExplicitBuyerUIDs, auctionRequest.UserSyncs); !hadSync && req.BidRequest.App == nil { - bidderRequest.BidderLabels.CookieFlag = metrics.CookieFlagNo - } else { - bidderRequest.BidderLabels.CookieFlag = metrics.CookieFlagYes - } - - bidderRequests = append(bidderRequests, bidderRequest) + return err } - return bidderRequests, errs -} + prebid := reqExt.GetPrebid() -func buildRequestExtForBidder(bidder string, requestExt json.RawMessage, requestExtParsed *openrtb_ext.ExtRequest, bidderParamsInReqExt map[string]json.RawMessage, cfgABC *openrtb_ext.ExtAlternateBidderCodes) (json.RawMessage, error) { - // Resolve alternatebiddercode for current bidder + // Resolve alternatebiddercode var reqABC *openrtb_ext.ExtAlternateBidderCodes - if len(requestExt) != 0 && requestExtParsed != nil && requestExtParsed.Prebid.AlternateBidderCodes != nil { - reqABC = requestExtParsed.Prebid.AlternateBidderCodes + if prebid != nil && prebid.AlternateBidderCodes != nil { + reqABC = prebid.AlternateBidderCodes } alternateBidderCodes := buildRequestExtAlternateBidderCodes(bidder, cfgABC, reqABC) - if (len(requestExt) == 0 || requestExtParsed == nil) && alternateBidderCodes == nil { - return nil, nil - } - - // Resolve Bidder Params - var bidderParams json.RawMessage - if bidderParamsInReqExt != nil { - bidderParams = bidderParamsInReqExt[bidder] - } - - // Copy Allowed Fields - // Per: https://docs.prebid.org/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.html#prebid-server-ortb2-extension-summary - prebid := openrtb_ext.ExtRequestPrebid{ - BidderParams: bidderParams, - AlternateBidderCodes: alternateBidderCodes, - } - - if requestExtParsed != nil { - prebid.Channel = requestExtParsed.Prebid.Channel - prebid.CurrencyConversions = requestExtParsed.Prebid.CurrencyConversions - prebid.Debug = requestExtParsed.Prebid.Debug - prebid.Integration = requestExtParsed.Prebid.Integration - prebid.MultiBid = buildRequestExtMultiBid(bidder, requestExtParsed.Prebid.MultiBid, alternateBidderCodes) - prebid.Sdk = requestExtParsed.Prebid.Sdk - prebid.Server = requestExtParsed.Prebid.Server - } - - // Marshal New Prebid Object - prebidJson, err := jsonutil.Marshal(prebid) - if err != nil { - return nil, err - } - - // Parse Existing Ext - extMap := make(map[string]json.RawMessage) - if len(requestExt) != 0 { - if err := jsonutil.Unmarshal(requestExt, &extMap); err != nil { - return nil, err + var prebidNew openrtb_ext.ExtRequestPrebid + if prebid == nil { + prebidNew = openrtb_ext.ExtRequestPrebid{ + BidderParams: reqExtBidderParams[bidder], + AlternateBidderCodes: alternateBidderCodes, } - } - - // Update Ext With Prebid Json - if bytes.Equal(prebidJson, []byte(`{}`)) { - delete(extMap, "prebid") } else { - extMap["prebid"] = prebidJson + // Copy Allowed Fields + // Per: https://docs.prebid.org/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.html#prebid-server-ortb2-extension-summary + prebidNew = openrtb_ext.ExtRequestPrebid{ + BidderParams: reqExtBidderParams[bidder], + AlternateBidderCodes: alternateBidderCodes, + Channel: prebid.Channel, + CurrencyConversions: prebid.CurrencyConversions, + Debug: prebid.Debug, + Integration: prebid.Integration, + MultiBid: buildRequestExtMultiBid(bidder, prebid.MultiBid, alternateBidderCodes), + Sdk: prebid.Sdk, + Server: prebid.Server, + } } - if len(extMap) > 0 { - return jsonutil.Marshal(extMap) - } else { - return nil, nil - } + reqExt.SetPrebid(&prebidNew) + return nil } func buildRequestExtAlternateBidderCodes(bidder string, accABC *openrtb_ext.ExtAlternateBidderCodes, reqABC *openrtb_ext.ExtAlternateBidderCodes) *openrtb_ext.ExtAlternateBidderCodes { - if altBidderCodes := copyExtAlternateBidderCodes(bidder, reqABC); altBidderCodes != nil { return altBidderCodes } @@ -692,7 +766,7 @@ func createSanitizedImpExt(impExt, impExtPrebid map[string]json.RawMessage) (map // // In this function, "givenBidder" may or may not be an alias. "coreBidder" must *not* be an alias. // It returns true if a Cookie User Sync existed, and false otherwise. -func prepareUser(req *openrtb2.BidRequest, givenBidder, syncerKey string, explicitBuyerUIDs map[string]string, usersyncs IdFetcher) bool { +func prepareUser(req *openrtb_ext.RequestWrapper, givenBidder, syncerKey string, explicitBuyerUIDs map[string]string, usersyncs IdFetcher) bool { cookieId, hadCookie, _ := usersyncs.GetUID(syncerKey) if id, ok := explicitBuyerUIDs[strings.ToLower(givenBidder)]; ok { @@ -720,42 +794,32 @@ func copyWithBuyerUID(user *openrtb2.User, buyerUID string) *openrtb2.User { return user } -// removeUnpermissionedEids modifies the request to remove any request.user.ext.eids not permissions for the specific bidder -func removeUnpermissionedEids(request *openrtb2.BidRequest, bidder string, requestExt *openrtb_ext.ExtRequest) error { +// removeUnpermissionedEids modifies the request to remove any request.user.eids not permissions for the specific bidder +func removeUnpermissionedEids(reqWrapper *openrtb_ext.RequestWrapper, bidder string) error { // ensure request might have eids (as much as we can check before unmarshalling) - if request.User == nil || len(request.User.Ext) == 0 { + if reqWrapper.User == nil || len(reqWrapper.User.EIDs) == 0 { return nil } // ensure request has eid permissions to enforce - if requestExt == nil || requestExt.Prebid.Data == nil || len(requestExt.Prebid.Data.EidPermissions) == 0 { - return nil - } - - // low level unmarshal to preserve other request.user.ext values. prebid server is non-destructive. - var userExt map[string]json.RawMessage - if err := jsonutil.Unmarshal(request.User.Ext, &userExt); err != nil { + reqExt, err := reqWrapper.GetRequestExt() + if err != nil { return err } - - eidsJSON, eidsSpecified := userExt["eids"] - if !eidsSpecified { + if reqExt == nil { return nil } - var eids []openrtb2.EID - if err := jsonutil.Unmarshal(eidsJSON, &eids); err != nil { - return err - } - - // exit early if there are no eids (empty array) - if len(eids) == 0 { + reqExtPrebid := reqExt.GetPrebid() + if reqExtPrebid == nil || reqExtPrebid.Data == nil || len(reqExtPrebid.Data.EidPermissions) == 0 { return nil } + eids := reqWrapper.User.EIDs + // translate eid permissions to a map for quick lookup eidRules := make(map[string][]string) - for _, p := range requestExt.Prebid.Data.EidPermissions { + for _, p := range reqExtPrebid.Data.EidPermissions { eidRules[p.Source] = p.Bidders } @@ -783,37 +847,14 @@ func removeUnpermissionedEids(request *openrtb2.BidRequest, bidder string, reque return nil } - // marshal eidsAllowed back to userExt if len(eidsAllowed) == 0 { - delete(userExt, "eids") + reqWrapper.User.EIDs = nil } else { - eidsRaw, err := jsonutil.Marshal(eidsAllowed) - if err != nil { - return err - } - userExt["eids"] = eidsRaw + reqWrapper.User.EIDs = eidsAllowed } - - // exit early if userExt is empty - if len(userExt) == 0 { - setUserExtWithCopy(request, nil) - return nil - } - - userExtJSON, err := jsonutil.Marshal(userExt) - if err != nil { - return err - } - setUserExtWithCopy(request, userExtJSON) return nil } -func setUserExtWithCopy(request *openrtb2.BidRequest, userExtJSON json.RawMessage) { - userCopy := *request.User - userCopy.Ext = userExtJSON - request.User = &userCopy -} - // resolveBidder returns the known BidderName associated with bidder, if bidder is an alias. If it's not an alias, the bidder is returned. func resolveBidder(bidder string, requestAliases map[string]string) (openrtb_ext.BidderName, bool) { normalisedBidderName, _ := openrtb_ext.NormalizeBidderName(bidder) @@ -946,14 +987,19 @@ func getExtBidAdjustmentFactors(requestExtPrebid *openrtb_ext.ExtRequestPrebid) return nil } -func applyFPD(fpd map[openrtb_ext.BidderName]*firstpartydata.ResolvedFirstPartyData, r BidderRequest) { +func applyFPD(fpd map[openrtb_ext.BidderName]*firstpartydata.ResolvedFirstPartyData, + coreBidderName openrtb_ext.BidderName, + bidderName openrtb_ext.BidderName, + isRequestAlias bool, + reqWrapper *openrtb_ext.RequestWrapper, + fpdUserEIDsPresent bool) { if fpd == nil { return } - bidder := r.BidderCoreName - if r.IsRequestAlias { - bidder = r.BidderName + bidder := coreBidderName + if isRequestAlias { + bidder = bidderName } fpdToApply, exists := fpd[bidder] @@ -962,77 +1008,31 @@ func applyFPD(fpd map[openrtb_ext.BidderName]*firstpartydata.ResolvedFirstPartyD } if fpdToApply.Site != nil { - r.BidRequest.Site = fpdToApply.Site + reqWrapper.Site = fpdToApply.Site } if fpdToApply.App != nil { - r.BidRequest.App = fpdToApply.App + reqWrapper.App = fpdToApply.App } if fpdToApply.User != nil { - //BuyerUID is a value obtained between fpd extraction and fpd application. - //BuyerUID needs to be set back to fpd before applying this fpd to final bidder request - if r.BidRequest.User != nil && len(r.BidRequest.User.BuyerUID) > 0 { - fpdToApply.User.BuyerUID = r.BidRequest.User.BuyerUID - } - r.BidRequest.User = fpdToApply.User - } -} - -func buildBidResponseRequest(req *openrtb2.BidRequest, - bidderImpResponses stored_responses.BidderImpsWithBidResponses, - requestAliases map[string]string, - bidderImpReplaceImpID stored_responses.BidderImpReplaceImpID) map[openrtb_ext.BidderName]BidderRequest { - - bidderToBidderResponse := make(map[openrtb_ext.BidderName]BidderRequest) - - for bidderName, impResps := range bidderImpResponses { - resolvedBidder, isRequestAlias := resolveBidder(string(bidderName), requestAliases) - bidderToBidderResponse[bidderName] = BidderRequest{ - BidRequest: req, - BidderCoreName: resolvedBidder, - BidderName: bidderName, - BidderStoredResponses: impResps, - ImpReplaceImpId: bidderImpReplaceImpID[string(bidderName)], - IsRequestAlias: isRequestAlias, - BidderLabels: metrics.AdapterLabels{Adapter: resolvedBidder}, - } - } - return bidderToBidderResponse -} - -func mergeBidderRequests(allBidderRequests []BidderRequest, bidderNameToBidderReq map[openrtb_ext.BidderName]BidderRequest) []BidderRequest { - if len(allBidderRequests) == 0 && len(bidderNameToBidderReq) == 0 { - return allBidderRequests - } - if len(allBidderRequests) == 0 && len(bidderNameToBidderReq) > 0 { - for _, v := range bidderNameToBidderReq { - allBidderRequests = append(allBidderRequests, v) - } - return allBidderRequests - } else if len(allBidderRequests) > 0 && len(bidderNameToBidderReq) > 0 { - //merge bidder requests with real imps and imps with stored resp - for bn, br := range bidderNameToBidderReq { - found := false - for i, ar := range allBidderRequests { - if ar.BidderName == bn { - //bidder req with real imps and imps with stored resp - allBidderRequests[i].BidderStoredResponses = br.BidderStoredResponses - found = true - break - } + if reqWrapper.User != nil { + if len(reqWrapper.User.BuyerUID) > 0 { + //BuyerUID is a value obtained between fpd extraction and fpd application. + //BuyerUID needs to be set back to fpd before applying this fpd to final bidder request + fpdToApply.User.BuyerUID = reqWrapper.User.BuyerUID } - if !found { - //bidder req with stored bid responses only - br.BidRequest.Imp = nil // to indicate this bidder request has bidder responses only - allBidderRequests = append(allBidderRequests, br) + + // if FPD config didn't have user.eids - use reqWrapper.User.EIDs after removeUnpermissionedEids + if !fpdUserEIDsPresent { + fpdToApply.User.EIDs = reqWrapper.User.EIDs } } + reqWrapper.User = fpdToApply.User } - return allBidderRequests } -func setLegacyGDPRFromGPP(r *openrtb2.BidRequest, gpp gpplib.GppContainer) { +func setLegacyGDPRFromGPP(r *openrtb_ext.RequestWrapper, gpp gpplib.GppContainer) { if r.Regs != nil && r.Regs.GDPR == nil { if r.Regs.GPPSID != nil { // Set to 0 unless SID exists @@ -1061,13 +1061,12 @@ func setLegacyGDPRFromGPP(r *openrtb2.BidRequest, gpp gpplib.GppContainer) { } } } - } -func setLegacyUSPFromGPP(r *openrtb2.BidRequest, gpp gpplib.GppContainer) { + +func setLegacyUSPFromGPP(r *openrtb_ext.RequestWrapper, gpp gpplib.GppContainer) { if r.Regs == nil { return } - if len(r.Regs.USPrivacy) > 0 || r.Regs.GPPSID == nil { return } @@ -1082,7 +1081,6 @@ func setLegacyUSPFromGPP(r *openrtb2.BidRequest, gpp gpplib.GppContainer) { } } } - } func WrapJSONInData(data []byte) []byte { @@ -1143,24 +1141,20 @@ func getPrebidMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) { } } -func applyBidAdjustmentToFloor(allBidderRequests []BidderRequest, bidAdjustmentFactors map[string]float64) { - - if len(bidAdjustmentFactors) == 0 { +func applyBidAdjustmentToFloor(req *openrtb_ext.RequestWrapper, bidder string, adjustmentFactors map[string]float64) { + if len(adjustmentFactors) == 0 { return } - for _, bidderRequest := range allBidderRequests { - bidAdjustment := 1.0 - - if bidAdjustemntValue, ok := bidAdjustmentFactors[string(bidderRequest.BidderName)]; ok { - bidAdjustment = bidAdjustemntValue - } + bidAdjustment := 1.0 + if v, ok := adjustmentFactors[bidder]; ok && v != 0.0 { + bidAdjustment = v + } - if bidAdjustment != 1.0 { - for index, imp := range bidderRequest.BidRequest.Imp { - imp.BidFloor = imp.BidFloor / bidAdjustment - bidderRequest.BidRequest.Imp[index] = imp - } + if bidAdjustment != 1.0 { + for index, imp := range req.Imp { + imp.BidFloor = imp.BidFloor / bidAdjustment + req.Imp[index] = imp } } } diff --git a/exchange/utils_test.go b/exchange/utils_test.go index 69cfdf70abf..67ad46dd725 100644 --- a/exchange/utils_test.go +++ b/exchange/utils_test.go @@ -4,24 +4,21 @@ import ( "context" "encoding/json" "errors" - "fmt" "sort" "testing" - "github.com/prebid/prebid-server/v2/stored_responses" - gpplib "github.com/prebid/go-gpp" "github.com/prebid/go-gpp/constants" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/firstpartydata" - "github.com/prebid/prebid-server/v2/gdpr" - "github.com/prebid/prebid-server/v2/metrics" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/privacy" - "github.com/prebid/prebid-server/v2/util/jsonutil" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/firstpartydata" + "github.com/prebid/prebid-server/v3/gdpr" + "github.com/prebid/prebid-server/v3/metrics" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/privacy" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/ptrutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" @@ -46,7 +43,7 @@ func (p *permissionsMock) BidderSyncAllowed(ctx context.Context, bidder openrtb_ return true, nil } -func (p *permissionsMock) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) (gdpr.AuctionPermissions, error) { +func (p *permissionsMock) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) gdpr.AuctionPermissions { permissions := gdpr.AuctionPermissions{ PassGeo: p.passGeo, PassID: p.passID, @@ -54,7 +51,7 @@ func (p *permissionsMock) AuctionActivitiesAllowed(ctx context.Context, bidderCo if p.allowAllBidders { permissions.AllowBidRequest = true - return permissions, p.activitiesError + return permissions } for _, allowedBidder := range p.allowedBidders { @@ -63,7 +60,7 @@ func (p *permissionsMock) AuctionActivitiesAllowed(ctx context.Context, bidderCo } } - return permissions, p.activitiesError + return permissions } type fakePermissionsBuilder struct { @@ -967,7 +964,7 @@ func TestCleanOpenRTBRequestsWithBidResponses(t *testing.T) { W: ptrutil.ToPtr[int64](300), H: ptrutil.ToPtr[int64](250), }, - Ext: json.RawMessage(`{"prebid":{"bidder":{"bidderA":{"placementId":"123"}}}}`), + Ext: json.RawMessage(`{"prebid":{"bidder":{"bidderA":{"placementId":"123"},"bidderB":{"placementId":"456"}}}}`), }, }, expectedBidderRequests: map[string]BidderRequest{ @@ -998,7 +995,7 @@ func TestCleanOpenRTBRequestsWithBidResponses(t *testing.T) { W: ptrutil.ToPtr[int64](300), H: ptrutil.ToPtr[int64](250), }, - Ext: json.RawMessage(`{"prebid":{"bidder":{"bidderA":{"placementId":"123"}}}}`), + Ext: json.RawMessage(`{"prebid":{"bidder":{"bidderA":{"placementId":"123"},"bidderB":{"placementId":"456"}}}}`), }, { ID: "imp-id2", @@ -1038,7 +1035,7 @@ func TestCleanOpenRTBRequestsWithBidResponses(t *testing.T) { W: ptrutil.ToPtr[int64](300), H: ptrutil.ToPtr[int64](250), }, - Ext: json.RawMessage(`{"prebid":{"bidder":{"bidderA":{"placementId":"123"}}}}`), + Ext: json.RawMessage(`{"prebid":{"bidder":{"bidderA":{"placementId":"123"},"bidderB":{"placementId":"456"}}}}`), }, { ID: "imp-id2", @@ -1104,11 +1101,11 @@ func TestCleanOpenRTBRequestsWithBidResponses(t *testing.T) { imps: []openrtb2.Imp{ { ID: "imp-id1", - Ext: json.RawMessage(`"prebid": {}`), + Ext: json.RawMessage(`{"prebid":{"bidder":{"bidderA":{"placementId":"123"}}}}`), }, { ID: "imp-id2", - Ext: json.RawMessage(`"prebid": {}`), + Ext: json.RawMessage(`{"prebid":{"bidder":{"bidderA":{"placementId":"123"}}}}`), }, }, expectedBidderRequests: map[string]BidderRequest{ @@ -1279,7 +1276,7 @@ func TestCleanOpenRTBRequestsCCPA(t *testing.T) { req := newBidRequest(t) req.Ext = test.reqExt req.Regs = &openrtb2.Regs{ - Ext: json.RawMessage(`{"us_privacy":"` + test.ccpaConsent + `"}`), + USPrivacy: test.ccpaConsent, } privacyConfig := config.Privacy{ @@ -1339,32 +1336,32 @@ func TestCleanOpenRTBRequestsCCPA(t *testing.T) { func TestCleanOpenRTBRequestsCCPAErrors(t *testing.T) { testCases := []struct { - description string - reqExt json.RawMessage - reqRegsExt json.RawMessage - expectError error + description string + reqExt json.RawMessage + reqRegsPrivacy string + expectError error }{ { - description: "Invalid Consent", - reqExt: json.RawMessage(`{"prebid":{"nosale":["*"]}}`), - reqRegsExt: json.RawMessage(`{"us_privacy":"malformed"}`), + description: "Invalid Consent", + reqExt: json.RawMessage(`{"prebid":{"nosale":["*"]}}`), + reqRegsPrivacy: "malformed", expectError: &errortypes.Warning{ Message: "request.regs.ext.us_privacy must contain 4 characters", WarningCode: errortypes.InvalidPrivacyConsentWarningCode, }, }, { - description: "Invalid No Sale Bidders", - reqExt: json.RawMessage(`{"prebid":{"nosale":["*", "another"]}}`), - reqRegsExt: json.RawMessage(`{"us_privacy":"1NYN"}`), - expectError: errors.New("request.ext.prebid.nosale is invalid: can only specify all bidders if no other bidders are provided"), + description: "Invalid No Sale Bidders", + reqExt: json.RawMessage(`{"prebid":{"nosale":["*", "another"]}}`), + reqRegsPrivacy: "1NYN", + expectError: errors.New("request.ext.prebid.nosale is invalid: can only specify all bidders if no other bidders are provided"), }, } for _, test := range testCases { req := newBidRequest(t) req.Ext = test.reqExt - req.Regs = &openrtb2.Regs{Ext: test.reqRegsExt} + req.Regs = &openrtb2.Regs{USPrivacy: test.reqRegsPrivacy} var reqExtStruct openrtb_ext.ExtRequest err := jsonutil.UnmarshalValid(req.Ext, &reqExtStruct) @@ -1480,46 +1477,114 @@ func TestCleanOpenRTBRequestsSChain(t *testing.T) { testCases := []struct { description string inExt json.RawMessage - inSourceExt json.RawMessage + inSChain *openrtb2.SupplyChain outRequestExt json.RawMessage - outSourceExt json.RawMessage + outSource *openrtb2.Source hasError bool + ortbVersion string }{ { description: "nil", inExt: nil, - inSourceExt: nil, + inSChain: nil, outRequestExt: nil, - outSourceExt: nil, + outSource: &openrtb2.Source{ + TID: "testTID", + SChain: nil, + Ext: nil, + }, }, { - description: "ORTB 2.5 chain at source.ext.schain", - inExt: nil, - inSourceExt: json.RawMessage(`{` + seller1SChain + `}`), + description: "Supply Chain defined in request.Source.supplyChain", + inExt: nil, + inSChain: &openrtb2.SupplyChain{ + Complete: 1, + Ver: "1.0", + Ext: nil, + Nodes: []openrtb2.SupplyChainNode{ + { + ASI: "directseller1.com", + SID: "00001", + RID: "BidRequest1", + HP: openrtb2.Int8Ptr(1), + Ext: nil, + }, + }, + }, outRequestExt: nil, - outSourceExt: json.RawMessage(`{` + seller1SChain + `}`), + outSource: &openrtb2.Source{ + TID: "testTID", + SChain: &openrtb2.SupplyChain{ + Complete: 1, + Ver: "1.0", + Ext: nil, + Nodes: []openrtb2.SupplyChainNode{ + { + ASI: "directseller1.com", + SID: "00001", + RID: "BidRequest1", + HP: openrtb2.Int8Ptr(1), + Ext: nil, + }, + }, + }, + Ext: nil, + }, + ortbVersion: "2.6", }, { - description: "ORTB 2.5 schain at request.ext.prebid.schains", + description: "Supply Chain defined in request.ext.prebid.schains", inExt: json.RawMessage(`{"prebid":{"schains":[{"bidders":["appnexus"],` + seller1SChain + `}]}}`), - inSourceExt: nil, + inSChain: nil, outRequestExt: nil, - outSourceExt: json.RawMessage(`{` + seller1SChain + `}`), + outSource: &openrtb2.Source{ + TID: "testTID", + SChain: &openrtb2.SupplyChain{ + Complete: 1, + Ver: "1.0", + Ext: nil, + Nodes: []openrtb2.SupplyChainNode{ + { + ASI: "directseller1.com", + SID: "00001", + RID: "BidRequest1", + HP: openrtb2.Int8Ptr(1), + Ext: nil, + }, + }, + }, + Ext: nil, + }, + ortbVersion: "2.6", }, { - description: "schainwriter instantation error -- multiple bidder schains in ext.prebid.schains.", - inExt: json.RawMessage(`{"prebid":{"schains":[{"bidders":["appnexus"],` + seller1SChain + `},{"bidders":["appnexus"],` + seller2SChain + `}]}}`), - inSourceExt: json.RawMessage(`{` + seller1SChain + `}`), + description: "schainwriter instantation error -- multiple bidder schains in ext.prebid.schains.", + inExt: json.RawMessage(`{"prebid":{"schains":[{"bidders":["appnexus"],` + seller1SChain + `},{"bidders":["appnexus"],` + seller2SChain + `}]}}`), + inSChain: &openrtb2.SupplyChain{ + Complete: 1, + Ver: "1.0", + Ext: nil, + Nodes: []openrtb2.SupplyChainNode{ + { + ASI: "directseller1.com", + SID: "00001", + RID: "BidRequest1", + HP: openrtb2.Int8Ptr(1), + Ext: nil, + }, + }, + }, + outRequestExt: nil, - outSourceExt: nil, + outSource: nil, hasError: true, }, } for _, test := range testCases { req := newBidRequest(t) - if test.inSourceExt != nil { - req.Source.Ext = test.inSourceExt + if test.inSChain != nil { + req.Source.SChain = test.inSChain } var extRequest *openrtb_ext.ExtRequest @@ -1548,7 +1613,7 @@ func TestCleanOpenRTBRequestsSChain(t *testing.T) { privacyConfig: config.Privacy{}, gdprPermsBuilder: gdprPermissionsBuilder, hostSChainNode: nil, - bidderInfo: config.BidderInfos{}, + bidderInfo: config.BidderInfos{"appnexus": config.BidderInfo{OpenRTB: &config.OpenRTBInfo{Version: test.ortbVersion}}}, } bidderRequests, _, errs := reqSplitter.cleanOpenRTBRequests(context.Background(), auctionReq, extRequest, gdpr.SignalNo, false, map[string]float64{}) @@ -1558,7 +1623,7 @@ func TestCleanOpenRTBRequestsSChain(t *testing.T) { } else { result := bidderRequests[0] assert.Nil(t, errs) - assert.Equal(t, test.outSourceExt, result.BidRequest.Source.Ext, test.description+":Source.Ext") + assert.Equal(t, test.outSource, result.BidRequest.Source, test.description+":Source") assert.Equal(t, test.outRequestExt, result.BidRequest.Ext, test.description+":Ext") } } @@ -2291,7 +2356,7 @@ func TestCleanOpenRTBRequestsGDPR(t *testing.T) { for _, test := range testCases { req := newBidRequest(t) - req.User.Ext = json.RawMessage(`{"consent":"` + test.gdprConsent + `"}`) + req.User.Consent = test.gdprConsent privacyConfig := config.Privacy{} accountConfig := config.Account{} @@ -2473,14 +2538,14 @@ func TestCleanOpenRTBRequestsWithOpenRTBDowngrade(t *testing.T) { req: AuctionRequest{BidRequestWrapper: &openrtb_ext.RequestWrapper{BidRequest: bidReq}, UserSyncs: &emptyUsersync{}, TCF2Config: emptyTCF2Config}, expectRegs: &downgradedRegs, expectUser: &downgradedUser, - bidderInfos: config.BidderInfos{"appnexus": config.BidderInfo{OpenRTB: &config.OpenRTBInfo{GPPSupported: false}}}, + bidderInfos: config.BidderInfos{"appnexus": config.BidderInfo{OpenRTB: &config.OpenRTBInfo{GPPSupported: false, Version: "2.6"}}}, }, { name: "Supported", req: AuctionRequest{BidRequestWrapper: &openrtb_ext.RequestWrapper{BidRequest: bidReq}, UserSyncs: &emptyUsersync{}, TCF2Config: emptyTCF2Config}, expectRegs: bidReq.Regs, expectUser: bidReq.User, - bidderInfos: config.BidderInfos{"appnexus": config.BidderInfo{OpenRTB: &config.OpenRTBInfo{GPPSupported: true}}}, + bidderInfos: config.BidderInfos{"appnexus": config.BidderInfo{OpenRTB: &config.OpenRTBInfo{GPPSupported: true, Version: "2.6"}}}, }, } @@ -2527,145 +2592,146 @@ func TestBuildRequestExtForBidder(t *testing.T) { ) testCases := []struct { - description string + name string requestExt json.RawMessage bidderParams map[string]json.RawMessage alternateBidderCodes *openrtb_ext.ExtAlternateBidderCodes expectedJson json.RawMessage }{ { - description: "Nil", + name: "Nil", bidderParams: nil, requestExt: nil, alternateBidderCodes: nil, expectedJson: nil, }, { - description: "Empty", + name: "Empty", bidderParams: nil, alternateBidderCodes: nil, requestExt: json.RawMessage(`{}`), expectedJson: nil, }, { - description: "Prebid - Allowed Fields Only", + name: "Prebid - Allowed Fields Only", bidderParams: nil, requestExt: json.RawMessage(`{"prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}, "server": {"externalurl": "url", "gvlid": 1, "datacenter": "2"}, "sdk": {"renderers": [{"name": "r1"}]}}}`), expectedJson: json.RawMessage(`{"prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}, "server": {"externalurl": "url", "gvlid": 1, "datacenter": "2"}, "sdk": {"renderers": [{"name": "r1"}]}}}`), }, { - description: "Prebid - Allowed Fields + Bidder Params", + name: "Prebid - Allowed Fields + Bidder Params", bidderParams: map[string]json.RawMessage{bidder: bidderParams}, requestExt: json.RawMessage(`{"prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}, "server": {"externalurl": "url", "gvlid": 1, "datacenter": "2"}, "sdk": {"renderers": [{"name": "r1"}]}}}`), expectedJson: json.RawMessage(`{"prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}, "server": {"externalurl": "url", "gvlid": 1, "datacenter": "2"}, "sdk": {"renderers": [{"name": "r1"}]}, "bidderparams":"bar"}}`), }, { - description: "Other", + name: "Other", bidderParams: nil, requestExt: json.RawMessage(`{"other":"foo"}`), expectedJson: json.RawMessage(`{"other":"foo"}`), }, { - description: "Prebid + Other + Bider Params", + name: "Prebid + Other + Bider Params", bidderParams: map[string]json.RawMessage{bidder: bidderParams}, requestExt: json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}, "server": {"externalurl": "url", "gvlid": 1, "datacenter": "2"}, "sdk": {"renderers": [{"name": "r1"}]}}}`), expectedJson: json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}, "server": {"externalurl": "url", "gvlid": 1, "datacenter": "2"}, "sdk": {"renderers": [{"name": "r1"}]}, "bidderparams":"bar"}}`), }, { - description: "Prebid + AlternateBidderCodes in pbs config but current bidder not in AlternateBidderCodes config", + name: "Prebid + AlternateBidderCodes in pbs config but current bidder not in AlternateBidderCodes config", bidderParams: map[string]json.RawMessage{bidder: bidderParams}, alternateBidderCodes: &openrtb_ext.ExtAlternateBidderCodes{Enabled: true, Bidders: map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{"bar": {Enabled: true, AllowedBidderCodes: []string{"*"}}}}, requestExt: json.RawMessage(`{"other":"foo"}`), expectedJson: json.RawMessage(`{"other":"foo","prebid":{"alternatebiddercodes":{"enabled":true,"bidders":null},"bidderparams":"bar"}}`), }, { - description: "Prebid + AlternateBidderCodes in request", + name: "Prebid + AlternateBidderCodes in request", bidderParams: map[string]json.RawMessage{bidder: bidderParams}, alternateBidderCodes: &openrtb_ext.ExtAlternateBidderCodes{}, requestExt: json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true},"alternatebiddercodes":{"enabled":true,"bidders":{"foo":{"enabled":true,"allowedbiddercodes":["foo2"]},"bar":{"enabled":true,"allowedbiddercodes":["ix"]}}}}}`), expectedJson: json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true},"alternatebiddercodes":{"enabled":true,"bidders":{"foo":{"enabled":true,"allowedbiddercodes":["foo2"]}}},"bidderparams":"bar"}}`), }, { - description: "Prebid + AlternateBidderCodes in request but current bidder not in AlternateBidderCodes config", + name: "Prebid + AlternateBidderCodes in request but current bidder not in AlternateBidderCodes config", bidderParams: map[string]json.RawMessage{bidder: bidderParams}, alternateBidderCodes: &openrtb_ext.ExtAlternateBidderCodes{}, requestExt: json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true},"alternatebiddercodes":{"enabled":true,"bidders":{"bar":{"enabled":true,"allowedbiddercodes":["ix"]}}}}}`), expectedJson: json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true},"alternatebiddercodes":{"enabled":true,"bidders":null},"bidderparams":"bar"}}`), }, { - description: "Prebid + AlternateBidderCodes in both pbs config and in the request", + name: "Prebid + AlternateBidderCodes in both pbs config and in the request", bidderParams: map[string]json.RawMessage{bidder: bidderParams}, alternateBidderCodes: &openrtb_ext.ExtAlternateBidderCodes{Enabled: true, Bidders: map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{"foo": {Enabled: true, AllowedBidderCodes: []string{"*"}}}}, requestExt: json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true},"alternatebiddercodes":{"enabled":true,"bidders":{"foo":{"enabled":true,"allowedbiddercodes":["foo2"]},"bar":{"enabled":true,"allowedbiddercodes":["ix"]}}}}}`), expectedJson: json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true},"alternatebiddercodes":{"enabled":true,"bidders":{"foo":{"enabled":true,"allowedbiddercodes":["foo2"]}}},"bidderparams":"bar"}}`), }, { - description: "Prebid + Other + Bider Params + MultiBid.Bidder", + name: "Prebid + Other + Bider Params + MultiBid.Bidder", bidderParams: map[string]json.RawMessage{bidder: bidderParams}, requestExt: json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true},"multibid":[{"bidder":"foo","maxbids":2,"targetbiddercodeprefix":"fmb"},{"bidders":["appnexus","groupm"],"maxbids":2}]}}`), expectedJson: json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true},"multibid":[{"bidder":"foo","maxbids":2,"targetbiddercodeprefix":"fmb"}],"bidderparams":"bar"}}`), }, { - description: "Prebid + Other + Bider Params + MultiBid.Bidders", + name: "Prebid + Other + Bider Params + MultiBid.Bidders", bidderParams: map[string]json.RawMessage{bidder: bidderParams}, requestExt: json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true},"multibid":[{"bidder":"pubmatic","maxbids":3,"targetbiddercodeprefix":"pubM"},{"bidders":["foo","groupm"],"maxbids":4}]}}`), expectedJson: json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true},"multibid":[{"bidders":["foo"],"maxbids":4}],"bidderparams":"bar"}}`), }, { - description: "Prebid + Other + Bider Params + MultiBid (foo not in MultiBid)", + name: "Prebid + Other + Bider Params + MultiBid (foo not in MultiBid)", bidderParams: map[string]json.RawMessage{bidder: bidderParams}, requestExt: json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true},"multibid":[{"bidder":"foo2","maxbids":2,"targetbiddercodeprefix":"fmb"},{"bidders":["appnexus","groupm"],"maxbids":2}]}}`), expectedJson: json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true},"bidderparams":"bar"}}`), }, { - description: "Prebid + Other + Bider Params + MultiBid (foo not in MultiBid)", + name: "Prebid + Other + Bider Params + MultiBid (foo not in MultiBid)", bidderParams: map[string]json.RawMessage{bidder: bidderParams}, requestExt: json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true},"multibid":[{"bidder":"foo2","maxbids":2,"targetbiddercodeprefix":"fmb"},{"bidders":["appnexus","groupm"],"maxbids":2}]}}`), expectedJson: json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true},"bidderparams":"bar"}}`), }, { - description: "Prebid + AlternateBidderCodes.MultiBid.Bidder", + name: "Prebid + AlternateBidderCodes.MultiBid.Bidder", requestExt: json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true},"alternatebiddercodes":{"enabled":true,"bidders":{"foo":{"enabled":true,"allowedbiddercodes":["pubmatic"]}}},"multibid":[{"bidder":"foo","maxbids":3,"targetbiddercodeprefix":"fmb"},{"bidder":"foo2","maxbids":4,"targetbiddercodeprefix":"fmb2"},{"bidder":"pubmatic","maxbids":5,"targetbiddercodeprefix":"pm"}]}}`), expectedJson: json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true},"alternatebiddercodes":{"enabled":true,"bidders":{"foo":{"enabled":true,"allowedbiddercodes":["pubmatic"]}}},"multibid":[{"bidder":"foo","maxbids":3,"targetbiddercodeprefix":"fmb"},{"bidder":"pubmatic","maxbids":5,"targetbiddercodeprefix":"pm"}]}}`), }, { - description: "Prebid + AlternateBidderCodes.MultiBid.Bidders", + name: "Prebid + AlternateBidderCodes.MultiBid.Bidders", requestExt: json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true},"alternatebiddercodes":{"enabled":true,"bidders":{"foo":{"enabled":true,"allowedbiddercodes":["pubmatic"]}}},"multibid":[{"bidder":"foo","maxbids":3,"targetbiddercodeprefix":"fmb"},{"bidders":["pubmatic","groupm"],"maxbids":4}]}}`), expectedJson: json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true},"alternatebiddercodes":{"enabled":true,"bidders":{"foo":{"enabled":true,"allowedbiddercodes":["pubmatic"]}}},"multibid":[{"bidder":"foo","maxbids":3,"targetbiddercodeprefix":"fmb"},{"bidders":["pubmatic"],"maxbids":4}]}}`), }, { - description: "Prebid + AlternateBidderCodes.MultiBid.Bidder with *", + name: "Prebid + AlternateBidderCodes.MultiBid.Bidder with *", requestExt: json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true},"alternatebiddercodes":{"enabled":true,"bidders":{"foo":{"enabled":true,"allowedbiddercodes":["*"]}}},"multibid":[{"bidder":"foo","maxbids":3,"targetbiddercodeprefix":"fmb"},{"bidder":"foo2","maxbids":4,"targetbiddercodeprefix":"fmb2"},{"bidder":"pubmatic","maxbids":5,"targetbiddercodeprefix":"pm"}]}}`), expectedJson: json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true},"alternatebiddercodes":{"enabled":true,"bidders":{"foo":{"enabled":true,"allowedbiddercodes":["*"]}}},"multibid":[{"bidder":"foo","maxbids":3,"targetbiddercodeprefix":"fmb"},{"bidder":"foo2","maxbids":4,"targetbiddercodeprefix":"fmb2"},{"bidder":"pubmatic","maxbids":5,"targetbiddercodeprefix":"pm"}]}}`), }, { - description: "Prebid + AlternateBidderCodes.MultiBid.Bidders with *", + name: "Prebid + AlternateBidderCodes.MultiBid.Bidders with *", requestExt: json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true},"alternatebiddercodes":{"enabled":true,"bidders":{"foo":{"enabled":true,"allowedbiddercodes":["*"]}}},"multibid":[{"bidder":"foo","maxbids":3,"targetbiddercodeprefix":"fmb"},{"bidders":["pubmatic","groupm"],"maxbids":4}]}}`), expectedJson: json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true},"alternatebiddercodes":{"enabled":true,"bidders":{"foo":{"enabled":true,"allowedbiddercodes":["*"]}}},"multibid":[{"bidder":"foo","maxbids":3,"targetbiddercodeprefix":"fmb"},{"bidders":["pubmatic"],"maxbids":4},{"bidders":["groupm"],"maxbids":4}]}}`), }, { - description: "Prebid + AlternateBidderCodes + MultiBid", + name: "Prebid + AlternateBidderCodes + MultiBid", requestExt: json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true},"alternatebiddercodes":{"enabled":true,"bidders":{"foo":{"enabled":true,"allowedbiddercodes":["foo2"]}}},"multibid":[{"bidder":"foo3","maxbids":3,"targetbiddercodeprefix":"fmb"},{"bidders":["pubmatic","groupm"],"maxbids":4}]}}`), expectedJson: json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true},"alternatebiddercodes":{"enabled":true,"bidders":{"foo":{"enabled":true,"allowedbiddercodes":["foo2"]}}}}}`), }, } for _, test := range testCases { - requestExtParsed := &openrtb_ext.ExtRequest{} - if test.requestExt != nil { - err := jsonutil.UnmarshalValid(test.requestExt, requestExtParsed) - if !assert.NoError(t, err, test.description+":parse_ext") { - continue + t.Run(test.name, func(t *testing.T) { + req := openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Ext: test.requestExt, + }, } - } + err := buildRequestExtForBidder(bidder, &req, test.bidderParams, test.alternateBidderCodes) + assert.NoError(t, req.RebuildRequest()) + assert.NoError(t, err) - actualJson, actualErr := buildRequestExtForBidder(bidder, test.requestExt, requestExtParsed, test.bidderParams, test.alternateBidderCodes) - if len(test.expectedJson) > 0 { - assert.JSONEq(t, string(test.expectedJson), string(actualJson), test.description+":json") - } else { - assert.Equal(t, test.expectedJson, actualJson, test.description+":json") - } - assert.NoError(t, actualErr, test.description+":err") + if len(test.expectedJson) > 0 { + assert.JSONEq(t, string(test.expectedJson), string(req.Ext)) + } else { + assert.Equal(t, test.expectedJson, req.Ext) + } + }) } } @@ -2673,28 +2739,37 @@ func TestBuildRequestExtForBidder_RequestExtParsedNil(t *testing.T) { var ( bidder = "foo" requestExt = json.RawMessage(`{}`) - requestExtParsed *openrtb_ext.ExtRequest bidderParams map[string]json.RawMessage alternateBidderCodes *openrtb_ext.ExtAlternateBidderCodes ) - actualJson, actualErr := buildRequestExtForBidder(bidder, requestExt, requestExtParsed, bidderParams, alternateBidderCodes) - assert.Nil(t, actualJson) - assert.NoError(t, actualErr) + req := openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Ext: requestExt, + }, + } + err := buildRequestExtForBidder(bidder, &req, bidderParams, alternateBidderCodes) + assert.NoError(t, req.RebuildRequest()) + assert.Nil(t, req.Ext) + assert.NoError(t, err) } func TestBuildRequestExtForBidder_RequestExtMalformed(t *testing.T) { var ( bidder = "foo" requestExt = json.RawMessage(`malformed`) - requestExtParsed = &openrtb_ext.ExtRequest{} bidderParams map[string]json.RawMessage alternateBidderCodes *openrtb_ext.ExtAlternateBidderCodes ) - actualJson, actualErr := buildRequestExtForBidder(bidder, requestExt, requestExtParsed, bidderParams, alternateBidderCodes) - assert.Equal(t, json.RawMessage(nil), actualJson) - assert.EqualError(t, actualErr, "expect { or n, but found m") + req := openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Ext: requestExt, + }, + } + err := buildRequestExtForBidder(bidder, &req, bidderParams, alternateBidderCodes) + assert.NoError(t, req.RebuildRequest()) + assert.EqualError(t, err, "expect { or n, but found m") } // newAdapterAliasBidRequest builds a BidRequest with aliases @@ -2880,193 +2955,112 @@ func TestRemoveUnpermissionedEids(t *testing.T) { bidder := "bidderA" testCases := []struct { - description string - userExt json.RawMessage - eidPermissions []openrtb_ext.ExtRequestPrebidDataEidPermission - expectedUserExt json.RawMessage + description string + userEids []openrtb2.EID + eidPermissions []openrtb_ext.ExtRequestPrebidDataEidPermission + expectedUserEids []openrtb2.EID }{ - { - description: "Extension Nil", - userExt: nil, - eidPermissions: []openrtb_ext.ExtRequestPrebidDataEidPermission{ - {Source: "source1", Bidders: []string{"bidderA"}}, - }, - expectedUserExt: nil, - }, - { - description: "Extension Empty", - userExt: json.RawMessage(`{}`), - eidPermissions: []openrtb_ext.ExtRequestPrebidDataEidPermission{ - {Source: "source1", Bidders: []string{"bidderA"}}, - }, - expectedUserExt: json.RawMessage(`{}`), - }, - { - description: "Extension Empty - Keep Other Data", - userExt: json.RawMessage(`{"other":42}`), - eidPermissions: []openrtb_ext.ExtRequestPrebidDataEidPermission{ - {Source: "source1", Bidders: []string{"bidderA"}}, - }, - expectedUserExt: json.RawMessage(`{"other":42}`), - }, + { description: "Eids Empty", - userExt: json.RawMessage(`{"eids":[]}`), + userEids: []openrtb2.EID{}, eidPermissions: []openrtb_ext.ExtRequestPrebidDataEidPermission{ {Source: "source1", Bidders: []string{"bidderA"}}, }, - expectedUserExt: json.RawMessage(`{"eids":[]}`), + expectedUserEids: []openrtb2.EID{}, }, { - description: "Eids Empty - Keep Other Data", - userExt: json.RawMessage(`{"eids":[],"other":42}`), - eidPermissions: []openrtb_ext.ExtRequestPrebidDataEidPermission{ - {Source: "source1", Bidders: []string{"bidderA"}}, - }, - expectedUserExt: json.RawMessage(`{"eids":[],"other":42}`), - }, - { - description: "Allowed By Nil Permissions", - userExt: json.RawMessage(`{"eids":[{"source":"source1","uids":[{"id":"anyID"}]}]}`), - eidPermissions: nil, - expectedUserExt: json.RawMessage(`{"eids":[{"source":"source1","uids":[{"id":"anyID"}]}]}`), + description: "Allowed By Nil Permissions", + userEids: []openrtb2.EID{{Source: "source1", UIDs: []openrtb2.UID{{ID: "anyID"}}}}, + eidPermissions: nil, + expectedUserEids: []openrtb2.EID{{Source: "source1", UIDs: []openrtb2.UID{{ID: "anyID"}}}}, }, { - description: "Allowed By Empty Permissions", - userExt: json.RawMessage(`{"eids":[{"source":"source1","uids":[{"id":"anyID"}]}]}`), - eidPermissions: []openrtb_ext.ExtRequestPrebidDataEidPermission{}, - expectedUserExt: json.RawMessage(`{"eids":[{"source":"source1","uids":[{"id":"anyID"}]}]}`), + description: "Allowed By Empty Permissions", + userEids: []openrtb2.EID{{Source: "source1", UIDs: []openrtb2.UID{{ID: "anyID"}}}}, + eidPermissions: []openrtb_ext.ExtRequestPrebidDataEidPermission{}, + expectedUserEids: []openrtb2.EID{{Source: "source1", UIDs: []openrtb2.UID{{ID: "anyID"}}}}, }, { description: "Allowed By Specific Bidder", - userExt: json.RawMessage(`{"eids":[{"source":"source1","uids":[{"id":"anyID"}]}]}`), + userEids: []openrtb2.EID{{Source: "source1", UIDs: []openrtb2.UID{{ID: "anyID"}}}}, eidPermissions: []openrtb_ext.ExtRequestPrebidDataEidPermission{ {Source: "source1", Bidders: []string{"bidderA"}}, }, - expectedUserExt: json.RawMessage(`{"eids":[{"source":"source1","uids":[{"id":"anyID"}]}]}`), + expectedUserEids: []openrtb2.EID{{Source: "source1", UIDs: []openrtb2.UID{{ID: "anyID"}}}}, }, { description: "Allowed By Specific Bidder - Case Insensitive", - userExt: json.RawMessage(`{"eids":[{"source":"source1","uids":[{"id":"anyID"}]}]}`), + userEids: []openrtb2.EID{{Source: "source1", UIDs: []openrtb2.UID{{ID: "anyID"}}}}, eidPermissions: []openrtb_ext.ExtRequestPrebidDataEidPermission{ {Source: "source1", Bidders: []string{"BIDDERA"}}, }, - expectedUserExt: json.RawMessage(`{"eids":[{"source":"source1","uids":[{"id":"anyID"}]}]}`), + expectedUserEids: []openrtb2.EID{{Source: "source1", UIDs: []openrtb2.UID{{ID: "anyID"}}}}, }, { description: "Allowed By All Bidders", - userExt: json.RawMessage(`{"eids":[{"source":"source1","uids":[{"id":"anyID"}]}]}`), + userEids: []openrtb2.EID{{Source: "source1", UIDs: []openrtb2.UID{{ID: "anyID"}}}}, eidPermissions: []openrtb_ext.ExtRequestPrebidDataEidPermission{ {Source: "source1", Bidders: []string{"*"}}, }, - expectedUserExt: json.RawMessage(`{"eids":[{"source":"source1","uids":[{"id":"anyID"}]}]}`), + expectedUserEids: []openrtb2.EID{{Source: "source1", UIDs: []openrtb2.UID{{ID: "anyID"}}}}, }, { description: "Allowed By Lack Of Matching Source", - userExt: json.RawMessage(`{"eids":[{"source":"source1","uids":[{"id":"anyID"}]}]}`), + userEids: []openrtb2.EID{{Source: "source1", UIDs: []openrtb2.UID{{ID: "anyID"}}}}, eidPermissions: []openrtb_ext.ExtRequestPrebidDataEidPermission{ {Source: "source2", Bidders: []string{"otherBidder"}}, }, - expectedUserExt: json.RawMessage(`{"eids":[{"source":"source1","uids":[{"id":"anyID"}]}]}`), - }, - { - description: "Allowed - Keep Other Data", - userExt: json.RawMessage(`{"eids":[{"source":"source1","uids":[{"id":"anyID"}]}],"other":42}`), - eidPermissions: []openrtb_ext.ExtRequestPrebidDataEidPermission{ - {Source: "source1", Bidders: []string{"bidderA"}}, - }, - expectedUserExt: json.RawMessage(`{"eids":[{"source":"source1","uids":[{"id":"anyID"}]}],"other":42}`), + expectedUserEids: []openrtb2.EID{{Source: "source1", UIDs: []openrtb2.UID{{ID: "anyID"}}}}, }, { description: "Denied", - userExt: json.RawMessage(`{"eids":[{"source":"source1","uids":[{"id":"anyID"}]}]}`), + userEids: []openrtb2.EID{{Source: "source1", UIDs: []openrtb2.UID{{ID: "anyID"}}}}, eidPermissions: []openrtb_ext.ExtRequestPrebidDataEidPermission{ {Source: "source1", Bidders: []string{"otherBidder"}}, }, - expectedUserExt: nil, + expectedUserEids: nil, }, { - description: "Denied - Keep Other Data", - userExt: json.RawMessage(`{"eids":[{"source":"source1","uids":[{"id":"anyID"}]}],"otherdata":42}`), - eidPermissions: []openrtb_ext.ExtRequestPrebidDataEidPermission{ - {Source: "source1", Bidders: []string{"otherBidder"}}, + description: "Mix Of Allowed By Specific Bidder, Allowed By Lack Of Matching Source, Denied", + userEids: []openrtb2.EID{ + {Source: "source1", UIDs: []openrtb2.UID{{ID: "anyID1"}}}, + {Source: "source2", UIDs: []openrtb2.UID{{ID: "anyID2"}}}, + {Source: "source3", UIDs: []openrtb2.UID{{ID: "anyID3"}}}, }, - expectedUserExt: json.RawMessage(`{"otherdata":42}`), - }, - { - description: "Mix Of Allowed By Specific Bidder, Allowed By Lack Of Matching Source, Denied, Keep Other Data", - userExt: json.RawMessage(`{"eids":[{"source":"source1","uids":[{"id":"anyID1"}]},{"source":"source2","uids":[{"id":"anyID2"}]},{"source":"source3","uids":[{"id":"anyID3"}]}],"other":42}`), eidPermissions: []openrtb_ext.ExtRequestPrebidDataEidPermission{ {Source: "source1", Bidders: []string{"bidderA"}}, {Source: "source3", Bidders: []string{"otherBidder"}}, }, - expectedUserExt: json.RawMessage(`{"eids":[{"source":"source1","uids":[{"id":"anyID1"}]},{"source":"source2","uids":[{"id":"anyID2"}]}],"other":42}`), + expectedUserEids: []openrtb2.EID{ + {Source: "source1", UIDs: []openrtb2.UID{{ID: "anyID1"}}}, + {Source: "source2", UIDs: []openrtb2.UID{{ID: "anyID2"}}}, + }, }, } for _, test := range testCases { - request := &openrtb2.BidRequest{ - User: &openrtb2.User{Ext: test.userExt}, - } + t.Run(test.description, func(t *testing.T) { + request := &openrtb2.BidRequest{ + User: &openrtb2.User{EIDs: test.userEids}, + } - requestExt := &openrtb_ext.ExtRequest{ - Prebid: openrtb_ext.ExtRequestPrebid{ + reqWrapper := openrtb_ext.RequestWrapper{BidRequest: request} + re, _ := reqWrapper.GetRequestExt() + re.SetPrebid(&openrtb_ext.ExtRequestPrebid{ Data: &openrtb_ext.ExtRequestPrebidData{ EidPermissions: test.eidPermissions, }, - }, - } - - expectedRequest := &openrtb2.BidRequest{ - User: &openrtb2.User{Ext: test.expectedUserExt}, - } - - resultErr := removeUnpermissionedEids(request, bidder, requestExt) - assert.NoError(t, resultErr, test.description) - assert.Equal(t, expectedRequest, request, test.description) - } -} - -func TestRemoveUnpermissionedEidsUnmarshalErrors(t *testing.T) { - testCases := []struct { - description string - userExt json.RawMessage - expectedErr string - }{ - { - description: "Malformed Ext", - userExt: json.RawMessage(`malformed`), - expectedErr: "expect { or n, but found m", - }, - { - description: "Malformed Eid Array Type", - userExt: json.RawMessage(`{"eids":[42]}`), - expectedErr: "cannot unmarshal []openrtb2.EID: expect { or n, but found 4", - }, - { - description: "Malformed Eid Item Type", - userExt: json.RawMessage(`{"eids":[{"source":42,"id":"anyID"}]}`), - expectedErr: "cannot unmarshal openrtb2.EID.Source: expects \" or n, but found 4", - }, - } - - for _, test := range testCases { - request := &openrtb2.BidRequest{ - User: &openrtb2.User{Ext: test.userExt}, - } + }) - requestExt := &openrtb_ext.ExtRequest{ - Prebid: openrtb_ext.ExtRequestPrebid{ - Data: &openrtb_ext.ExtRequestPrebidData{ - EidPermissions: []openrtb_ext.ExtRequestPrebidDataEidPermission{ - {Source: "source1", Bidders: []string{"*"}}, - }, - }, - }, - } + expectedRequest := &openrtb2.BidRequest{ + User: &openrtb2.User{EIDs: test.expectedUserEids}, + } - resultErr := removeUnpermissionedEids(request, "bidderA", requestExt) - assert.EqualError(t, resultErr, test.expectedErr, test.description) + resultErr := removeUnpermissionedEids(&reqWrapper, bidder) + assert.NoError(t, resultErr, test.description) + assert.Equal(t, expectedRequest, reqWrapper.BidRequest) + }) } } @@ -3184,23 +3178,17 @@ func TestGetDebugInfo(t *testing.T) { func TestRemoveUnpermissionedEidsEmptyValidations(t *testing.T) { testCases := []struct { - description string - request *openrtb2.BidRequest - requestExt *openrtb_ext.ExtRequest + description string + request *openrtb2.BidRequest + eidPermissions []openrtb_ext.ExtRequestPrebidDataEidPermission }{ { description: "Nil User", request: &openrtb2.BidRequest{ User: nil, }, - requestExt: &openrtb_ext.ExtRequest{ - Prebid: openrtb_ext.ExtRequestPrebid{ - Data: &openrtb_ext.ExtRequestPrebidData{ - EidPermissions: []openrtb_ext.ExtRequestPrebidDataEidPermission{ - {Source: "source1", Bidders: []string{"*"}}, - }, - }, - }, + eidPermissions: []openrtb_ext.ExtRequestPrebidDataEidPermission{ + {Source: "source1", Bidders: []string{"*"}}, }, }, { @@ -3208,14 +3196,8 @@ func TestRemoveUnpermissionedEidsEmptyValidations(t *testing.T) { request: &openrtb2.BidRequest{ User: &openrtb2.User{}, }, - requestExt: &openrtb_ext.ExtRequest{ - Prebid: openrtb_ext.ExtRequestPrebid{ - Data: &openrtb_ext.ExtRequestPrebidData{ - EidPermissions: []openrtb_ext.ExtRequestPrebidDataEidPermission{ - {Source: "source1", Bidders: []string{"*"}}, - }, - }, - }, + eidPermissions: []openrtb_ext.ExtRequestPrebidDataEidPermission{ + {Source: "source1", Bidders: []string{"*"}}, }, }, { @@ -3223,27 +3205,25 @@ func TestRemoveUnpermissionedEidsEmptyValidations(t *testing.T) { request: &openrtb2.BidRequest{ User: &openrtb2.User{Ext: json.RawMessage(`{"eids":[{"source":"source1","id":"anyID"}]}`)}, }, - requestExt: nil, - }, - { - description: "Nil Prebid Data", - request: &openrtb2.BidRequest{ - User: &openrtb2.User{Ext: json.RawMessage(`{"eids":[{"source":"source1","id":"anyID"}]}`)}, - }, - requestExt: &openrtb_ext.ExtRequest{ - Prebid: openrtb_ext.ExtRequestPrebid{ - Data: nil, - }, - }, }, } for _, test := range testCases { - requestExpected := *test.request + t.Run(test.description, func(t *testing.T) { + requestExpected := *test.request + reqWrapper := openrtb_ext.RequestWrapper{BidRequest: test.request} + + re, _ := reqWrapper.GetRequestExt() + re.SetPrebid(&openrtb_ext.ExtRequestPrebid{ + Data: &openrtb_ext.ExtRequestPrebidData{ + EidPermissions: test.eidPermissions, + }, + }) - resultErr := removeUnpermissionedEids(test.request, "bidderA", test.requestExt) - assert.NoError(t, resultErr, test.description+":err") - assert.Equal(t, &requestExpected, test.request, test.description+":request") + resultErr := removeUnpermissionedEids(&reqWrapper, "bidderA") + assert.NoError(t, resultErr, test.description+":err") + assert.Equal(t, &requestExpected, reqWrapper.BidRequest, test.description+":request") + }) } } @@ -3278,28 +3258,57 @@ func TestCleanOpenRTBRequestsSChainMultipleBidders(t *testing.T) { }, }.Builder + ortb26enabled := config.BidderInfo{OpenRTB: &config.OpenRTBInfo{Version: "2.6"}} reqSplitter := &requestSplitter{ bidderToSyncerKey: map[string]string{}, me: &metrics.MetricsEngineMock{}, privacyConfig: config.Privacy{}, gdprPermsBuilder: gdprPermissionsBuilder, hostSChainNode: nil, - bidderInfo: config.BidderInfos{}, + bidderInfo: config.BidderInfos{"appnexus": ortb26enabled, "axonix": ortb26enabled}, } bidderRequests, _, errs := reqSplitter.cleanOpenRTBRequests(context.Background(), auctionReq, extRequest, gdpr.SignalNo, false, map[string]float64{}) assert.Nil(t, errs) assert.Len(t, bidderRequests, 2, "Bid request count is not 2") - bidRequestSourceExts := map[openrtb_ext.BidderName]json.RawMessage{} + bidRequestSourceSupplyChain := map[openrtb_ext.BidderName]*openrtb2.SupplyChain{} for _, bidderRequest := range bidderRequests { - bidRequestSourceExts[bidderRequest.BidderName] = bidderRequest.BidRequest.Source.Ext + bidRequestSourceSupplyChain[bidderRequest.BidderName] = bidderRequest.BidRequest.Source.SChain + } + + appnexusSchainsSchainExpected := &openrtb2.SupplyChain{ + Complete: 1, + Ver: "1.0", + Ext: nil, + Nodes: []openrtb2.SupplyChainNode{ + { + ASI: "directseller1.com", + SID: "00001", + RID: "BidRequest1", + HP: openrtb2.Int8Ptr(1), + Ext: nil, + }, + }, } - appnexusPrebidSchainsSchain := json.RawMessage(`{"schain":{"complete":1,"nodes":[{"asi":"directseller1.com","sid":"00001","rid":"BidRequest1","hp":1}],"ver":"1.0"}}`) - axonixPrebidSchainsSchain := json.RawMessage(`{"schain":{"complete":1,"nodes":[{"asi":"directseller2.com","sid":"00002","rid":"BidRequest2","hp":1}],"ver":"1.0"}}`) - assert.Equal(t, appnexusPrebidSchainsSchain, bidRequestSourceExts["appnexus"], "Incorrect appnexus bid request schain in source.ext") - assert.Equal(t, axonixPrebidSchainsSchain, bidRequestSourceExts["axonix"], "Incorrect axonix bid request schain in source.ext") + axonixSchainsSchainExpected := &openrtb2.SupplyChain{ + Complete: 1, + Ver: "1.0", + Ext: nil, + Nodes: []openrtb2.SupplyChainNode{ + { + ASI: "directseller2.com", + SID: "00002", + RID: "BidRequest2", + HP: openrtb2.Int8Ptr(1), + Ext: nil, + }, + }, + } + + assert.Equal(t, appnexusSchainsSchainExpected, bidRequestSourceSupplyChain["appnexus"], "Incorrect appnexus bid request schain ") + assert.Equal(t, axonixSchainsSchainExpected, bidRequestSourceSupplyChain["axonix"], "Incorrect axonix bid request schain") } func TestCleanOpenRTBRequestsBidAdjustment(t *testing.T) { @@ -3423,6 +3432,7 @@ func TestApplyFPD(t *testing.T) { inputBidderIsRequestAlias bool inputRequest openrtb2.BidRequest expectedRequest openrtb2.BidRequest + fpdUserEIDsExisted bool }{ { description: "fpd-nil", @@ -3544,17 +3554,45 @@ func TestApplyFPD(t *testing.T) { inputRequest: openrtb2.BidRequest{}, expectedRequest: openrtb2.BidRequest{Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "AppId"}, User: &openrtb2.User{ID: "UserId", BuyerUID: "FPDBuyerUID"}}, }, + { + description: "req.User is defined and had bidder fpd user eids (fpdUserEIDsExisted); bidderFPD.User defined and has EIDs. Expect to see user.EIDs in result request taken from fpd", + inputFpd: map[openrtb_ext.BidderName]*firstpartydata.ResolvedFirstPartyData{ + "bidderNormalized": {Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "AppId"}, User: &openrtb2.User{ID: "UserId", EIDs: []openrtb2.EID{{Source: "source1"}, {Source: "source2"}}}}, + }, + inputBidderName: "bidderFromRequest", + inputBidderCoreName: "bidderNormalized", + inputBidderIsRequestAlias: false, + inputRequest: openrtb2.BidRequest{User: &openrtb2.User{ID: "UserId", EIDs: []openrtb2.EID{{Source: "source3"}, {Source: "source4"}}}}, + expectedRequest: openrtb2.BidRequest{Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "AppId"}, User: &openrtb2.User{ID: "UserId", EIDs: []openrtb2.EID{{Source: "source1"}, {Source: "source2"}}}}, + fpdUserEIDsExisted: true, + }, + { + description: "req.User is defined and doesn't have fpr user eids (fpdUserEIDsExisted); bidderFPD.User defined and has EIDs. Expect to see user.EIDs in result request taken from original req", + inputFpd: map[openrtb_ext.BidderName]*firstpartydata.ResolvedFirstPartyData{ + "bidderNormalized": {Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "AppId"}, User: &openrtb2.User{ID: "UserId", EIDs: []openrtb2.EID{{Source: "source1"}, {Source: "source2"}}}}, + }, + inputBidderName: "bidderFromRequest", + inputBidderCoreName: "bidderNormalized", + inputBidderIsRequestAlias: false, + inputRequest: openrtb2.BidRequest{User: &openrtb2.User{ID: "UserId", EIDs: []openrtb2.EID{{Source: "source3"}, {Source: "source4"}}}}, + expectedRequest: openrtb2.BidRequest{Site: &openrtb2.Site{ID: "SiteId"}, App: &openrtb2.App{ID: "AppId"}, User: &openrtb2.User{ID: "UserId", EIDs: []openrtb2.EID{{Source: "source3"}, {Source: "source4"}}}}, + fpdUserEIDsExisted: false, + }, } for _, testCase := range testCases { - bidderRequest := BidderRequest{ - BidderName: openrtb_ext.BidderName(testCase.inputBidderName), - BidderCoreName: openrtb_ext.BidderName(testCase.inputBidderCoreName), - IsRequestAlias: testCase.inputBidderIsRequestAlias, - BidRequest: &testCase.inputRequest, - } - applyFPD(testCase.inputFpd, bidderRequest) - assert.Equal(t, testCase.expectedRequest, testCase.inputRequest, fmt.Sprintf("incorrect request after applying fpd, testcase %s", testCase.description)) + t.Run(testCase.description, func(t *testing.T) { + reqWrapper := &openrtb_ext.RequestWrapper{BidRequest: &testCase.inputRequest} + applyFPD( + testCase.inputFpd, + openrtb_ext.BidderName(testCase.inputBidderCoreName), + openrtb_ext.BidderName(testCase.inputBidderName), + testCase.inputBidderIsRequestAlias, + reqWrapper, + testCase.fpdUserEIDsExisted, + ) + assert.Equal(t, &testCase.expectedRequest, reqWrapper.BidRequest) + }) } } @@ -3881,21 +3919,27 @@ func (gs GPPMockSection) Encode(bool) []byte { func TestGdprFromGPP(t *testing.T) { testCases := []struct { name string - initialRequest *openrtb2.BidRequest + initialRequest *openrtb_ext.RequestWrapper gpp gpplib.GppContainer - expectedRequest *openrtb2.BidRequest + expectedRequest *openrtb_ext.RequestWrapper }{ { - name: "Empty", // Empty Request - initialRequest: &openrtb2.BidRequest{}, - gpp: gpplib.GppContainer{}, - expectedRequest: &openrtb2.BidRequest{}, + name: "Empty", // Empty Request + initialRequest: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{}, + }, + gpp: gpplib.GppContainer{}, + expectedRequest: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{}, + }, }, { name: "GDPR_Downgrade", // GDPR from GPP, into empty - initialRequest: &openrtb2.BidRequest{ - Regs: &openrtb2.Regs{ - GPPSID: []int8{2}, + initialRequest: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Regs: &openrtb2.Regs{ + GPPSID: []int8{2}, + }, }, }, gpp: gpplib.GppContainer{ @@ -3907,25 +3951,29 @@ func TestGdprFromGPP(t *testing.T) { }, }, }, - expectedRequest: &openrtb2.BidRequest{ - Regs: &openrtb2.Regs{ - GPPSID: []int8{2}, - GDPR: ptrutil.ToPtr[int8](1), - }, - User: &openrtb2.User{ - Consent: "GDPRConsent", + expectedRequest: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Regs: &openrtb2.Regs{ + GPPSID: []int8{2}, + GDPR: ptrutil.ToPtr[int8](1), + }, + User: &openrtb2.User{ + Consent: "GDPRConsent", + }, }, }, }, { name: "GDPR_Downgrade", // GDPR from GPP, into empty legacy, existing objects - initialRequest: &openrtb2.BidRequest{ - Regs: &openrtb2.Regs{ - GPPSID: []int8{2}, - USPrivacy: "LegacyUSP", - }, - User: &openrtb2.User{ - ID: "1234", + initialRequest: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Regs: &openrtb2.Regs{ + GPPSID: []int8{2}, + USPrivacy: "LegacyUSP", + }, + User: &openrtb2.User{ + ID: "1234", + }, }, }, gpp: gpplib.GppContainer{ @@ -3937,27 +3985,31 @@ func TestGdprFromGPP(t *testing.T) { }, }, }, - expectedRequest: &openrtb2.BidRequest{ - Regs: &openrtb2.Regs{ - GPPSID: []int8{2}, - GDPR: ptrutil.ToPtr[int8](1), - USPrivacy: "LegacyUSP", - }, - User: &openrtb2.User{ - ID: "1234", - Consent: "GDPRConsent", + expectedRequest: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Regs: &openrtb2.Regs{ + GPPSID: []int8{2}, + GDPR: ptrutil.ToPtr[int8](1), + USPrivacy: "LegacyUSP", + }, + User: &openrtb2.User{ + ID: "1234", + Consent: "GDPRConsent", + }, }, }, }, { name: "Downgrade_Blocked_By_Existing", // GDPR from GPP blocked by existing GDPR", - initialRequest: &openrtb2.BidRequest{ - Regs: &openrtb2.Regs{ - GPPSID: []int8{2}, - GDPR: ptrutil.ToPtr[int8](1), - }, - User: &openrtb2.User{ - Consent: "LegacyConsent", + initialRequest: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Regs: &openrtb2.Regs{ + GPPSID: []int8{2}, + GDPR: ptrutil.ToPtr[int8](1), + }, + User: &openrtb2.User{ + Consent: "LegacyConsent", + }, }, }, gpp: gpplib.GppContainer{ @@ -3969,22 +4021,26 @@ func TestGdprFromGPP(t *testing.T) { }, }, }, - expectedRequest: &openrtb2.BidRequest{ - Regs: &openrtb2.Regs{ - GPPSID: []int8{2}, - GDPR: ptrutil.ToPtr[int8](1), - }, - User: &openrtb2.User{ - Consent: "LegacyConsent", + expectedRequest: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Regs: &openrtb2.Regs{ + GPPSID: []int8{2}, + GDPR: ptrutil.ToPtr[int8](1), + }, + User: &openrtb2.User{ + Consent: "LegacyConsent", + }, }, }, }, { name: "Downgrade_Partial", // GDPR from GPP partially blocked by existing GDPR - initialRequest: &openrtb2.BidRequest{ - Regs: &openrtb2.Regs{ - GPPSID: []int8{2}, - GDPR: ptrutil.ToPtr[int8](0), + initialRequest: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Regs: &openrtb2.Regs{ + GPPSID: []int8{2}, + GDPR: ptrutil.ToPtr[int8](0), + }, }, }, gpp: gpplib.GppContainer{ @@ -3996,21 +4052,25 @@ func TestGdprFromGPP(t *testing.T) { }, }, }, - expectedRequest: &openrtb2.BidRequest{ - Regs: &openrtb2.Regs{ - GPPSID: []int8{2}, - GDPR: ptrutil.ToPtr[int8](0), - }, - User: &openrtb2.User{ - Consent: "GDPRConsent", + expectedRequest: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Regs: &openrtb2.Regs{ + GPPSID: []int8{2}, + GDPR: ptrutil.ToPtr[int8](0), + }, + User: &openrtb2.User{ + Consent: "GDPRConsent", + }, }, }, }, { name: "No_GDPR", // Downgrade not possible due to missing GDPR - initialRequest: &openrtb2.BidRequest{ - Regs: &openrtb2.Regs{ - GPPSID: []int8{6}, + initialRequest: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Regs: &openrtb2.Regs{ + GPPSID: []int8{6}, + }, }, }, gpp: gpplib.GppContainer{ @@ -4022,18 +4082,22 @@ func TestGdprFromGPP(t *testing.T) { }, }, }, - expectedRequest: &openrtb2.BidRequest{ - Regs: &openrtb2.Regs{ - GPPSID: []int8{6}, - GDPR: ptrutil.ToPtr[int8](0), + expectedRequest: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Regs: &openrtb2.Regs{ + GPPSID: []int8{6}, + GDPR: ptrutil.ToPtr[int8](0), + }, }, }, }, { name: "No_SID", // GDPR from GPP partially blocked by no SID - initialRequest: &openrtb2.BidRequest{ - Regs: &openrtb2.Regs{ - GPPSID: []int8{6}, + initialRequest: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Regs: &openrtb2.Regs{ + GPPSID: []int8{6}, + }, }, }, gpp: gpplib.GppContainer{ @@ -4049,19 +4113,23 @@ func TestGdprFromGPP(t *testing.T) { }, }, }, - expectedRequest: &openrtb2.BidRequest{ - Regs: &openrtb2.Regs{ - GPPSID: []int8{6}, - GDPR: ptrutil.ToPtr[int8](0), - }, - User: &openrtb2.User{ - Consent: "GDPRConsent", + expectedRequest: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Regs: &openrtb2.Regs{ + GPPSID: []int8{6}, + GDPR: ptrutil.ToPtr[int8](0), + }, + User: &openrtb2.User{ + Consent: "GDPRConsent", + }, }, }, }, { - name: "GDPR_Nil_SID", // GDPR from GPP, into empty, but with nil SID - initialRequest: &openrtb2.BidRequest{}, + name: "GDPR_Nil_SID", // GDPR from GPP, into empty, but with nil SID + initialRequest: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{}, + }, gpp: gpplib.GppContainer{ SectionTypes: []constants.SectionID{2}, Sections: []gpplib.Section{ @@ -4071,20 +4139,24 @@ func TestGdprFromGPP(t *testing.T) { }, }, }, - expectedRequest: &openrtb2.BidRequest{ - User: &openrtb2.User{ - Consent: "GDPRConsent", + expectedRequest: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + User: &openrtb2.User{ + Consent: "GDPRConsent", + }, }, }, }, { name: "Downgrade_Nil_SID_Blocked_By_Existing", // GDPR from GPP blocked by existing GDPR, with nil SID", - initialRequest: &openrtb2.BidRequest{ - Regs: &openrtb2.Regs{ - GDPR: ptrutil.ToPtr[int8](1), - }, - User: &openrtb2.User{ - Consent: "LegacyConsent", + initialRequest: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Regs: &openrtb2.Regs{ + GDPR: ptrutil.ToPtr[int8](1), + }, + User: &openrtb2.User{ + Consent: "LegacyConsent", + }, }, }, gpp: gpplib.GppContainer{ @@ -4096,12 +4168,14 @@ func TestGdprFromGPP(t *testing.T) { }, }, }, - expectedRequest: &openrtb2.BidRequest{ - Regs: &openrtb2.Regs{ - GDPR: ptrutil.ToPtr[int8](1), - }, - User: &openrtb2.User{ - Consent: "LegacyConsent", + expectedRequest: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Regs: &openrtb2.Regs{ + GDPR: ptrutil.ToPtr[int8](1), + }, + User: &openrtb2.User{ + Consent: "LegacyConsent", + }, }, }, }, @@ -4118,21 +4192,27 @@ func TestGdprFromGPP(t *testing.T) { func TestPrivacyFromGPP(t *testing.T) { testCases := []struct { name string - initialRequest *openrtb2.BidRequest + initialRequest *openrtb_ext.RequestWrapper gpp gpplib.GppContainer - expectedRequest *openrtb2.BidRequest + expectedRequest *openrtb_ext.RequestWrapper }{ { - name: "Empty", // Empty Request - initialRequest: &openrtb2.BidRequest{}, - gpp: gpplib.GppContainer{}, - expectedRequest: &openrtb2.BidRequest{}, + name: "Empty", // Empty Request + initialRequest: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{}, + }, + gpp: gpplib.GppContainer{}, + expectedRequest: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{}, + }, }, { name: "Privacy_Downgrade", // US Privacy from GPP, into empty - initialRequest: &openrtb2.BidRequest{ - Regs: &openrtb2.Regs{ - GPPSID: []int8{6}, + initialRequest: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Regs: &openrtb2.Regs{ + GPPSID: []int8{6}, + }, }, }, gpp: gpplib.GppContainer{ @@ -4144,19 +4224,23 @@ func TestPrivacyFromGPP(t *testing.T) { }, }, }, - expectedRequest: &openrtb2.BidRequest{ - Regs: &openrtb2.Regs{ - GPPSID: []int8{6}, - USPrivacy: "USPrivacy", + expectedRequest: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Regs: &openrtb2.Regs{ + GPPSID: []int8{6}, + USPrivacy: "USPrivacy", + }, }, }, }, { name: "Downgrade_Blocked_By_Existing", // US Privacy from GPP blocked by existing US Privacy - initialRequest: &openrtb2.BidRequest{ - Regs: &openrtb2.Regs{ - GPPSID: []int8{6}, - USPrivacy: "LegacyPrivacy", + initialRequest: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Regs: &openrtb2.Regs{ + GPPSID: []int8{6}, + USPrivacy: "LegacyPrivacy", + }, }, }, gpp: gpplib.GppContainer{ @@ -4168,18 +4252,22 @@ func TestPrivacyFromGPP(t *testing.T) { }, }, }, - expectedRequest: &openrtb2.BidRequest{ - Regs: &openrtb2.Regs{ - GPPSID: []int8{6}, - USPrivacy: "LegacyPrivacy", + expectedRequest: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Regs: &openrtb2.Regs{ + GPPSID: []int8{6}, + USPrivacy: "LegacyPrivacy", + }, }, }, }, { name: "No_USPrivacy", // Downgrade not possible due to missing USPrivacy - initialRequest: &openrtb2.BidRequest{ - Regs: &openrtb2.Regs{ - GPPSID: []int8{2}, + initialRequest: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Regs: &openrtb2.Regs{ + GPPSID: []int8{2}, + }, }, }, gpp: gpplib.GppContainer{ @@ -4191,17 +4279,21 @@ func TestPrivacyFromGPP(t *testing.T) { }, }, }, - expectedRequest: &openrtb2.BidRequest{ - Regs: &openrtb2.Regs{ - GPPSID: []int8{2}, + expectedRequest: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Regs: &openrtb2.Regs{ + GPPSID: []int8{2}, + }, }, }, }, { name: "No_SID", // US Privacy from GPP partially blocked by no SID - initialRequest: &openrtb2.BidRequest{ - Regs: &openrtb2.Regs{ - GPPSID: []int8{2}, + initialRequest: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Regs: &openrtb2.Regs{ + GPPSID: []int8{2}, + }, }, }, gpp: gpplib.GppContainer{ @@ -4217,9 +4309,11 @@ func TestPrivacyFromGPP(t *testing.T) { }, }, }, - expectedRequest: &openrtb2.BidRequest{ - Regs: &openrtb2.Regs{ - GPPSID: []int8{2}, + expectedRequest: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Regs: &openrtb2.Regs{ + GPPSID: []int8{2}, + }, }, }, }, @@ -4709,6 +4803,7 @@ func TestCleanOpenRTBRequestsActivities(t *testing.T) { privacyConfig config.AccountPrivacy componentName string allow bool + ortbVersion string expectedReqNumber int expectedUser openrtb2.User expectUserScrub bool @@ -4720,6 +4815,7 @@ func TestCleanOpenRTBRequestsActivities(t *testing.T) { name: "fetch_bids_request_with_one_bidder_allowed", req: newBidRequest(t), privacyConfig: getFetchBidsActivityConfig("appnexus", true), + ortbVersion: "2.6", expectedReqNumber: 1, expectedUser: expectedUserDefault, expectedDevice: expectedDeviceDefault, @@ -4738,6 +4834,7 @@ func TestCleanOpenRTBRequestsActivities(t *testing.T) { name: "transmit_ufpd_allowed", req: newBidRequest(t), privacyConfig: getTransmitUFPDActivityConfig("appnexus", true), + ortbVersion: "2.6", expectedReqNumber: 1, expectedUser: expectedUserDefault, expectedDevice: expectedDeviceDefault, @@ -4779,6 +4876,7 @@ func TestCleanOpenRTBRequestsActivities(t *testing.T) { name: "transmit_precise_geo_allowed", req: newBidRequest(t), privacyConfig: getTransmitPreciseGeoActivityConfig("appnexus", true), + ortbVersion: "2.6", expectedReqNumber: 1, expectedUser: expectedUserDefault, expectedDevice: expectedDeviceDefault, @@ -4790,6 +4888,7 @@ func TestCleanOpenRTBRequestsActivities(t *testing.T) { name: "transmit_precise_geo_deny", req: newBidRequest(t), privacyConfig: getTransmitPreciseGeoActivityConfig("appnexus", false), + ortbVersion: "2.6", expectedReqNumber: 1, expectedUser: openrtb2.User{ ID: "our-id", @@ -4822,6 +4921,7 @@ func TestCleanOpenRTBRequestsActivities(t *testing.T) { name: "transmit_tid_allowed", req: newBidRequest(t), privacyConfig: getTransmitTIDActivityConfig("appnexus", true), + ortbVersion: "2.6", expectedReqNumber: 1, expectedUser: expectedUserDefault, expectedDevice: expectedDeviceDefault, @@ -4832,6 +4932,7 @@ func TestCleanOpenRTBRequestsActivities(t *testing.T) { name: "transmit_tid_deny", req: newBidRequest(t), privacyConfig: getTransmitTIDActivityConfig("appnexus", false), + ortbVersion: "2.6", expectedReqNumber: 1, expectedUser: expectedUserDefault, expectedDevice: expectedDeviceDefault, @@ -4868,7 +4969,7 @@ func TestCleanOpenRTBRequestsActivities(t *testing.T) { bidderToSyncerKey: bidderToSyncerKey, me: &metricsMock, hostSChainNode: nil, - bidderInfo: config.BidderInfos{}, + bidderInfo: config.BidderInfos{"appnexus": config.BidderInfo{OpenRTB: &config.OpenRTBInfo{Version: test.ortbVersion}}}, } bidderRequests, _, errs := reqSplitter.cleanOpenRTBRequests(context.Background(), auctionReq, nil, gdpr.SignalNo, false, map[string]float64{}) @@ -4942,119 +5043,96 @@ func getTransmitTIDActivityConfig(componentName string, allow bool) config.Accou func TestApplyBidAdjustmentToFloor(t *testing.T) { type args struct { - allBidderRequests []BidderRequest + bidRequestWrapper *openrtb_ext.RequestWrapper + bidderName string bidAdjustmentFactors map[string]float64 } tests := []struct { - name string - args args - expectedAllBidderRequests []BidderRequest + name string + args args + expectedBidRequest *openrtb2.BidRequest }{ { - name: " bidAdjustmentFactor is empty", + name: "bid_adjustment_factor_is_nil", args: args{ - allBidderRequests: []BidderRequest{ - { - BidRequest: &openrtb2.BidRequest{ - Imp: []openrtb2.Imp{{BidFloor: 100}, {BidFloor: 150}}, - }, - BidderName: openrtb_ext.BidderName("appnexus"), - }, - }, - bidAdjustmentFactors: map[string]float64{}, - }, - expectedAllBidderRequests: []BidderRequest{ - { + bidRequestWrapper: &openrtb_ext.RequestWrapper{ BidRequest: &openrtb2.BidRequest{ Imp: []openrtb2.Imp{{BidFloor: 100}, {BidFloor: 150}}, }, - BidderName: openrtb_ext.BidderName("appnexus"), }, + bidderName: "appnexus", + bidAdjustmentFactors: nil, + }, + expectedBidRequest: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{BidFloor: 100}, {BidFloor: 150}}, }, }, { - name: "bidAdjustmentFactor not present for request bidder", + name: "bid_adjustment_factor_is_empty", args: args{ - allBidderRequests: []BidderRequest{ - { - BidRequest: &openrtb2.BidRequest{ - Imp: []openrtb2.Imp{{BidFloor: 100}, {BidFloor: 150}}, - }, - BidderName: openrtb_ext.BidderName("appnexus"), + bidRequestWrapper: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{BidFloor: 100}, {BidFloor: 150}}, }, }, - bidAdjustmentFactors: map[string]float64{"pubmatic": 1.0}, + bidderName: "appnexus", + bidAdjustmentFactors: map[string]float64{}, }, - expectedAllBidderRequests: []BidderRequest{ - { + expectedBidRequest: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{BidFloor: 100}, {BidFloor: 150}}, + }, + }, + { + name: "bid_adjustment_factor_not_present", + args: args{ + bidRequestWrapper: &openrtb_ext.RequestWrapper{ BidRequest: &openrtb2.BidRequest{ Imp: []openrtb2.Imp{{BidFloor: 100}, {BidFloor: 150}}, }, - BidderName: openrtb_ext.BidderName("appnexus"), }, + bidderName: "appnexus", + bidAdjustmentFactors: map[string]float64{"pubmatic": 1.0}, + }, + expectedBidRequest: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{BidFloor: 100}, {BidFloor: 150}}, }, }, { - name: "bidAdjustmentFactor present for request bidder", + name: "bid_adjustment_factor_present", args: args{ - allBidderRequests: []BidderRequest{ - { - BidRequest: &openrtb2.BidRequest{ - Imp: []openrtb2.Imp{{BidFloor: 100}, {BidFloor: 150}}, - }, - BidderName: openrtb_ext.BidderName("appnexus"), + bidRequestWrapper: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{BidFloor: 100}, {BidFloor: 150}}, }, }, + bidderName: "appnexus", bidAdjustmentFactors: map[string]float64{"pubmatic": 1.0, "appnexus": 0.75}, }, - expectedAllBidderRequests: []BidderRequest{ - { - BidRequest: &openrtb2.BidRequest{ - Imp: []openrtb2.Imp{{BidFloor: 133.33333333333334}, {BidFloor: 200}}, - }, - BidderName: openrtb_ext.BidderName("appnexus"), - }, + expectedBidRequest: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{BidFloor: 133.33333333333334}, {BidFloor: 200}}, }, }, { - name: "bidAdjustmentFactor present only for appnexus request bidder", + name: "bid_adjustment_factor_present_and_zero", args: args{ - allBidderRequests: []BidderRequest{ - { - BidRequest: &openrtb2.BidRequest{ - Imp: []openrtb2.Imp{{BidFloor: 100}, {BidFloor: 150}}, - }, - BidderName: openrtb_ext.BidderName("appnexus"), - }, - { - BidRequest: &openrtb2.BidRequest{ - Imp: []openrtb2.Imp{{BidFloor: 100}, {BidFloor: 150}}, - }, - BidderName: openrtb_ext.BidderName("pubmatic"), - }, - }, - bidAdjustmentFactors: map[string]float64{"appnexus": 0.75}, - }, - expectedAllBidderRequests: []BidderRequest{ - { - BidRequest: &openrtb2.BidRequest{ - Imp: []openrtb2.Imp{{BidFloor: 133.33333333333334}, {BidFloor: 200}}, - }, - BidderName: openrtb_ext.BidderName("appnexus"), - }, - { + bidRequestWrapper: &openrtb_ext.RequestWrapper{ BidRequest: &openrtb2.BidRequest{ Imp: []openrtb2.Imp{{BidFloor: 100}, {BidFloor: 150}}, }, - BidderName: openrtb_ext.BidderName("pubmatic"), }, + bidderName: "appnexus", + bidAdjustmentFactors: map[string]float64{"pubmatic": 1.0, "appnexus": 0.0}, + }, + expectedBidRequest: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{{BidFloor: 100}, {BidFloor: 150}}, }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - applyBidAdjustmentToFloor(tt.args.allBidderRequests, tt.args.bidAdjustmentFactors) - assert.Equal(t, tt.expectedAllBidderRequests, tt.args.allBidderRequests, tt.name) + applyBidAdjustmentToFloor(tt.args.bidRequestWrapper, tt.args.bidderName, tt.args.bidAdjustmentFactors) + assert.NoError(t, tt.args.bidRequestWrapper.RebuildRequest()) + assert.Equal(t, tt.expectedBidRequest, tt.args.bidRequestWrapper.BidRequest, tt.name) }) } } @@ -5277,24 +5355,85 @@ func TestCopyExtAlternateBidderCodes(t *testing.T) { } } -func TestBuildBidResponseRequestBidderName(t *testing.T) { - bidderImpResponses := stored_responses.BidderImpsWithBidResponses{ - openrtb_ext.BidderName("appnexus"): {"impId1": json.RawMessage(`{}`), "impId2": json.RawMessage(`{}`)}, - openrtb_ext.BidderName("appneXUS"): {"impId3": json.RawMessage(`{}`), "impId4": json.RawMessage(`{}`)}, - } +func TestRemoveImpsWithStoredResponses(t *testing.T) { + bidRespId1 := json.RawMessage(`{"id": "resp_id1"}`) + testCases := []struct { + description string + req *openrtb_ext.RequestWrapper + storedBidResponses map[string]json.RawMessage + expectedImps []openrtb2.Imp + }{ + { + description: "request with imps and stored bid response for this imp", + req: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + {ID: "imp-id1"}, + }, + }, + }, + storedBidResponses: map[string]json.RawMessage{ + "imp-id1": bidRespId1, + }, + expectedImps: nil, + }, + { + description: "request with imps and stored bid response for one of these imp", + req: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + {ID: "imp-id1"}, + {ID: "imp-id2"}, + }, + }, + }, + storedBidResponses: map[string]json.RawMessage{ + "imp-id1": bidRespId1, + }, + expectedImps: []openrtb2.Imp{ + { + ID: "imp-id2", + }, + }, + }, + { + description: "request with imps and stored bid response for both of these imp", + req: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + {ID: "imp-id1"}, + {ID: "imp-id2"}, + }, + }, + }, + storedBidResponses: map[string]json.RawMessage{ + "imp-id1": bidRespId1, + "imp-id2": bidRespId1, + }, + expectedImps: nil, + }, + { + description: "request with imps and no stored bid responses", + req: &openrtb_ext.RequestWrapper{ + BidRequest: &openrtb2.BidRequest{ + Imp: []openrtb2.Imp{ + {ID: "imp-id1"}, + {ID: "imp-id2"}, + }, + }, + }, + storedBidResponses: nil, - bidderImpReplaceImpID := stored_responses.BidderImpReplaceImpID{ - "appnexus": {"impId1": true, "impId2": false}, - "appneXUS": {"impId3": true, "impId4": false}, + expectedImps: []openrtb2.Imp{ + {ID: "imp-id1"}, + {ID: "imp-id2"}, + }, + }, + } + for _, testCase := range testCases { + request := testCase.req + removeImpsWithStoredResponses(request, testCase.storedBidResponses) + assert.NoError(t, request.RebuildRequest()) + assert.Equal(t, testCase.expectedImps, request.Imp, "incorrect Impressions for testCase %s", testCase.description) } - result := buildBidResponseRequest(nil, bidderImpResponses, nil, bidderImpReplaceImpID) - - resultAppnexus := result["appnexus"] - assert.Equal(t, resultAppnexus.BidderName, openrtb_ext.BidderName("appnexus")) - assert.Equal(t, resultAppnexus.ImpReplaceImpId, map[string]bool{"impId1": true, "impId2": false}) - - resultAppneXUS := result["appneXUS"] - assert.Equal(t, resultAppneXUS.BidderName, openrtb_ext.BidderName("appneXUS")) - assert.Equal(t, resultAppneXUS.ImpReplaceImpId, map[string]bool{"impId3": true, "impId4": false}) - } diff --git a/experiment/adscert/inprocesssigner.go b/experiment/adscert/inprocesssigner.go index eabd35ebb95..ee5f4905d2a 100644 --- a/experiment/adscert/inprocesssigner.go +++ b/experiment/adscert/inprocesssigner.go @@ -8,7 +8,7 @@ import ( "github.com/IABTechLab/adscert/pkg/adscert/discovery" "github.com/IABTechLab/adscert/pkg/adscert/signatory" "github.com/benbjohnson/clock" - "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v3/config" ) // inProcessSigner holds the signatory to add adsCert header to requests using in process go library diff --git a/experiment/adscert/remotesigner.go b/experiment/adscert/remotesigner.go index d23dad201d3..c441bbebb63 100644 --- a/experiment/adscert/remotesigner.go +++ b/experiment/adscert/remotesigner.go @@ -6,7 +6,7 @@ import ( "github.com/IABTechLab/adscert/pkg/adscert/api" "github.com/IABTechLab/adscert/pkg/adscert/signatory" - "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v3/config" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" ) diff --git a/experiment/adscert/signer.go b/experiment/adscert/signer.go index f060f957149..f7ea9a4254d 100644 --- a/experiment/adscert/signer.go +++ b/experiment/adscert/signer.go @@ -6,7 +6,7 @@ import ( "github.com/IABTechLab/adscert/pkg/adscert/api" "github.com/IABTechLab/adscert/pkg/adscert/logger" "github.com/IABTechLab/adscert/pkg/adscert/signatory" - "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v3/config" ) const SignHeader = "X-Ads-Cert-Auth" diff --git a/experiment/adscert/signer_test.go b/experiment/adscert/signer_test.go index fceb2e5c79c..3e08d0f6ba0 100644 --- a/experiment/adscert/signer_test.go +++ b/experiment/adscert/signer_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/IABTechLab/adscert/pkg/adscert/api" - "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v3/config" "github.com/stretchr/testify/assert" ) diff --git a/firstpartydata/first_party_data.go b/firstpartydata/first_party_data.go index 019730f23ef..44a3241a53c 100644 --- a/firstpartydata/first_party_data.go +++ b/firstpartydata/first_party_data.go @@ -9,10 +9,10 @@ import ( "github.com/prebid/openrtb/v20/openrtb2" jsonpatch "gopkg.in/evanphx/json-patch.v4" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/jsonutil" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/ptrutil" ) var ( diff --git a/firstpartydata/first_party_data_test.go b/firstpartydata/first_party_data_test.go index 44c9405f1bc..3a11e44478b 100644 --- a/firstpartydata/first_party_data_test.go +++ b/firstpartydata/first_party_data_test.go @@ -7,9 +7,9 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/floors/enforce.go b/floors/enforce.go index d499c7d3806..f72d2bb72c5 100644 --- a/floors/enforce.go +++ b/floors/enforce.go @@ -6,10 +6,10 @@ import ( "math/rand" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/currency" - "github.com/prebid/prebid-server/v2/exchange/entities" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/currency" + "github.com/prebid/prebid-server/v3/exchange/entities" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // Enforce does floors enforcement for bids from all bidders based on floors provided in request, account level floors config diff --git a/floors/enforce_test.go b/floors/enforce_test.go index 9b3fd36a717..3da86e2d74a 100644 --- a/floors/enforce_test.go +++ b/floors/enforce_test.go @@ -7,11 +7,11 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/currency" - "github.com/prebid/prebid-server/v2/exchange/entities" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/currency" + "github.com/prebid/prebid-server/v3/exchange/entities" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/floors/fetcher.go b/floors/fetcher.go index 5ed96b9ec36..071ee200353 100644 --- a/floors/fetcher.go +++ b/floors/fetcher.go @@ -15,10 +15,10 @@ import ( validator "github.com/asaskevich/govalidator" "github.com/coocood/freecache" "github.com/golang/glog" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/metrics" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/timeutil" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/metrics" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/timeutil" ) var refetchCheckInterval = 300 diff --git a/floors/fetcher_test.go b/floors/fetcher_test.go index 499c9312302..91ce496f32f 100644 --- a/floors/fetcher_test.go +++ b/floors/fetcher_test.go @@ -12,12 +12,12 @@ import ( "github.com/alitto/pond" "github.com/coocood/freecache" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/metrics" - metricsConf "github.com/prebid/prebid-server/v2/metrics/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/ptrutil" - "github.com/prebid/prebid-server/v2/util/timeutil" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/metrics" + metricsConf "github.com/prebid/prebid-server/v3/metrics/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/ptrutil" + "github.com/prebid/prebid-server/v3/util/timeutil" "github.com/stretchr/testify/assert" ) diff --git a/floors/floors.go b/floors/floors.go index af7422e4c52..9aa70aedbde 100644 --- a/floors/floors.go +++ b/floors/floors.go @@ -6,10 +6,10 @@ import ( "math/rand" "strings" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/currency" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/currency" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/ptrutil" ) type Price struct { diff --git a/floors/floors_test.go b/floors/floors_test.go index b9618bb86f2..438a49f9281 100644 --- a/floors/floors_test.go +++ b/floors/floors_test.go @@ -7,11 +7,11 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/currency" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/jsonutil" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/currency" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/floors/rule.go b/floors/rule.go index ec696dd0f76..65ddf31e727 100644 --- a/floors/rule.go +++ b/floors/rule.go @@ -9,9 +9,9 @@ import ( "github.com/golang/glog" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/currency" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/currency" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/ptrutil" ) const ( diff --git a/floors/rule_test.go b/floors/rule_test.go index b01bab79384..d356a768233 100644 --- a/floors/rule_test.go +++ b/floors/rule_test.go @@ -6,9 +6,9 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/currency" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/currency" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/floors/validate.go b/floors/validate.go index 245bf993e58..140df7def39 100644 --- a/floors/validate.go +++ b/floors/validate.go @@ -4,8 +4,8 @@ import ( "fmt" "strings" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) var validSchemaDimensions = map[string]struct{}{ diff --git a/floors/validate_test.go b/floors/validate_test.go index ccb75c7a659..36c1c73e0b5 100644 --- a/floors/validate_test.go +++ b/floors/validate_test.go @@ -5,8 +5,8 @@ import ( "fmt" "testing" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/gdpr/aggregated_config.go b/gdpr/aggregated_config.go index 9ac03143a1c..3df5fdc7ff8 100644 --- a/gdpr/aggregated_config.go +++ b/gdpr/aggregated_config.go @@ -3,8 +3,8 @@ package gdpr import ( "github.com/prebid/go-gdpr/consentconstants" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // TCF2ConfigReader is an interface to access TCF2 configurations diff --git a/gdpr/aggregated_config_test.go b/gdpr/aggregated_config_test.go index a24e9eff1b1..f577772cb6e 100644 --- a/gdpr/aggregated_config_test.go +++ b/gdpr/aggregated_config_test.go @@ -5,8 +5,8 @@ import ( "github.com/prebid/go-gdpr/consentconstants" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/gdpr/basic_enforcement_test.go b/gdpr/basic_enforcement_test.go index eb22f59bc0b..7bb0076940b 100644 --- a/gdpr/basic_enforcement_test.go +++ b/gdpr/basic_enforcement_test.go @@ -6,7 +6,7 @@ import ( "github.com/prebid/go-gdpr/consentconstants" "github.com/prebid/go-gdpr/vendorconsent" tcf2 "github.com/prebid/go-gdpr/vendorconsent/tcf2" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/gdpr/full_enforcement_test.go b/gdpr/full_enforcement_test.go index 32ba2e50289..eed86bf2383 100644 --- a/gdpr/full_enforcement_test.go +++ b/gdpr/full_enforcement_test.go @@ -8,8 +8,8 @@ import ( tcf2 "github.com/prebid/go-gdpr/vendorconsent/tcf2" "github.com/prebid/go-gdpr/vendorlist" "github.com/prebid/go-gdpr/vendorlist2" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" "github.com/stretchr/testify/assert" ) diff --git a/gdpr/gdpr.go b/gdpr/gdpr.go index 1b4f6cb4680..20c5e9306be 100644 --- a/gdpr/gdpr.go +++ b/gdpr/gdpr.go @@ -3,8 +3,8 @@ package gdpr import ( "context" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) type Permissions interface { @@ -20,8 +20,8 @@ type Permissions interface { // Determines whether or not to send PI information to a bidder, or mask it out. // - // If the consent string was nonsensical, the returned error will be an ErrorMalformedConsent. - AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) (permissions AuctionPermissions, err error) + // If the consent string was nonsensical, the no permissions are granted. + AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) AuctionPermissions } type PermissionsBuilder func(TCF2ConfigReader, RequestInfo) Permissions diff --git a/gdpr/gdpr_test.go b/gdpr/gdpr_test.go index 3729eda3d5b..db81d1396a8 100644 --- a/gdpr/gdpr_test.go +++ b/gdpr/gdpr_test.go @@ -6,8 +6,8 @@ import ( "github.com/prebid/go-gdpr/consentconstants" "github.com/prebid/go-gdpr/vendorlist" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/gdpr/impl.go b/gdpr/impl.go index 614c06d9a6a..47fd4521c1c 100644 --- a/gdpr/impl.go +++ b/gdpr/impl.go @@ -6,7 +6,7 @@ import ( "github.com/prebid/go-gdpr/api" "github.com/prebid/go-gdpr/consentconstants" tcf2 "github.com/prebid/go-gdpr/vendorconsent/tcf2" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) const noBidder openrtb_ext.BidderName = "" @@ -56,33 +56,36 @@ func (p *permissionsImpl) BidderSyncAllowed(ctx context.Context, bidder openrtb_ } // AuctionActivitiesAllowed determines whether auction activities are permitted for a given bidder -func (p *permissionsImpl) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) (permissions AuctionPermissions, err error) { +func (p *permissionsImpl) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) AuctionPermissions { if _, ok := p.nonStandardPublishers[p.publisherID]; ok { - return AllowAll, nil + return AllowAll } + if p.gdprSignal != SignalYes { - return AllowAll, nil + return AllowAll } + if p.consent == "" { - return p.defaultPermissions(), nil + return p.defaultPermissions() } + pc, err := parseConsent(p.consent) if err != nil { - return p.defaultPermissions(), err + return p.defaultPermissions() } + vendorID, _ := p.resolveVendorID(bidderCoreName, bidder) vendor, err := p.getVendor(ctx, vendorID, *pc) if err != nil { - return p.defaultPermissions(), err + return p.defaultPermissions() } - vendorInfo := VendorInfo{vendorID: vendorID, vendor: vendor} - - permissions = AuctionPermissions{} - permissions.AllowBidRequest = p.allowBidRequest(bidderCoreName, pc.consentMeta, vendorInfo) - permissions.PassGeo = p.allowGeo(bidderCoreName, pc.consentMeta, vendor) - permissions.PassID = p.allowID(bidderCoreName, pc.consentMeta, vendorInfo) - return permissions, nil + vendorInfo := VendorInfo{vendorID: vendorID, vendor: vendor} + return AuctionPermissions{ + AllowBidRequest: p.allowBidRequest(bidderCoreName, pc.consentMeta, vendorInfo), + PassGeo: p.allowGeo(bidderCoreName, pc.consentMeta, vendor), + PassID: p.allowID(bidderCoreName, pc.consentMeta, vendorInfo), + } } // defaultPermissions returns a permissions object that denies passing user IDs while @@ -222,6 +225,6 @@ func (a AlwaysAllow) HostCookiesAllowed(ctx context.Context) (bool, error) { func (a AlwaysAllow) BidderSyncAllowed(ctx context.Context, bidder openrtb_ext.BidderName) (bool, error) { return true, nil } -func (a AlwaysAllow) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) (permissions AuctionPermissions, err error) { - return AllowAll, nil +func (a AlwaysAllow) AuctionActivitiesAllowed(ctx context.Context, bidderCoreName openrtb_ext.BidderName, bidder openrtb_ext.BidderName) AuctionPermissions { + return AllowAll } diff --git a/gdpr/impl_test.go b/gdpr/impl_test.go index 64fa4434d4d..79d43d58232 100644 --- a/gdpr/impl_test.go +++ b/gdpr/impl_test.go @@ -9,8 +9,8 @@ import ( "github.com/prebid/go-gdpr/consentconstants" "github.com/prebid/go-gdpr/vendorlist" "github.com/prebid/go-gdpr/vendorlist2" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) @@ -335,9 +335,8 @@ func TestAllowActivities(t *testing.T) { perms.gdprSignal = tt.gdpr perms.publisherID = tt.publisherID - permissions, err := perms.AuctionActivitiesAllowed(context.Background(), tt.bidderCoreName, tt.bidderName) + permissions := perms.AuctionActivitiesAllowed(context.Background(), tt.bidderCoreName, tt.bidderName) - assert.Nil(t, err, tt.description) assert.Equal(t, tt.passID, permissions.PassID, tt.description) } } @@ -437,8 +436,7 @@ func TestAllowActivitiesBidderWithoutGVLID(t *testing.T) { purposeEnforcerBuilder: NewPurposeEnforcerBuilder(&tcf2AggConfig), } - permissions, err := perms.AuctionActivitiesAllowed(context.Background(), bidderWithoutGVLID, bidderWithoutGVLID) - assert.NoError(t, err) + permissions := perms.AuctionActivitiesAllowed(context.Background(), bidderWithoutGVLID, bidderWithoutGVLID) assert.Equal(t, tt.allowBidRequest, permissions.AllowBidRequest) assert.Equal(t, tt.passID, permissions.PassID) }) @@ -658,8 +656,7 @@ func TestAllowActivitiesGeoAndID(t *testing.T) { perms.consent = td.consent perms.purposeEnforcerBuilder = NewPurposeEnforcerBuilder(&tcf2AggConfig) - permissions, err := perms.AuctionActivitiesAllowed(context.Background(), td.bidderCoreName, td.bidder) - assert.NoErrorf(t, err, "Error processing AuctionActivitiesAllowed for %s", td.description) + permissions := perms.AuctionActivitiesAllowed(context.Background(), td.bidderCoreName, td.bidder) assert.EqualValuesf(t, td.allowBidRequest, permissions.AllowBidRequest, "AllowBid failure on %s", td.description) assert.EqualValuesf(t, td.passGeo, permissions.PassGeo, "PassGeo failure on %s", td.description) assert.EqualValuesf(t, td.passID, permissions.PassID, "PassID failure on %s", td.description) @@ -695,8 +692,7 @@ func TestAllowActivitiesWhitelist(t *testing.T) { } // Assert that an item that otherwise would not be allowed PI access, gets approved because it is found in the GDPR.NonStandardPublishers array - permissions, err := perms.AuctionActivitiesAllowed(context.Background(), openrtb_ext.BidderAppnexus, openrtb_ext.BidderAppnexus) - assert.NoErrorf(t, err, "Error processing AuctionActivitiesAllowed") + permissions := perms.AuctionActivitiesAllowed(context.Background(), openrtb_ext.BidderAppnexus, openrtb_ext.BidderAppnexus) assert.EqualValuesf(t, true, permissions.PassGeo, "PassGeo failure") assert.EqualValuesf(t, true, permissions.PassID, "PassID failure") } @@ -767,8 +763,7 @@ func TestAllowActivitiesPubRestrict(t *testing.T) { perms.aliasGVLIDs = td.aliasGVLIDs perms.consent = td.consent - permissions, err := perms.AuctionActivitiesAllowed(context.Background(), td.bidderCoreName, td.bidder) - assert.NoErrorf(t, err, "Error processing AuctionActivitiesAllowed for %s", td.description) + permissions := perms.AuctionActivitiesAllowed(context.Background(), td.bidderCoreName, td.bidder) assert.EqualValuesf(t, td.passGeo, permissions.PassGeo, "PassGeo failure on %s", td.description) assert.EqualValuesf(t, td.passID, permissions.PassID, "PassID failure on %s", td.description) } @@ -1101,8 +1096,7 @@ func TestAllowActivitiesBidRequests(t *testing.T) { perms.cfg = &tcf2AggConfig perms.purposeEnforcerBuilder = NewPurposeEnforcerBuilder(&tcf2AggConfig) - permissions, err := perms.AuctionActivitiesAllowed(context.Background(), td.bidderCoreName, td.bidder) - assert.NoErrorf(t, err, "Error processing AuctionActivitiesAllowed for %s", td.description) + permissions := perms.AuctionActivitiesAllowed(context.Background(), td.bidderCoreName, td.bidder) assert.EqualValuesf(t, td.allowBidRequest, permissions.AllowBidRequest, "AllowBid failure on %s", td.description) assert.EqualValuesf(t, td.passGeo, permissions.PassGeo, "PassGeo failure on %s", td.description) assert.EqualValuesf(t, td.passID, permissions.PassID, "PassID failure on %s", td.description) @@ -1196,8 +1190,7 @@ func TestAllowActivitiesVendorException(t *testing.T) { perms.cfg = &tcf2AggConfig perms.purposeEnforcerBuilder = NewPurposeEnforcerBuilder(&tcf2AggConfig) - permissions, err := perms.AuctionActivitiesAllowed(context.Background(), td.bidderCoreName, td.bidder) - assert.NoErrorf(t, err, "Error processing AuctionActivitiesAllowed for %s", td.description) + permissions := perms.AuctionActivitiesAllowed(context.Background(), td.bidderCoreName, td.bidder) assert.EqualValuesf(t, td.allowBidRequest, permissions.AllowBidRequest, "AllowBid failure on %s", td.description) assert.EqualValuesf(t, td.passGeo, permissions.PassGeo, "PassGeo failure on %s", td.description) assert.EqualValuesf(t, td.passID, permissions.PassID, "PassID failure on %s", td.description) diff --git a/gdpr/purpose_config.go b/gdpr/purpose_config.go index ff3a92300ff..020d0aaa06e 100644 --- a/gdpr/purpose_config.go +++ b/gdpr/purpose_config.go @@ -2,7 +2,7 @@ package gdpr import ( "github.com/prebid/go-gdpr/consentconstants" - "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v3/config" ) // purposeConfig represents all of the config info selected from the host and account configs for diff --git a/gdpr/purpose_config_test.go b/gdpr/purpose_config_test.go index c2bd6f56d8f..61b7b9b2d68 100644 --- a/gdpr/purpose_config_test.go +++ b/gdpr/purpose_config_test.go @@ -3,7 +3,7 @@ package gdpr import ( "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/gdpr/purpose_enforcer.go b/gdpr/purpose_enforcer.go index ceef0e5f561..5cc5d8e83d5 100644 --- a/gdpr/purpose_enforcer.go +++ b/gdpr/purpose_enforcer.go @@ -4,8 +4,8 @@ import ( "github.com/prebid/go-gdpr/api" "github.com/prebid/go-gdpr/consentconstants" tcf2 "github.com/prebid/go-gdpr/vendorconsent/tcf2" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // PurposeEnforcer represents the enforcement strategy for determining if legal basis is achieved for a purpose diff --git a/gdpr/purpose_enforcer_test.go b/gdpr/purpose_enforcer_test.go index 1f931898ff1..756bb07d716 100644 --- a/gdpr/purpose_enforcer_test.go +++ b/gdpr/purpose_enforcer_test.go @@ -4,8 +4,8 @@ import ( "testing" "github.com/prebid/go-gdpr/consentconstants" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/gdpr/signal.go b/gdpr/signal.go index 3d2e4de1251..478985b64f5 100644 --- a/gdpr/signal.go +++ b/gdpr/signal.go @@ -3,7 +3,7 @@ package gdpr import ( "strconv" - "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v3/errortypes" ) type Signal int diff --git a/gdpr/vendorlist-fetching.go b/gdpr/vendorlist-fetching.go index 64424f5ee69..dc035483479 100644 --- a/gdpr/vendorlist-fetching.go +++ b/gdpr/vendorlist-fetching.go @@ -14,7 +14,7 @@ import ( "github.com/prebid/go-gdpr/api" "github.com/prebid/go-gdpr/vendorlist" "github.com/prebid/go-gdpr/vendorlist2" - "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v3/config" "golang.org/x/net/context/ctxhttp" ) diff --git a/gdpr/vendorlist-fetching_test.go b/gdpr/vendorlist-fetching_test.go index 98dc4ba5aa3..4e9e31dd936 100644 --- a/gdpr/vendorlist-fetching_test.go +++ b/gdpr/vendorlist-fetching_test.go @@ -11,8 +11,8 @@ import ( "github.com/prebid/go-gdpr/api" "github.com/prebid/go-gdpr/consentconstants" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) func TestFetcherDynamicLoadListExists(t *testing.T) { diff --git a/go.mod b/go.mod index c16acc331df..c199310739b 100644 --- a/go.mod +++ b/go.mod @@ -1,7 +1,9 @@ -module github.com/prebid/prebid-server/v2 +module github.com/prebid/prebid-server/v3 go 1.21 +retract v3.0.0 // Forgot to update major version in import path and module name + require ( github.com/DATA-DOG/go-sqlmock v1.5.0 github.com/IABTechLab/adscert v0.34.0 @@ -29,7 +31,7 @@ require ( github.com/prometheus/client_golang v1.12.1 github.com/prometheus/client_model v0.2.0 github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 - github.com/rs/cors v1.8.2 + github.com/rs/cors v1.11.0 github.com/spf13/viper v1.12.0 github.com/stretchr/testify v1.8.1 github.com/vrischmann/go-metrics-influxdb v0.1.1 @@ -43,6 +45,7 @@ require ( ) require ( + github.com/51Degrees/device-detection-go/v4 v4.4.35 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect @@ -58,6 +61,7 @@ require ( github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/prebid/prebid-server/v2 v2.32.0 github.com/prometheus/common v0.32.1 // indirect github.com/prometheus/procfs v0.7.3 // indirect github.com/sergi/go-diff v1.2.0 // indirect @@ -67,6 +71,10 @@ require ( github.com/spf13/pflag v1.0.5 // indirect github.com/stretchr/objx v0.5.0 // indirect github.com/subosito/gotenv v1.3.0 // indirect + github.com/tidwall/gjson v1.17.1 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.0 // indirect + github.com/tidwall/sjson v1.2.5 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect diff --git a/go.sum b/go.sum index 00827d6fb6c..00f42ae8bbe 100644 --- a/go.sum +++ b/go.sum @@ -49,6 +49,8 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/51Degrees/device-detection-go/v4 v4.4.35 h1:qhP2tzoXhGE1aYY3NftMJ+ccxz0+2kM8aF4SH7fTyuA= +github.com/51Degrees/device-detection-go/v4 v4.4.35/go.mod h1:dbdG1fySqdY+a5pUnZ0/G0eD03G6H3Vh8kRC+1f9qSc= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= @@ -135,6 +137,7 @@ github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= +github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= @@ -316,9 +319,11 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lib/pq v1.10.4 h1:SO9z7FRPzA03QhHKJrH5BXA6HU1rS4V2nIVrrNC1iYk= github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w= @@ -405,6 +410,8 @@ github.com/prebid/go-gpp v0.2.0 h1:41Ssxd4Zxr50WgwG1q/1+6awGU3pFnwV7FR4XCLQSuM= github.com/prebid/go-gpp v0.2.0/go.mod h1:b0TLoVln+HXFD9L9xeimxIH3FN8WDKPJ42auslxEkow= github.com/prebid/openrtb/v20 v20.1.0 h1:Rb+Z3H3UxiqqnjgJK3R9Wt73ibrh7HPzG7ikBckQNqc= github.com/prebid/openrtb/v20 v20.1.0/go.mod h1:hLBrA/APkSrxs5MaW639l+y/EAHivDfRagO2TX/wbSc= +github.com/prebid/prebid-server/v2 v2.32.0 h1:E+zX1CGtWjkUTPQzMKHMEsn26yGDnZI6znG1rgxosQo= +github.com/prebid/prebid-server/v2 v2.32.0/go.mod h1:wyuZeJWIWtt+D5YWN/CL+t9IklM/Gof5YBs+Urt1tHM= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= @@ -436,8 +443,9 @@ github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqn github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= -github.com/rs/cors v1.8.2 h1:KCooALfAYGs415Cwu5ABvv9n9509fSiG5SQJn/AQo4U= -github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rs/cors v1.11.0 h1:0B9GE/r9Bc2UxRMMtymBkHTenPkHDv0CW4Y98GBY+po= +github.com/rs/cors v1.11.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= @@ -483,6 +491,15 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/subosito/gotenv v1.3.0 h1:mjC+YW8QpAdXibNi+vNWgzmgBH4+5l5dCXv8cNysBLI= github.com/subosito/gotenv v1.3.0/go.mod h1:YzJjq/33h7nrwdY+iHMhEOEEbW0ovIz0tB6t6PwAXzs= +github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.17.1 h1:wlYEnwqAHgzmhNUFfw7Xalt2JzQvsMx2Se4PcoFCT/U= +github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= +github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/vrischmann/go-metrics-influxdb v0.1.1 h1:xneKFRjsS4BiVYvAKaM/rOlXYd1pGHksnES0ECCJLgo= github.com/vrischmann/go-metrics-influxdb v0.1.1/go.mod h1:q7YC8bFETCYopXRMtUvQQdLaoVhpsEwvQS2zZEYCqg8= diff --git a/hooks/empty_plan.go b/hooks/empty_plan.go index 514d3824898..72c1a9276d5 100644 --- a/hooks/empty_plan.go +++ b/hooks/empty_plan.go @@ -1,8 +1,8 @@ package hooks import ( - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/hooks/hookstage" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/hooks/hookstage" ) // EmptyPlanBuilder implements the ExecutionPlanBuilder interface diff --git a/hooks/hookanalytics/analytics_test.go b/hooks/hookanalytics/analytics_test.go index 27584cf0d39..a1186e1b862 100644 --- a/hooks/hookanalytics/analytics_test.go +++ b/hooks/hookanalytics/analytics_test.go @@ -3,7 +3,7 @@ package hookanalytics import ( "testing" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/jsonutil" "github.com/stretchr/testify/assert" ) diff --git a/hooks/hookexecution/context.go b/hooks/hookexecution/context.go index f7b6a9d32e1..98a38714618 100644 --- a/hooks/hookexecution/context.go +++ b/hooks/hookexecution/context.go @@ -4,9 +4,9 @@ import ( "sync" "github.com/golang/glog" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/hooks/hookstage" - "github.com/prebid/prebid-server/v2/privacy" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/hooks/hookstage" + "github.com/prebid/prebid-server/v3/privacy" ) // executionContext holds information passed to module's hook during hook execution. diff --git a/hooks/hookexecution/enricher.go b/hooks/hookexecution/enricher.go index 3617a528660..7ca9f65f176 100644 --- a/hooks/hookexecution/enricher.go +++ b/hooks/hookexecution/enricher.go @@ -5,8 +5,8 @@ import ( "github.com/buger/jsonparser" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/util/jsonutil" jsonpatch "gopkg.in/evanphx/json-patch.v4" ) diff --git a/hooks/hookexecution/enricher_test.go b/hooks/hookexecution/enricher_test.go index 4f962dea279..beb07444d10 100644 --- a/hooks/hookexecution/enricher_test.go +++ b/hooks/hookexecution/enricher_test.go @@ -7,10 +7,10 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/hooks/hookanalytics" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/hooks/hookanalytics" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/hooks/hookexecution/errors.go b/hooks/hookexecution/errors.go index 1d016e26019..0e61ebc983b 100644 --- a/hooks/hookexecution/errors.go +++ b/hooks/hookexecution/errors.go @@ -3,7 +3,7 @@ package hookexecution import ( "fmt" - "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v3/errortypes" ) // TimeoutError indicates exceeding of the max execution time allotted for hook. diff --git a/hooks/hookexecution/execution.go b/hooks/hookexecution/execution.go index 46b54e46b3c..caaba59c3bb 100644 --- a/hooks/hookexecution/execution.go +++ b/hooks/hookexecution/execution.go @@ -7,14 +7,14 @@ import ( "sync" "time" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/hooks" - "github.com/prebid/prebid-server/v2/hooks/hookstage" - "github.com/prebid/prebid-server/v2/metrics" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/ortb" - "github.com/prebid/prebid-server/v2/privacy" - "github.com/prebid/prebid-server/v2/util/iputil" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/hooks" + "github.com/prebid/prebid-server/v3/hooks/hookstage" + "github.com/prebid/prebid-server/v3/metrics" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/ortb" + "github.com/prebid/prebid-server/v3/privacy" + "github.com/prebid/prebid-server/v3/util/iputil" ) type hookResponse[T any] struct { diff --git a/hooks/hookexecution/execution_test.go b/hooks/hookexecution/execution_test.go index 33f652faa2f..1090db578d4 100644 --- a/hooks/hookexecution/execution_test.go +++ b/hooks/hookexecution/execution_test.go @@ -4,10 +4,10 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/hooks/hookstage" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/privacy" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/hooks/hookstage" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/privacy" "github.com/stretchr/testify/assert" ) diff --git a/hooks/hookexecution/executor.go b/hooks/hookexecution/executor.go index 835e9de32c1..70725de79c5 100644 --- a/hooks/hookexecution/executor.go +++ b/hooks/hookexecution/executor.go @@ -6,14 +6,14 @@ import ( "sync" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/exchange/entities" - "github.com/prebid/prebid-server/v2/hooks" - "github.com/prebid/prebid-server/v2/hooks/hookstage" - "github.com/prebid/prebid-server/v2/metrics" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/privacy" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/exchange/entities" + "github.com/prebid/prebid-server/v3/hooks" + "github.com/prebid/prebid-server/v3/hooks/hookstage" + "github.com/prebid/prebid-server/v3/metrics" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/privacy" ) const ( diff --git a/hooks/hookexecution/executor_test.go b/hooks/hookexecution/executor_test.go index 2f7cb077494..5e19f24a96f 100644 --- a/hooks/hookexecution/executor_test.go +++ b/hooks/hookexecution/executor_test.go @@ -9,17 +9,17 @@ import ( "time" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/exchange/entities" - "github.com/prebid/prebid-server/v2/hooks" - "github.com/prebid/prebid-server/v2/hooks/hookanalytics" - "github.com/prebid/prebid-server/v2/hooks/hookstage" - "github.com/prebid/prebid-server/v2/metrics" - metricsConfig "github.com/prebid/prebid-server/v2/metrics/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/privacy" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/exchange/entities" + "github.com/prebid/prebid-server/v3/hooks" + "github.com/prebid/prebid-server/v3/hooks/hookanalytics" + "github.com/prebid/prebid-server/v3/hooks/hookstage" + "github.com/prebid/prebid-server/v3/metrics" + metricsConfig "github.com/prebid/prebid-server/v3/metrics/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/privacy" + "github.com/prebid/prebid-server/v3/util/ptrutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" ) diff --git a/hooks/hookexecution/mocks_test.go b/hooks/hookexecution/mocks_test.go index 8c34a518bab..57205707b98 100644 --- a/hooks/hookexecution/mocks_test.go +++ b/hooks/hookexecution/mocks_test.go @@ -5,9 +5,9 @@ import ( "errors" "time" - "github.com/prebid/prebid-server/v2/hooks/hookstage" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/hooks/hookstage" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/ptrutil" ) type mockUpdateHeaderEntrypointHook struct{} diff --git a/hooks/hookexecution/outcome.go b/hooks/hookexecution/outcome.go index ff8bf1e973e..d17d3cd4672 100644 --- a/hooks/hookexecution/outcome.go +++ b/hooks/hookexecution/outcome.go @@ -3,7 +3,7 @@ package hookexecution import ( "time" - "github.com/prebid/prebid-server/v2/hooks/hookanalytics" + "github.com/prebid/prebid-server/v3/hooks/hookanalytics" ) // Status indicates the result of hook execution. diff --git a/hooks/hookexecution/test_utils.go b/hooks/hookexecution/test_utils.go index 32ae9fd7a22..b26d4aae4bd 100644 --- a/hooks/hookexecution/test_utils.go +++ b/hooks/hookexecution/test_utils.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/jsonutil" "github.com/stretchr/testify/assert" ) diff --git a/hooks/hookstage/allprocessedbidresponses.go b/hooks/hookstage/allprocessedbidresponses.go index 233a68b6efd..6bfe0d80821 100644 --- a/hooks/hookstage/allprocessedbidresponses.go +++ b/hooks/hookstage/allprocessedbidresponses.go @@ -3,8 +3,8 @@ package hookstage import ( "context" - "github.com/prebid/prebid-server/v2/exchange/entities" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/exchange/entities" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // AllProcessedBidResponses hooks are invoked over a list of all diff --git a/hooks/hookstage/bidderrequest.go b/hooks/hookstage/bidderrequest.go index 05f3574c8bf..8c27f07242a 100644 --- a/hooks/hookstage/bidderrequest.go +++ b/hooks/hookstage/bidderrequest.go @@ -2,7 +2,8 @@ package hookstage import ( "context" - "github.com/prebid/prebid-server/v2/openrtb_ext" + + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // BidderRequest hooks are invoked for each bidder participating in auction. diff --git a/hooks/hookstage/bidderrequest_mutations.go b/hooks/hookstage/bidderrequest_mutations.go index 6f4d5a5bacb..3ab571ff8e7 100644 --- a/hooks/hookstage/bidderrequest_mutations.go +++ b/hooks/hookstage/bidderrequest_mutations.go @@ -3,7 +3,7 @@ package hookstage import ( "errors" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/prebid/openrtb/v20/adcom1" ) diff --git a/hooks/hookstage/invocation.go b/hooks/hookstage/invocation.go index 73b210957e2..6408e8667df 100644 --- a/hooks/hookstage/invocation.go +++ b/hooks/hookstage/invocation.go @@ -3,7 +3,7 @@ package hookstage import ( "encoding/json" - "github.com/prebid/prebid-server/v2/hooks/hookanalytics" + "github.com/prebid/prebid-server/v3/hooks/hookanalytics" ) // HookResult represents the result of execution the concrete hook instance. diff --git a/hooks/hookstage/processedauctionrequest.go b/hooks/hookstage/processedauctionrequest.go index 02638dccc20..06742138826 100644 --- a/hooks/hookstage/processedauctionrequest.go +++ b/hooks/hookstage/processedauctionrequest.go @@ -2,7 +2,8 @@ package hookstage import ( "context" - "github.com/prebid/prebid-server/v2/openrtb_ext" + + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // ProcessedAuctionRequest hooks are invoked after the request is parsed diff --git a/hooks/hookstage/rawbidderresponse.go b/hooks/hookstage/rawbidderresponse.go index 7d08a7d2e02..7f518211569 100644 --- a/hooks/hookstage/rawbidderresponse.go +++ b/hooks/hookstage/rawbidderresponse.go @@ -3,7 +3,7 @@ package hookstage import ( "context" - "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v3/adapters" ) // RawBidderResponse hooks are invoked for each bidder participating in auction. diff --git a/hooks/hookstage/rawbidderresponse_mutations.go b/hooks/hookstage/rawbidderresponse_mutations.go index efab874fa15..931d76f6a2e 100644 --- a/hooks/hookstage/rawbidderresponse_mutations.go +++ b/hooks/hookstage/rawbidderresponse_mutations.go @@ -3,7 +3,7 @@ package hookstage import ( "errors" - "github.com/prebid/prebid-server/v2/adapters" + "github.com/prebid/prebid-server/v3/adapters" ) func (c *ChangeSet[T]) RawBidderResponse() ChangeSetRawBidderResponse[T] { diff --git a/hooks/plan.go b/hooks/plan.go index a3a0e9af661..62655f6cf5c 100644 --- a/hooks/plan.go +++ b/hooks/plan.go @@ -4,8 +4,8 @@ import ( "time" "github.com/golang/glog" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/hooks/hookstage" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/hooks/hookstage" ) type Stage string diff --git a/hooks/plan_test.go b/hooks/plan_test.go index 064403cb8cf..fd2d0554e5c 100644 --- a/hooks/plan_test.go +++ b/hooks/plan_test.go @@ -5,9 +5,9 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/hooks/hookstage" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/hooks/hookstage" + "github.com/prebid/prebid-server/v3/util/jsonutil" "github.com/stretchr/testify/assert" ) diff --git a/hooks/repo.go b/hooks/repo.go index 3d8db581bda..cb77c7bbea6 100644 --- a/hooks/repo.go +++ b/hooks/repo.go @@ -3,7 +3,7 @@ package hooks import ( "fmt" - "github.com/prebid/prebid-server/v2/hooks/hookstage" + "github.com/prebid/prebid-server/v3/hooks/hookstage" ) // HookRepository is the interface that exposes methods diff --git a/hooks/repo_test.go b/hooks/repo_test.go index 1ffbf0bfbed..d6d37133511 100644 --- a/hooks/repo_test.go +++ b/hooks/repo_test.go @@ -5,7 +5,7 @@ import ( "fmt" "testing" - "github.com/prebid/prebid-server/v2/hooks/hookstage" + "github.com/prebid/prebid-server/v3/hooks/hookstage" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/injector/injector.go b/injector/injector.go index 8f902273257..9de2c1b726b 100644 --- a/injector/injector.go +++ b/injector/injector.go @@ -6,8 +6,8 @@ import ( "io" "strings" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/metrics" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/metrics" ) const ( diff --git a/injector/injector_test.go b/injector/injector_test.go index 2c9dceba154..b3457b094b7 100644 --- a/injector/injector_test.go +++ b/injector/injector_test.go @@ -6,10 +6,10 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/exchange/entities" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/exchange/entities" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/ptrutil" "github.com/stretchr/testify/assert" ) @@ -35,7 +35,7 @@ var reqWrapper = &openrtb_ext.RequestWrapper{ Device: &openrtb2.Device{ Lmt: ptrutil.ToPtr(int8(1)), }, - User: &openrtb2.User{Ext: []byte(`{"consent":"1" }`)}, + User: &openrtb2.User{Consent: "1", Ext: []byte(`{"consent":"2" }`)}, Ext: []byte(`{"prebid":{"channel": {"name":"test1"},"macros":{"CUSTOMMACR1":"value1"}}}`), }, } diff --git a/macros/macros.go b/macros/macros.go index bde843c3cbb..2b0e29d6238 100644 --- a/macros/macros.go +++ b/macros/macros.go @@ -17,6 +17,10 @@ type EndpointTemplateParams struct { GvlID string PageID string SupplyId string + SspId string + SspID string + SeatID string + TokenID string } // UserSyncPrivacy specifies privacy policy macros, represented as strings, for user sync urls. diff --git a/macros/provider.go b/macros/provider.go index 0b4ef3eacb3..575aa49aa57 100644 --- a/macros/provider.go +++ b/macros/provider.go @@ -5,8 +5,8 @@ import ( "strconv" "time" - "github.com/prebid/prebid-server/v2/exchange/entities" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/exchange/entities" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) const ( @@ -104,9 +104,8 @@ func (b *MacroProvider) populateRequestMacros(reqWrapper *openrtb_ext.RequestWra } } - userExt, err := reqWrapper.GetUserExt() - if err == nil && userExt != nil && userExt.GetConsent() != nil { - b.macros[MacroKeyConsent] = *userExt.GetConsent() + if reqWrapper.User != nil && len(reqWrapper.User.Consent) > 0 { + b.macros[MacroKeyConsent] = reqWrapper.User.Consent } if reqWrapper.Device != nil && reqWrapper.Device.Lmt != nil { b.macros[MacroKeyLmtTracking] = strconv.Itoa(int(*reqWrapper.Device.Lmt)) diff --git a/macros/provider_test.go b/macros/provider_test.go index 3da56ea7826..795fae9c412 100644 --- a/macros/provider_test.go +++ b/macros/provider_test.go @@ -4,8 +4,8 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/exchange/entities" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/exchange/entities" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) @@ -132,7 +132,7 @@ func TestPopulateRequestMacros(t *testing.T) { args: args{ reqWrapper: &openrtb_ext.RequestWrapper{ BidRequest: &openrtb2.BidRequest{ - User: &openrtb2.User{Ext: []byte(`{"consent":"1" }`)}, + User: &openrtb2.User{Consent: "1", Ext: []byte(`{"consent":"2" }`)}, Ext: []byte(`{"prebid":{"integration":"testIntegration"}}`), }, }, @@ -189,7 +189,7 @@ func TestPopulateRequestMacros(t *testing.T) { Device: &openrtb2.Device{ Lmt: &lmt, }, - User: &openrtb2.User{Ext: []byte(`{"consent":"1" }`)}, + User: &openrtb2.User{Consent: "1", Ext: []byte(`{"consent":"2" }`)}, Ext: []byte(`{"prebid":{"channel": {"name":"test1"},"macros":{"CUSTOMMACR1":"value1"}}}`), }, }, diff --git a/macros/string_index_based_replacer_test.go b/macros/string_index_based_replacer_test.go index 6e09db1e15a..515640d4ff2 100644 --- a/macros/string_index_based_replacer_test.go +++ b/macros/string_index_based_replacer_test.go @@ -5,8 +5,8 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/exchange/entities" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/exchange/entities" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) @@ -116,7 +116,7 @@ var req *openrtb_ext.RequestWrapper = &openrtb_ext.RequestWrapper{ Device: &openrtb2.Device{ Lmt: &lmt, }, - User: &openrtb2.User{Ext: []byte(`{"consent":"yes" }`)}, + User: &openrtb2.User{Consent: "yes", Ext: []byte(`{"consent":"no" }`)}, Ext: []byte(`{"prebid":{"channel": {"name":"test1"},"macros":{"CUSTOMMACR1":"value1","CUSTOMMACR2":"value2","CUSTOMMACR3":"value3"}}}`), }, } diff --git a/main.go b/main.go index 4ef96b34724..0063b4ee0b6 100644 --- a/main.go +++ b/main.go @@ -8,13 +8,13 @@ import ( "time" jsoniter "github.com/json-iterator/go" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/currency" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/router" - "github.com/prebid/prebid-server/v2/server" - "github.com/prebid/prebid-server/v2/util/jsonutil" - "github.com/prebid/prebid-server/v2/util/task" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/currency" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/router" + "github.com/prebid/prebid-server/v3/server" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/task" "github.com/golang/glog" "github.com/spf13/viper" diff --git a/main_test.go b/main_test.go index 79ae373d473..494e6d67746 100644 --- a/main_test.go +++ b/main_test.go @@ -4,7 +4,7 @@ import ( "os" "testing" - "github.com/prebid/prebid-server/v2/config" + "github.com/prebid/prebid-server/v3/config" "github.com/stretchr/testify/assert" "github.com/spf13/viper" diff --git a/metrics/config/metrics.go b/metrics/config/metrics.go index 8b544bd966b..dcb330c47f9 100644 --- a/metrics/config/metrics.go +++ b/metrics/config/metrics.go @@ -3,10 +3,10 @@ package config import ( "time" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/metrics" - prometheusmetrics "github.com/prebid/prebid-server/v2/metrics/prometheus" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/metrics" + prometheusmetrics "github.com/prebid/prebid-server/v3/metrics/prometheus" + "github.com/prebid/prebid-server/v3/openrtb_ext" gometrics "github.com/rcrowley/go-metrics" influxdb "github.com/vrischmann/go-metrics-influxdb" ) diff --git a/metrics/config/metrics_test.go b/metrics/config/metrics_test.go index 4139f063b72..6060b692bfe 100644 --- a/metrics/config/metrics_test.go +++ b/metrics/config/metrics_test.go @@ -6,9 +6,9 @@ import ( "testing" "time" - mainConfig "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/metrics" - "github.com/prebid/prebid-server/v2/openrtb_ext" + mainConfig "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/metrics" + "github.com/prebid/prebid-server/v3/openrtb_ext" gometrics "github.com/rcrowley/go-metrics" ) @@ -39,16 +39,14 @@ func TestGoMetricsEngine(t *testing.T) { } } -// Test the multiengine func TestMultiMetricsEngine(t *testing.T) { cfg := mainConfig.Configuration{} cfg.Metrics.Influxdb.Host = "localhost" adapterList := openrtb_ext.CoreBidderNames() goEngine := metrics.NewMetrics(gometrics.NewPrefixedRegistry("prebidserver."), adapterList, mainConfig.DisabledMetrics{}, nil, modulesStages) - engineList := make(MultiMetricsEngine, 2) - engineList[0] = goEngine - engineList[1] = &NilMetricsEngine{} - var metricsEngine metrics.MetricsEngine = &engineList + metricsEngine := make(MultiMetricsEngine, 2) + metricsEngine[0] = goEngine + metricsEngine[1] = &NilMetricsEngine{} labels := metrics.Labels{ Source: metrics.DemandWeb, RType: metrics.ReqTypeORTB2Web, @@ -108,23 +106,23 @@ func TestMultiMetricsEngine(t *testing.T) { metricsEngine.RecordModuleExecutionError(module) metricsEngine.RecordModuleTimeout(module) } - labelsBlacklist := []metrics.Labels{ + labelsBlocked := []metrics.Labels{ { Source: metrics.DemandWeb, RType: metrics.ReqTypeAMP, PubID: "test2", CookieFlag: metrics.CookieFlagYes, - RequestStatus: metrics.RequestStatusBlacklisted, + RequestStatus: metrics.RequestStatusBlockedApp, }, { Source: metrics.DemandWeb, RType: metrics.ReqTypeVideo, PubID: "test2", CookieFlag: metrics.CookieFlagYes, - RequestStatus: metrics.RequestStatusBlacklisted, + RequestStatus: metrics.RequestStatusBlockedApp, }, } - for _, label := range labelsBlacklist { + for _, label := range labelsBlocked { metricsEngine.RecordRequest(label) } impTypeLabels.BannerImps = false @@ -150,14 +148,14 @@ func TestMultiMetricsEngine(t *testing.T) { //Make the metrics engine, instantiated here with goEngine, fill its RequestStatuses[RequestType][metrics.RequestStatusXX] with the new boolean values added to metrics.Labels VerifyMetrics(t, "RequestStatuses.OpenRTB2.OK", goEngine.RequestStatuses[metrics.ReqTypeORTB2Web][metrics.RequestStatusOK].Count(), 5) VerifyMetrics(t, "RequestStatuses.AMP.OK", goEngine.RequestStatuses[metrics.ReqTypeAMP][metrics.RequestStatusOK].Count(), 0) - VerifyMetrics(t, "RequestStatuses.AMP.BlacklistedAcctOrApp", goEngine.RequestStatuses[metrics.ReqTypeAMP][metrics.RequestStatusBlacklisted].Count(), 1) + VerifyMetrics(t, "RequestStatuses.AMP.BlockedApp", goEngine.RequestStatuses[metrics.ReqTypeAMP][metrics.RequestStatusBlockedApp].Count(), 1) VerifyMetrics(t, "RequestStatuses.Video.OK", goEngine.RequestStatuses[metrics.ReqTypeVideo][metrics.RequestStatusOK].Count(), 0) VerifyMetrics(t, "RequestStatuses.Video.Error", goEngine.RequestStatuses[metrics.ReqTypeVideo][metrics.RequestStatusErr].Count(), 0) VerifyMetrics(t, "RequestStatuses.Video.BadInput", goEngine.RequestStatuses[metrics.ReqTypeVideo][metrics.RequestStatusBadInput].Count(), 0) - VerifyMetrics(t, "RequestStatuses.Video.BlacklistedAcctOrApp", goEngine.RequestStatuses[metrics.ReqTypeVideo][metrics.RequestStatusBlacklisted].Count(), 1) + VerifyMetrics(t, "RequestStatuses.Video.BlockedApp", goEngine.RequestStatuses[metrics.ReqTypeVideo][metrics.RequestStatusBlockedApp].Count(), 1) VerifyMetrics(t, "RequestStatuses.OpenRTB2.Error", goEngine.RequestStatuses[metrics.ReqTypeORTB2Web][metrics.RequestStatusErr].Count(), 0) VerifyMetrics(t, "RequestStatuses.OpenRTB2.BadInput", goEngine.RequestStatuses[metrics.ReqTypeORTB2Web][metrics.RequestStatusBadInput].Count(), 0) - VerifyMetrics(t, "RequestStatuses.OpenRTB2.BlacklistedAcctOrApp", goEngine.RequestStatuses[metrics.ReqTypeORTB2Web][metrics.RequestStatusBlacklisted].Count(), 0) + VerifyMetrics(t, "RequestStatuses.OpenRTB2.BlockedApp", goEngine.RequestStatuses[metrics.ReqTypeORTB2Web][metrics.RequestStatusBlockedApp].Count(), 0) VerifyMetrics(t, "ImpsTypeBanner", goEngine.ImpsTypeBanner.Count(), 5) VerifyMetrics(t, "ImpsTypeVideo", goEngine.ImpsTypeVideo.Count(), 3) diff --git a/metrics/go_metrics.go b/metrics/go_metrics.go index ac28a18c8e1..428b1891e69 100644 --- a/metrics/go_metrics.go +++ b/metrics/go_metrics.go @@ -7,8 +7,8 @@ import ( "time" "github.com/golang/glog" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" metrics "github.com/rcrowley/go-metrics" ) diff --git a/metrics/go_metrics_test.go b/metrics/go_metrics_test.go index 7cacd9099db..791b4ee0ec8 100644 --- a/metrics/go_metrics_test.go +++ b/metrics/go_metrics_test.go @@ -5,8 +5,8 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" metrics "github.com/rcrowley/go-metrics" "github.com/stretchr/testify/assert" ) @@ -73,7 +73,7 @@ func TestNewMetrics(t *testing.T) { ensureContains(t, registry, "syncer.foo.request.ok", m.SyncerRequestsMeter["foo"][SyncerCookieSyncOK]) ensureContains(t, registry, "syncer.foo.request.privacy_blocked", m.SyncerRequestsMeter["foo"][SyncerCookieSyncPrivacyBlocked]) ensureContains(t, registry, "syncer.foo.request.already_synced", m.SyncerRequestsMeter["foo"][SyncerCookieSyncAlreadySynced]) - ensureContains(t, registry, "syncer.foo.request.type_not_supported", m.SyncerRequestsMeter["foo"][SyncerCookieSyncTypeNotSupported]) + ensureContains(t, registry, "syncer.foo.request.rejected_by_filter", m.SyncerRequestsMeter["foo"][SyncerCookieSyncRejectedByFilter]) ensureContains(t, registry, "syncer.foo.set.ok", m.SyncerSetsMeter["foo"][SyncerSetUidOK]) ensureContains(t, registry, "syncer.foo.set.cleared", m.SyncerSetsMeter["foo"][SyncerSetUidCleared]) @@ -908,7 +908,7 @@ func TestRecordSyncerRequest(t *testing.T) { assert.Equal(t, m.SyncerRequestsMeter["foo"][SyncerCookieSyncOK].Count(), int64(1)) assert.Equal(t, m.SyncerRequestsMeter["foo"][SyncerCookieSyncPrivacyBlocked].Count(), int64(0)) assert.Equal(t, m.SyncerRequestsMeter["foo"][SyncerCookieSyncAlreadySynced].Count(), int64(0)) - assert.Equal(t, m.SyncerRequestsMeter["foo"][SyncerCookieSyncTypeNotSupported].Count(), int64(0)) + assert.Equal(t, m.SyncerRequestsMeter["foo"][SyncerCookieSyncRejectedByFilter].Count(), int64(0)) } func TestRecordSetUid(t *testing.T) { diff --git a/metrics/metrics.go b/metrics/metrics.go index 2696c642e21..45484cab7fd 100644 --- a/metrics/metrics.go +++ b/metrics/metrics.go @@ -3,7 +3,7 @@ package metrics import ( "time" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) // Labels defines the labels that can be attached to the metrics. @@ -234,7 +234,7 @@ const ( RequestStatusBadInput RequestStatus = "badinput" RequestStatusErr RequestStatus = "err" RequestStatusNetworkErr RequestStatus = "networkerr" - RequestStatusBlacklisted RequestStatus = "blacklistedacctorapp" + RequestStatusBlockedApp RequestStatus = "blockedapp" RequestStatusQueueTimeout RequestStatus = "queuetimeout" RequestStatusAccountConfigErr RequestStatus = "acctconfigerr" ) @@ -245,7 +245,7 @@ func RequestStatuses() []RequestStatus { RequestStatusBadInput, RequestStatusErr, RequestStatusNetworkErr, - RequestStatusBlacklisted, + RequestStatusBlockedApp, RequestStatusQueueTimeout, RequestStatusAccountConfigErr, } @@ -361,7 +361,7 @@ const ( SyncerCookieSyncOK SyncerCookieSyncStatus = "ok" SyncerCookieSyncPrivacyBlocked SyncerCookieSyncStatus = "privacy_blocked" SyncerCookieSyncAlreadySynced SyncerCookieSyncStatus = "already_synced" - SyncerCookieSyncTypeNotSupported SyncerCookieSyncStatus = "type_not_supported" + SyncerCookieSyncRejectedByFilter SyncerCookieSyncStatus = "rejected_by_filter" ) // SyncerRequestStatuses returns possible syncer statuses. @@ -370,7 +370,7 @@ func SyncerRequestStatuses() []SyncerCookieSyncStatus { SyncerCookieSyncOK, SyncerCookieSyncPrivacyBlocked, SyncerCookieSyncAlreadySynced, - SyncerCookieSyncTypeNotSupported, + SyncerCookieSyncRejectedByFilter, } } diff --git a/metrics/metrics_mock.go b/metrics/metrics_mock.go index 56e2ab8fb1b..e979c6db72e 100644 --- a/metrics/metrics_mock.go +++ b/metrics/metrics_mock.go @@ -3,7 +3,7 @@ package metrics import ( "time" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/mock" ) diff --git a/metrics/prometheus/preload.go b/metrics/prometheus/preload.go index 73ea643722b..c59dfeece02 100644 --- a/metrics/prometheus/preload.go +++ b/metrics/prometheus/preload.go @@ -1,8 +1,8 @@ package prometheusmetrics import ( - "github.com/prebid/prebid-server/v2/metrics" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/metrics" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/prometheus/client_golang/prometheus" ) diff --git a/metrics/prometheus/prometheus.go b/metrics/prometheus/prometheus.go index 89b589badf8..7273a97f07d 100644 --- a/metrics/prometheus/prometheus.go +++ b/metrics/prometheus/prometheus.go @@ -6,9 +6,9 @@ import ( "strings" "time" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/metrics" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/metrics" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/prometheus/client_golang/prometheus" promCollector "github.com/prometheus/client_golang/prometheus/collectors" ) diff --git a/metrics/prometheus/prometheus_test.go b/metrics/prometheus/prometheus_test.go index fcb9ba6452c..3ec5969bb6f 100644 --- a/metrics/prometheus/prometheus_test.go +++ b/metrics/prometheus/prometheus_test.go @@ -5,9 +5,9 @@ import ( "testing" "time" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/metrics" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/metrics" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/prometheus/client_golang/prometheus" dto "github.com/prometheus/client_model/go" "github.com/stretchr/testify/assert" @@ -141,7 +141,7 @@ func TestConnectionMetrics(t *testing.T) { func TestRequestMetric(t *testing.T) { m := createMetricsForTesting() requestType := metrics.ReqTypeORTB2Web - requestStatus := metrics.RequestStatusBlacklisted + requestStatus := metrics.RequestStatusBlockedApp m.RecordRequest(metrics.Labels{ RType: requestType, @@ -285,7 +285,7 @@ func TestRequestMetricWithoutCookie(t *testing.T) { performTest := func(m *Metrics, cookieFlag metrics.CookieFlag) { m.RecordRequest(metrics.Labels{ RType: requestType, - RequestStatus: metrics.RequestStatusBlacklisted, + RequestStatus: metrics.RequestStatusBlockedApp, CookieFlag: cookieFlag, }) } @@ -337,7 +337,7 @@ func TestAccountMetric(t *testing.T) { performTest := func(m *Metrics, pubID string) { m.RecordRequest(metrics.Labels{ RType: metrics.ReqTypeORTB2Web, - RequestStatus: metrics.RequestStatusBlacklisted, + RequestStatus: metrics.RequestStatusBlockedApp, PubID: pubID, }) } @@ -1235,7 +1235,7 @@ func TestRecordSyncerRequestMetric(t *testing.T) { label: "already_synced", }, { - status: metrics.SyncerCookieSyncTypeNotSupported, + status: metrics.SyncerCookieSyncRejectedByFilter, label: "type_not_supported", }, } diff --git a/modules/builder.go b/modules/builder.go index e5d04e149af..2101b340231 100644 --- a/modules/builder.go +++ b/modules/builder.go @@ -1,13 +1,17 @@ package modules import ( - prebidOrtb2blocking "github.com/prebid/prebid-server/v2/modules/prebid/ortb2blocking" + fiftyonedegreesDevicedetection "github.com/prebid/prebid-server/v3/modules/fiftyonedegrees/devicedetection" + prebidOrtb2blocking "github.com/prebid/prebid-server/v3/modules/prebid/ortb2blocking" ) // builders returns mapping between module name and its builder // vendor and module names are chosen based on the module directory name func builders() ModuleBuilders { return ModuleBuilders{ + "fiftyonedegrees": { + "devicedetection": fiftyonedegreesDevicedetection.Builder, + }, "prebid": { "ortb2blocking": prebidOrtb2blocking.Builder, }, diff --git a/modules/fiftyonedegrees/devicedetection/README.md b/modules/fiftyonedegrees/devicedetection/README.md new file mode 100644 index 00000000000..645fb407fe5 --- /dev/null +++ b/modules/fiftyonedegrees/devicedetection/README.md @@ -0,0 +1,255 @@ +## Overview + +The 51Degrees module enriches an incoming OpenRTB request with [51Degrees Device Data](https://51degrees.com/documentation/_device_detection__overview.html). + +The module sets the following fields of the device object: `make`, `model`, `os`, `osv`, `h`, `w`, `ppi`, `pxratio` - interested bidder adapters may use these fields as needed. In addition the module sets `device.ext.fiftyonedegrees_deviceId` to a permanent device ID which can be rapidly looked up in on premise data exposing over 250 properties including the device age, chip set, codec support, and price, operating system and app/browser versions, age, and embedded features. + +## Operation Details + +### Evidence + +The module uses `device.ua` (User Agent) and `device.sua` (Structured User Agent) provided in the oRTB request payload as input (or 'evidence' in 51Degrees terminology). There is a fallback to the corresponding HTTP request headers if any of these are not present in the oRTB payload - in particular: `User-Agent` and `Sec-CH-UA-*` (aka User-Agent Client Hints). To make sure Prebid.js sends Structured User Agent in the oRTB payload - we strongly advice publishers to enable [First Party Data Enrichment module](dev-docs/modules/enrichmentFpdModule.html) for their wrappers and specify + +```js +pbjs.setConfig({ + firstPartyData: { + uaHints: [ + 'architecture', + 'model', + 'platform', + 'platformVersion', + 'fullVersionList', + ] + } +}) +``` + +### Data File Updates + +The module operates **fully autonomously and does not make any requests to any cloud services in real time to do device detection**. This is an [on-premise data](https://51degrees.com/developers/deployment-options/on-premise-data) deployment in 51Degrees terminology. The module operates using a local data file that is loaded into memory fully or partially during operation. The data file is occasionally updated to accomodate new devices, so it is recommended to enable automatic data updates in the module configuration. Alternatively `watch_file_system` option can be used and the file may be downloaded and replaced on disk manually. See the configuration options below. + +## Setup + +The 51Degrees module operates using a data file. You can get started with a free Lite data file that can be downloaded here: [51Degrees-LiteV4.1.hash](https://github.com/51Degrees/device-detection-data/blob/main/51Degrees-LiteV4.1.hash). The Lite file is capable of detecting limited device information, so if you need in-depth device data, please contact 51Degrees to obtain a license: [https://51degrees.com/contact-us](https://51degrees.com/contact-us?ContactReason=Free%20Trial). + +Put the data file in a file system location writable by the system account that is running the Prebid Server module and specify that directory location in the configuration parameters. The location needs to be writable if you would like to enable [automatic data file updates](https://51degrees.com/documentation/_features__automatic_datafile_updates.html). + +### Execution Plan + +This module supports running at two stages: + +* entrypoint: this is where incoming requests are parsed and device detection evidences are extracted. +* raw-auction-request: this is where outgoing auction requests to each bidder are enriched with the device detection data + +We recommend defining the execution plan right in the account config +so the module is only invoked for specific accounts. See below for an example. + +### Global Config + +There is no host-company level config for this module. + +### Account-Level Config + +To start using current module in PBS-Go you have to enable module and add `fiftyone-devicedetection-entrypoint-hook` and `fiftyone-devicedetection-raw-auction-request-hook` into hooks execution plan inside your config file: +Here's a general template for the account config used in PBS-Go: + +```json +{ + "hooks": { + "enabled":true, + "modules": { + "fiftyonedegrees": { + "devicedetection": { + "enabled": true, + "make_temp_copy": true, + "data_file": { + "path": "path/to/51Degrees-LiteV4.1.hash", + "update": { + "auto": true, + "url": "", + "polling_interval": 1800, + "license_key": "", + "product": "V4Enterprise", + "watch_file_system": "true", + "on_startup": true + } + } + } + }, + "host_execution_plan": { + "endpoints": { + "/openrtb2/auction": { + "stages": { + "entrypoint": { + "groups": [ + { + "timeout": 10, + "hook_sequence": [ + { + "module_code": "fiftyonedegrees.devicedetection", + "hook_impl_code": "fiftyone-devicedetection-entrypoint-hook" + } + ] + } + ] + }, + "raw_auction_request": { + "groups": [ + { + "timeout": 10, + "hook_sequence": [ + { + "module_code": "fiftyonedegrees.devicedetection", + "hook_impl_code": "fiftyone-devicedetection-raw-auction-request-hook" + } + ] + } + ] + } + } + } + } + } + } + } +} +``` + +The same config in YAML format: +```yaml +hooks: + enabled: true + modules: + fiftyonedegrees: + devicedetection: + enabled: true + make_temp_copy: true + data_file: + path: path/to/51Degrees-LiteV4.1.hash + update: + auto: true + url: "" + polling_interval: 1800 + license_key: "" + product: V4Enterprise + watch_file_system: 'true' + host_execution_plan: + endpoints: + "/openrtb2/auction": + stages: + entrypoint: + groups: + - timeout: 10 + hook_sequence: + - module_code: fiftyonedegrees.devicedetection + hook_impl_code: fiftyone-devicedetection-entrypoint-hook + raw_auction_request: + groups: + - timeout: 10 + hook_sequence: + - module_code: fiftyonedegrees.devicedetection + hook_impl_code: fiftyone-devicedetection-raw-auction-request-hook +``` + +Note that at a minimum (besides adding to the host_execution_plan) you need to enable the module and specify a path to the data file in the configuration. +Sample module enablement configuration in JSON and YAML formats: + +```json +{ + "modules": { + "fiftyonedegrees": { + "devicedetection": { + "enabled": true, + "data_file": { + "path": "path/to/51Degrees-LiteV4.1.hash" + } + } + } + } +} +``` + +```yaml + modules: + fiftyonedegrees: + devicedetection: + enabled: true + data_file: + path: "/path/to/51Degrees-LiteV4.1.hash" +``` + +## Module Configuration Parameters + +The parameter names are specified with full path using dot-notation. F.e. `section_name` .`sub_section` .`param_name` would result in this nesting in the JSON configuration: + +```json +{ + "section_name": { + "sub_section": { + "param_name": "param-value" + } + } +} +``` + +| Param Name | Required| Type | Default value | Description | +|:-------|:------|:------|:------|:---------------------------------------| +| `account_filter` .`allow_list` | No | list of strings | [] (empty list) | A list of account IDs that are allowed to use this module - only relevant if enabled globally for the host. If empty, all accounts are allowed. Full-string match is performed (whitespaces and capitalization matter). | +| `data_file` .`path` | **Yes** | string | null |The full path to the device detection data file. Sample file can be downloaded from [data repo on GitHub](https://github.com/51Degrees/device-detection-data/blob/main/51Degrees-LiteV4.1.hash), or get an Enterprise data file [here](https://51degrees.com/pricing). | +| `data_file` .`make_temp_copy` | No | boolean | true | If true, the engine will create a temporary copy of the data file rather than using the data file directly. | +| `data_file` .`update` .`auto` | No | boolean | true | If enabled, the engine will periodically (at predefined time intervals - see `polling-interval` parameter) check if new data file is available. When the new data file is available engine downloads it and switches to it for device detection. If custom `url` is not specified `license_key` param is required. | +| `data_file` .`update` .`on_startup` | No | boolean | false | If enabled, engine will check for the updated data file right away without waiting for the defined time interval. | +| `data_file` .`update` .`url` | No | string | null | Configure the engine to check the specified URL for the availability of the updated data file. If not specified the [51Degrees distributor service](https://51degrees.com/documentation/4.4/_info__distributor.html) URL will be used, which requires a License Key. | +| `data_file` .`update` .`license_key` | No | string | null | Required if `auto` is true and custom `url` is not specified. Allows to download the data file from the [51Degrees distributor service](https://51degrees.com/documentation/4.4/_info__distributor.html). | +| `data_file` .`update` .`watch_file_system` | No | boolean | true | If enabled the engine will watch the data file path for any changes, and automatically reload the data file from disk once it is updated. | +| `data_file` .`update` .`polling_interval` | No | int | 1800 | The time interval in seconds between consequent attempts to download an updated data file. Default = 1800 seconds = 30 minutes. | +| `data_file` .`update` .`product`| No | string | `V4Enterprise` | Set the Product used when checking for new device detection data files. A Product is exclusive to the 51Degrees paid service. Please see options [here](https://51degrees.com/documentation/_info__distributor.html). | +| `performance` .`profile` | No | string | `Balanced` | `performance.*` parameters are related to the tradeoffs between speed of device detection and RAM consumption or accuracy. `profile` dictates the proportion between the use of the RAM (the more RAM used - the faster is the device detection) and reads from disk (less RAM but slower device detection). Must be one of: `LowMemory`, `MaxPerformance`, `HighPerformance`, `Balanced`, `BalancedTemp`, `InMemory`. Defaults to `Balanced`. | +| `performance` .`concurrency` | No | int | 10 | Specify the expected number of concurrent operations that engine does. This sets the concurrency of the internal caches to avoid excessive locking. Default: 10. | +| `performance` .`difference` | No | int | 0 | Set the maximum difference to allow when processing evidence (HTTP headers). The meaning is the difference in hash value between the hash that was found, and the hash that is being searched for. By default this is 0. For more information see [51Degrees documentation](https://51degrees.com/documentation/_device_detection__hash.html). | +| `performance` .`drift` | No | int | 0 | Set the maximum drift to allow when matching hashes. If the drift is exceeded, the result is considered invalid and values will not be returned. By default this is 0. For more information see [51Degrees documentation](https://51degrees.com/documentation/_device_detection__hash.html). | +| `performance` .`allow_unmatched` | No | boolean | false | If set to false, a non-matching evidence will result in properties with no values set. If set to true, a non-matching evidence will cause the 'default profiles' to be returned. This means that properties will always have values (i.e. no need to check .hasValue) but some may be inaccurate. By default, this is false. | + +## Running the demo + +1. Download dependencies: +```bash +go mod download +``` + +2. Replace the original config file `pbs.json` (placed in the repository root or in `/etc/config`) with the sample [config file](sample/pbs.json): +``` +cp modules/fiftyonedegrees/devicedetection/sample/pbs.json pbs.json +``` + +3. Download `51Degrees-LiteV4.1.hash` from [[GitHub](https://github.com/51Degrees/device-detection-data/blob/main/51Degrees-LiteV4.1.hash)] and put it in the project root directory. + +```bash +curl -o 51Degrees-LiteV4.1.hash -L https://github.com/51Degrees/device-detection-data/raw/main/51Degrees-LiteV4.1.hash +``` + +4. Create a directory for sample stored requests (needed for the server to run): +```bash +mkdir -p sample/stored +``` + +5. Start the server: +```bash +go run main.go +``` + +6. Run sample request: +```bash +curl \ +--header "Content-Type: application/json" \ +http://localhost:8000/openrtb2/auction \ +--data @modules/fiftyonedegrees/devicedetection/sample/request_data.json +``` + +7. Observe the `device` object get enriched with `devicetype`, `os`, `osv`, `w`, `h` and `ext.fiftyonedegrees_deviceId`. + +## Maintainer contacts + +Any suggestions or questions can be directed to [support@51degrees.com](support@51degrees.com) e-mail. + +Or just open new [issue](https://github.com/prebid/prebid-server/issues/new) or [pull request](https://github.com/prebid/prebid-server/pulls) in this repository. diff --git a/modules/fiftyonedegrees/devicedetection/account_info_extractor.go b/modules/fiftyonedegrees/devicedetection/account_info_extractor.go new file mode 100644 index 00000000000..2a5168cfe0c --- /dev/null +++ b/modules/fiftyonedegrees/devicedetection/account_info_extractor.go @@ -0,0 +1,37 @@ +package devicedetection + +import ( + "github.com/tidwall/gjson" +) + +type accountInfo struct { + Id string +} + +type accountInfoExtractor struct{} + +func newAccountInfoExtractor() accountInfoExtractor { + return accountInfoExtractor{} +} + +// extract extracts the account information from the payload +// The account information is extracted from the publisher id or site publisher id +func (x accountInfoExtractor) extract(payload []byte) *accountInfo { + if payload == nil { + return nil + } + + publisherResult := gjson.GetBytes(payload, "app.publisher.id") + if publisherResult.Exists() { + return &accountInfo{ + Id: publisherResult.String(), + } + } + publisherResult = gjson.GetBytes(payload, "site.publisher.id") + if publisherResult.Exists() { + return &accountInfo{ + Id: publisherResult.String(), + } + } + return nil +} diff --git a/modules/fiftyonedegrees/devicedetection/account_info_extractor_test.go b/modules/fiftyonedegrees/devicedetection/account_info_extractor_test.go new file mode 100644 index 00000000000..2d32f7915b5 --- /dev/null +++ b/modules/fiftyonedegrees/devicedetection/account_info_extractor_test.go @@ -0,0 +1,74 @@ +package devicedetection + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +var ( + siteRequestPayload = []byte(` + { + "site": { + "publisher": { + "id": "p-bid-config-test-005" + } + } + } + `) + + mobileRequestPayload = []byte(` + { + "app": { + "publisher": { + "id": "p-bid-config-test-005" + } + } + } + `) + + emptyPayload = []byte(`{}`) +) + +func TestPublisherIdExtraction(t *testing.T) { + tests := []struct { + name string + payload []byte + expected string + expectNil bool + }{ + { + name: "SiteRequest", + payload: siteRequestPayload, + expected: "p-bid-config-test-005", + }, + { + name: "MobileRequest", + payload: mobileRequestPayload, + expected: "p-bid-config-test-005", + }, + { + name: "EmptyPublisherId", + payload: emptyPayload, + expectNil: true, + }, + { + name: "EmptyPayload", + payload: nil, + expectNil: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + extractor := newAccountInfoExtractor() + accountInfo := extractor.extract(tt.payload) + + if tt.expectNil { + assert.Nil(t, accountInfo) + } else { + assert.Equal(t, tt.expected, accountInfo.Id) + } + }) + } +} diff --git a/modules/fiftyonedegrees/devicedetection/account_validator.go b/modules/fiftyonedegrees/devicedetection/account_validator.go new file mode 100644 index 00000000000..fdff92531a7 --- /dev/null +++ b/modules/fiftyonedegrees/devicedetection/account_validator.go @@ -0,0 +1,28 @@ +package devicedetection + +import "slices" + +// defaultAccountValidator is a struct that contains an accountInfoExtractor +// and is used to validate if an account is allowed +type defaultAccountValidator struct { + AccountExtractor accountInfoExtractor +} + +func newAccountValidator() *defaultAccountValidator { + return &defaultAccountValidator{ + AccountExtractor: newAccountInfoExtractor(), + } +} + +func (x defaultAccountValidator) isAllowed(cfg config, req []byte) bool { + if len(cfg.AccountFilter.AllowList) == 0 { + return true + } + + accountInfo := x.AccountExtractor.extract(req) + if accountInfo != nil && slices.Contains(cfg.AccountFilter.AllowList, accountInfo.Id) { + return true + } + + return false +} diff --git a/modules/fiftyonedegrees/devicedetection/account_validator_test.go b/modules/fiftyonedegrees/devicedetection/account_validator_test.go new file mode 100644 index 00000000000..25f99e3b796 --- /dev/null +++ b/modules/fiftyonedegrees/devicedetection/account_validator_test.go @@ -0,0 +1,71 @@ +package devicedetection + +import ( + "encoding/json" + "testing" + + "github.com/prebid/openrtb/v20/openrtb2" + + "github.com/stretchr/testify/assert" +) + +func TestIsAllowed(t *testing.T) { + tests := []struct { + name string + allowList []string + expectedResult bool + }{ + { + name: "allowed", + allowList: []string{"1001"}, + expectedResult: true, + }, + { + name: "empty", + allowList: []string{}, + expectedResult: true, + }, + { + name: "disallowed", + allowList: []string{"1002"}, + expectedResult: false, + }, + { + name: "allow_list_is_nil", + allowList: nil, + expectedResult: true, + }, + { + name: "allow_list_contains_multiple", + allowList: []string{"1000", "1001", "1002"}, + expectedResult: true, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + validator := newAccountValidator() + cfg := config{ + AccountFilter: accountFilter{AllowList: test.allowList}, + } + + res := validator.isAllowed( + cfg, toBytes( + &openrtb2.BidRequest{ + App: &openrtb2.App{ + Publisher: &openrtb2.Publisher{ + ID: "1001", + }, + }, + }, + ), + ) + assert.Equal(t, test.expectedResult, res) + }) + } +} + +func toBytes(v interface{}) []byte { + res, _ := json.Marshal(v) + return res +} diff --git a/modules/fiftyonedegrees/devicedetection/config.go b/modules/fiftyonedegrees/devicedetection/config.go new file mode 100644 index 00000000000..a5c302bcff5 --- /dev/null +++ b/modules/fiftyonedegrees/devicedetection/config.go @@ -0,0 +1,80 @@ +package devicedetection + +import ( + "encoding/json" + "os" + + "github.com/51Degrees/device-detection-go/v4/dd" + "github.com/pkg/errors" + + "github.com/prebid/prebid-server/v3/util/jsonutil" +) + +type config struct { + DataFile dataFile `json:"data_file"` + AccountFilter accountFilter `json:"account_filter"` + Performance performance `json:"performance"` +} + +type dataFile struct { + Path string `json:"path"` + Update dataFileUpdate `json:"update"` + MakeTempCopy *bool `json:"make_temp_copy"` +} + +type dataFileUpdate struct { + Auto bool `json:"auto"` + Url string `json:"url"` + License string `json:"license_key"` + PollingInterval int `json:"polling_interval"` + Product string `json:"product"` + WatchFileSystem *bool `json:"watch_file_system"` + OnStartup bool `json:"on_startup"` +} + +type accountFilter struct { + AllowList []string `json:"allow_list"` +} + +type performance struct { + Profile string `json:"profile"` + Concurrency *int `json:"concurrency"` + Difference *int `json:"difference"` + AllowUnmatched *bool `json:"allow_unmatched"` + Drift *int `json:"drift"` +} + +var performanceProfileMap = map[string]dd.PerformanceProfile{ + "Default": dd.Default, + "LowMemory": dd.LowMemory, + "BalancedTemp": dd.BalancedTemp, + "Balanced": dd.Balanced, + "HighPerformance": dd.HighPerformance, + "InMemory": dd.InMemory, +} + +func (c *config) getPerformanceProfile() dd.PerformanceProfile { + mappedResult, ok := performanceProfileMap[c.Performance.Profile] + if !ok { + return dd.Default + } + + return mappedResult +} + +func parseConfig(data json.RawMessage) (config, error) { + var cfg config + if err := jsonutil.UnmarshalValid(data, &cfg); err != nil { + return cfg, errors.Wrap(err, "failed to parse config") + } + return cfg, nil +} + +func validateConfig(cfg config) error { + _, err := os.Stat(cfg.DataFile.Path) + if err != nil { + return errors.Wrap(err, "error opening hash file path") + } + + return nil +} diff --git a/modules/fiftyonedegrees/devicedetection/config_test.go b/modules/fiftyonedegrees/devicedetection/config_test.go new file mode 100644 index 00000000000..e2478d82b7d --- /dev/null +++ b/modules/fiftyonedegrees/devicedetection/config_test.go @@ -0,0 +1,119 @@ +package devicedetection + +import ( + "os" + "testing" + + "github.com/51Degrees/device-detection-go/v4/dd" + "github.com/stretchr/testify/assert" +) + +func TestParseConfig(t *testing.T) { + cfgRaw := []byte(`{ + "enabled": true, + "data_file": { + "path": "path/to/51Degrees-LiteV4.1.hash", + "update": { + "auto": true, + "url": "https://my.datafile.com/datafile.gz", + "polling_interval": 3600, + "license_key": "your_license_key", + "product": "V4Enterprise", + "on_startup": true + } + }, + "account_filter": {"allow_list": ["123"]}, + "performance": { + "profile": "default", + "concurrency": 1, + "difference": 1, + "allow_unmatched": true, + "drift": 1 + } + }`) + + cfg, err := parseConfig(cfgRaw) + + assert.NoError(t, err) + + assert.Equal(t, cfg.DataFile.Path, "path/to/51Degrees-LiteV4.1.hash") + assert.True(t, cfg.DataFile.Update.Auto) + assert.Equal(t, cfg.DataFile.Update.Url, "https://my.datafile.com/datafile.gz") + assert.Equal(t, cfg.DataFile.Update.PollingInterval, 3600) + assert.Equal(t, cfg.DataFile.Update.License, "your_license_key") + assert.Equal(t, cfg.DataFile.Update.Product, "V4Enterprise") + assert.True(t, cfg.DataFile.Update.OnStartup) + assert.Equal(t, cfg.AccountFilter.AllowList, []string{"123"}) + assert.Equal(t, cfg.Performance.Profile, "default") + assert.Equal(t, *cfg.Performance.Concurrency, 1) + assert.Equal(t, *cfg.Performance.Difference, 1) + assert.True(t, *cfg.Performance.AllowUnmatched) + assert.Equal(t, *cfg.Performance.Drift, 1) + assert.Equal(t, cfg.getPerformanceProfile(), dd.Default) +} + +func TestValidateConfig(t *testing.T) { + file, err := os.Create("test-validate-config.hash") + if err != nil { + t.Errorf("Failed to create file: %v", err) + } + defer file.Close() + defer os.Remove("test-validate-config.hash") + + cfgRaw := []byte(`{ + "enabled": true, + "data_file": { + "path": "test-validate-config.hash", + "update": { + "auto": true, + "url": "https://my.datafile.com/datafile.gz", + "polling_interval": 3600, + "licence_key": "your_licence_key", + "product": "V4Enterprise" + } + }, + "account_filter": {"allow_list": ["123"]}, + "performance": { + "profile": "default", + "concurrency": 1, + "difference": 1, + "allow_unmatched": true, + "drift": 1 + } + }`) + + cfg, err := parseConfig(cfgRaw) + assert.NoError(t, err) + + err = validateConfig(cfg) + assert.NoError(t, err) + +} + +func TestInvalidPerformanceProfile(t *testing.T) { + cfgRaw := []byte(`{ + "enabled": true, + "data_file": { + "path": "test-validate-config.hash", + "update": { + "auto": true, + "url": "https://my.datafile.com/datafile.gz", + "polling_interval": 3600, + "licence_key": "your_licence_key", + "product": "V4Enterprise" + } + }, + "account_filter": {"allow_list": ["123"]}, + "performance": { + "profile": "123", + "concurrency": 1, + "difference": 1, + "allow_unmatched": true, + "drift": 1 + } + }`) + cfg, err := parseConfig(cfgRaw) + assert.NoError(t, err) + + assert.Equal(t, cfg.getPerformanceProfile(), dd.Default) +} diff --git a/modules/fiftyonedegrees/devicedetection/context.go b/modules/fiftyonedegrees/devicedetection/context.go new file mode 100644 index 00000000000..3c10dd2f393 --- /dev/null +++ b/modules/fiftyonedegrees/devicedetection/context.go @@ -0,0 +1,8 @@ +package devicedetection + +// Context keys for device detection +const ( + evidenceFromHeadersCtxKey = "evidence_from_headers" + evidenceFromSuaCtxKey = "evidence_from_sua" + ddEnabledCtxKey = "dd_enabled" +) diff --git a/modules/fiftyonedegrees/devicedetection/device_detector.go b/modules/fiftyonedegrees/devicedetection/device_detector.go new file mode 100644 index 00000000000..8369d343d34 --- /dev/null +++ b/modules/fiftyonedegrees/devicedetection/device_detector.go @@ -0,0 +1,157 @@ +package devicedetection + +import ( + "github.com/51Degrees/device-detection-go/v4/dd" + "github.com/51Degrees/device-detection-go/v4/onpremise" + "github.com/pkg/errors" +) + +type engine interface { + Process(evidences []onpremise.Evidence) (*dd.ResultsHash, error) + GetHttpHeaderKeys() []dd.EvidenceKey +} + +type extractor interface { + extract(results Results, ua string) (*deviceInfo, error) +} + +type defaultDeviceDetector struct { + cfg *dd.ConfigHash + deviceInfoExtractor extractor + engine engine +} + +func newDeviceDetector(cfg *dd.ConfigHash, moduleConfig *config) (*defaultDeviceDetector, error) { + engineOptions := buildEngineOptions(moduleConfig, cfg) + + ddEngine, err := onpremise.New( + engineOptions..., + ) + if err != nil { + return nil, errors.Wrap(err, "Failed to create onpremise engine.") + } + + deviceDetector := &defaultDeviceDetector{ + engine: ddEngine, + cfg: cfg, + deviceInfoExtractor: newDeviceInfoExtractor(), + } + + return deviceDetector, nil +} + +func buildEngineOptions(moduleConfig *config, configHash *dd.ConfigHash) []onpremise.EngineOptions { + options := []onpremise.EngineOptions{ + onpremise.WithDataFile(moduleConfig.DataFile.Path), + } + + options = append( + options, + onpremise.WithProperties([]string{ + "HardwareVendor", + "HardwareName", + "DeviceType", + "PlatformVendor", + "PlatformName", + "PlatformVersion", + "BrowserVendor", + "BrowserName", + "BrowserVersion", + "ScreenPixelsWidth", + "ScreenPixelsHeight", + "PixelRatio", + "Javascript", + "GeoLocation", + "HardwareModel", + "HardwareFamily", + "HardwareModelVariants", + "ScreenInchesHeight", + "IsCrawler", + }), + ) + + options = append( + options, + onpremise.WithConfigHash(configHash), + ) + + if moduleConfig.DataFile.MakeTempCopy != nil { + options = append( + options, + onpremise.WithTempDataCopy(*moduleConfig.DataFile.MakeTempCopy), + ) + } + + dataUpdateOptions := []onpremise.EngineOptions{ + onpremise.WithAutoUpdate(moduleConfig.DataFile.Update.Auto), + } + + if moduleConfig.DataFile.Update.Url != "" { + dataUpdateOptions = append( + dataUpdateOptions, + onpremise.WithDataUpdateUrl( + moduleConfig.DataFile.Update.Url, + ), + ) + } + + if moduleConfig.DataFile.Update.PollingInterval > 0 { + dataUpdateOptions = append( + dataUpdateOptions, + onpremise.WithPollingInterval( + moduleConfig.DataFile.Update.PollingInterval, + ), + ) + } + + if moduleConfig.DataFile.Update.License != "" { + dataUpdateOptions = append( + dataUpdateOptions, + onpremise.WithLicenseKey(moduleConfig.DataFile.Update.License), + ) + } + + if moduleConfig.DataFile.Update.Product != "" { + dataUpdateOptions = append( + dataUpdateOptions, + onpremise.WithProduct(moduleConfig.DataFile.Update.Product), + ) + } + + if moduleConfig.DataFile.Update.WatchFileSystem != nil { + dataUpdateOptions = append( + dataUpdateOptions, + onpremise.WithFileWatch( + *moduleConfig.DataFile.Update.WatchFileSystem, + ), + ) + } + + dataUpdateOptions = append( + dataUpdateOptions, + onpremise.WithUpdateOnStart(moduleConfig.DataFile.Update.OnStartup), + ) + + options = append( + options, + dataUpdateOptions..., + ) + + return options +} + +func (x defaultDeviceDetector) getSupportedHeaders() []dd.EvidenceKey { + return x.engine.GetHttpHeaderKeys() +} + +func (x defaultDeviceDetector) getDeviceInfo(evidence []onpremise.Evidence, ua string) (*deviceInfo, error) { + results, err := x.engine.Process(evidence) + if err != nil { + return nil, errors.Wrap(err, "Failed to process evidence") + } + defer results.Free() + + deviceInfo, err := x.deviceInfoExtractor.extract(results, ua) + + return deviceInfo, err +} diff --git a/modules/fiftyonedegrees/devicedetection/device_detector_test.go b/modules/fiftyonedegrees/devicedetection/device_detector_test.go new file mode 100644 index 00000000000..84d6ab28cc0 --- /dev/null +++ b/modules/fiftyonedegrees/devicedetection/device_detector_test.go @@ -0,0 +1,190 @@ +package devicedetection + +import ( + "fmt" + "testing" + + "github.com/51Degrees/device-detection-go/v4/dd" + "github.com/51Degrees/device-detection-go/v4/onpremise" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" +) + +func TestBuildEngineOptions(t *testing.T) { + cases := []struct { + cfgRaw []byte + length int + }{ + { + cfgRaw: []byte(`{ + "enabled": true, + "data_file": { + "path": "path/to/51Degrees-LiteV4.1.hash", + "update": { + "auto": true, + "url": "https://my.datafile.com/datafile.gz", + "polling_interval": 3600, + "license_key": "your_license_key", + "product": "V4Enterprise", + "watch_file_system": true, + "on_startup": true + }, + "make_temp_copy": true + }, + "account_filter": {"allow_list": ["123"]}, + "performance": { + "profile": "default", + "concurrency": 1, + "difference": 1, + "allow_unmatched": true, + "drift": 1 + } + }`), + length: 11, + // data_file.path, data_file.update.auto:true, url, polling_interval, license_key, product, confighash, properties + // data_file.update.on_startup:true, data_file.update.watch_file_system:true, data_file.make_temp_copy:true + }, + { + cfgRaw: []byte(`{ + "enabled": true, + "data_file": { + "path": "path/to/51Degrees-LiteV4.1.hash" + }, + "account_filter": {"allow_list": ["123"]}, + "performance": { + "profile": "default", + "concurrency": 1, + "difference": 1, + "allow_unmatched": true, + "drift": 1 + } + }`), + length: 5, // data_file.update.auto:false, data_file.path, confighash, properties, data_file.update.on_startup:false + }, + } + + for _, c := range cases { + cfg, err := parseConfig(c.cfgRaw) + assert.NoError(t, err) + configHash := configHashFromConfig(&cfg) + options := buildEngineOptions(&cfg, configHash) + assert.Equal(t, c.length, len(options)) + } +} + +type engineMock struct { + mock.Mock +} + +func (e *engineMock) Process(evidences []onpremise.Evidence) (*dd.ResultsHash, error) { + args := e.Called(evidences) + res := args.Get(0) + if res == nil { + return nil, args.Error(1) + } + + return res.(*dd.ResultsHash), args.Error(1) +} + +func (e *engineMock) GetHttpHeaderKeys() []dd.EvidenceKey { + args := e.Called() + return args.Get(0).([]dd.EvidenceKey) +} + +type extractorMock struct { + mock.Mock +} + +func (e *extractorMock) extract(results Results, ua string) (*deviceInfo, error) { + args := e.Called(results, ua) + return args.Get(0).(*deviceInfo), args.Error(1) +} + +func TestGetDeviceInfo(t *testing.T) { + tests := []struct { + name string + engineResponse *dd.ResultsHash + engineError error + expectedResult *deviceInfo + expectedError string + }{ + { + name: "Success_path", + engineResponse: &dd.ResultsHash{}, + engineError: nil, + expectedResult: &deviceInfo{ + DeviceId: "123", + }, + expectedError: "", + }, + { + name: "Error_path", + engineResponse: nil, + engineError: fmt.Errorf("error"), + expectedResult: nil, + expectedError: "Failed to process evidence: error", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + extractorM := &extractorMock{} + extractorM.On("extract", mock.Anything, mock.Anything).Return( + &deviceInfo{ + DeviceId: "123", + }, nil, + ) + + engineM := &engineMock{} + engineM.On("Process", mock.Anything).Return( + tt.engineResponse, tt.engineError, + ) + + deviceDetector := defaultDeviceDetector{ + cfg: nil, + deviceInfoExtractor: extractorM, + engine: engineM, + } + + result, err := deviceDetector.getDeviceInfo( + []onpremise.Evidence{{ + Prefix: dd.HttpEvidenceQuery, + Key: "key", + Value: "val", + }}, "ua", + ) + + if tt.expectedError == "" { + assert.NoError(t, err) + assert.NotNil(t, result) + assert.Equal(t, tt.expectedResult.DeviceId, result.DeviceId) + } else { + assert.Errorf(t, err, tt.expectedError) + assert.Nil(t, result) + } + }) + } +} + +func TestGetSupportedHeaders(t *testing.T) { + engineM := &engineMock{} + + engineM.On("GetHttpHeaderKeys").Return( + []dd.EvidenceKey{{ + Key: "key", + Prefix: dd.HttpEvidenceQuery, + }}, + ) + + deviceDetector := defaultDeviceDetector{ + cfg: nil, + deviceInfoExtractor: nil, + engine: engineM, + } + + result := deviceDetector.getSupportedHeaders() + assert.NotNil(t, result) + assert.Equal(t, len(result), 1) + assert.Equal(t, result[0].Key, "key") + +} diff --git a/modules/fiftyonedegrees/devicedetection/device_info_extractor.go b/modules/fiftyonedegrees/devicedetection/device_info_extractor.go new file mode 100644 index 00000000000..1c913e21696 --- /dev/null +++ b/modules/fiftyonedegrees/devicedetection/device_info_extractor.go @@ -0,0 +1,121 @@ +package devicedetection + +import ( + "strconv" + + "github.com/golang/glog" + "github.com/pkg/errors" +) + +// deviceInfoExtractor is a struct that contains the methods to extract device information +// from the results of the device detection +type deviceInfoExtractor struct{} + +func newDeviceInfoExtractor() deviceInfoExtractor { + return deviceInfoExtractor{} +} + +type Results interface { + ValuesString(string, string) (string, error) + HasValues(string) (bool, error) + DeviceId() (string, error) +} + +type deviceInfoProperty string + +const ( + deviceInfoHardwareVendor deviceInfoProperty = "HardwareVendor" + deviceInfoHardwareName deviceInfoProperty = "HardwareName" + deviceInfoDeviceType deviceInfoProperty = "DeviceType" + deviceInfoPlatformVendor deviceInfoProperty = "PlatformVendor" + deviceInfoPlatformName deviceInfoProperty = "PlatformName" + deviceInfoPlatformVersion deviceInfoProperty = "PlatformVersion" + deviceInfoBrowserVendor deviceInfoProperty = "BrowserVendor" + deviceInfoBrowserName deviceInfoProperty = "BrowserName" + deviceInfoBrowserVersion deviceInfoProperty = "BrowserVersion" + deviceInfoScreenPixelsWidth deviceInfoProperty = "ScreenPixelsWidth" + deviceInfoScreenPixelsHeight deviceInfoProperty = "ScreenPixelsHeight" + deviceInfoPixelRatio deviceInfoProperty = "PixelRatio" + deviceInfoJavascript deviceInfoProperty = "Javascript" + deviceInfoGeoLocation deviceInfoProperty = "GeoLocation" + deviceInfoHardwareModel deviceInfoProperty = "HardwareModel" + deviceInfoHardwareFamily deviceInfoProperty = "HardwareFamily" + deviceInfoHardwareModelVariants deviceInfoProperty = "HardwareModelVariants" + deviceInfoScreenInchesHeight deviceInfoProperty = "ScreenInchesHeight" +) + +func (x deviceInfoExtractor) extract(results Results, ua string) (*deviceInfo, error) { + hardwareVendor := x.getValue(results, deviceInfoHardwareVendor) + hardwareName := x.getValue(results, deviceInfoHardwareName) + deviceType := x.getValue(results, deviceInfoDeviceType) + platformVendor := x.getValue(results, deviceInfoPlatformVendor) + platformName := x.getValue(results, deviceInfoPlatformName) + platformVersion := x.getValue(results, deviceInfoPlatformVersion) + browserVendor := x.getValue(results, deviceInfoBrowserVendor) + browserName := x.getValue(results, deviceInfoBrowserName) + browserVersion := x.getValue(results, deviceInfoBrowserVersion) + screenPixelsWidth, _ := strconv.ParseInt(x.getValue(results, deviceInfoScreenPixelsWidth), 10, 64) + screenPixelsHeight, _ := strconv.ParseInt(x.getValue(results, deviceInfoScreenPixelsHeight), 10, 64) + pixelRatio, _ := strconv.ParseFloat(x.getValue(results, deviceInfoPixelRatio), 10) + javascript, _ := strconv.ParseBool(x.getValue(results, deviceInfoJavascript)) + geoLocation, _ := strconv.ParseBool(x.getValue(results, deviceInfoGeoLocation)) + deviceId, err := results.DeviceId() + if err != nil { + return nil, errors.Wrap(err, "Failed to get device id.") + } + hardwareModel := x.getValue(results, deviceInfoHardwareModel) + hardwareFamily := x.getValue(results, deviceInfoHardwareFamily) + hardwareModelVariants := x.getValue(results, deviceInfoHardwareModelVariants) + screenInchedHeight, _ := strconv.ParseFloat(x.getValue(results, deviceInfoScreenInchesHeight), 10) + + p := &deviceInfo{ + HardwareVendor: hardwareVendor, + HardwareName: hardwareName, + DeviceType: deviceType, + PlatformVendor: platformVendor, + PlatformName: platformName, + PlatformVersion: platformVersion, + BrowserVendor: browserVendor, + BrowserName: browserName, + BrowserVersion: browserVersion, + ScreenPixelsWidth: screenPixelsWidth, + ScreenPixelsHeight: screenPixelsHeight, + PixelRatio: pixelRatio, + Javascript: javascript, + GeoLocation: geoLocation, + UserAgent: ua, + DeviceId: deviceId, + HardwareModel: hardwareModel, + HardwareFamily: hardwareFamily, + HardwareModelVariants: hardwareModelVariants, + ScreenInchesHeight: screenInchedHeight, + } + + return p, nil +} + +// function getValue return a value results for a property +func (x deviceInfoExtractor) getValue(results Results, propertyName deviceInfoProperty) string { + // Get the values in string + value, err := results.ValuesString( + string(propertyName), + ",", + ) + if err != nil { + glog.Errorf("Failed to get results values string.") + return "" + } + + hasValues, err := results.HasValues(string(propertyName)) + if err != nil { + glog.Errorf("Failed to check if a matched value exists for property %s.\n", propertyName) + return "" + } + + if !hasValues { + glog.Warningf("Property %s does not have a matched value.\n", propertyName) + return "Unknown" + } + + return value +} diff --git a/modules/fiftyonedegrees/devicedetection/device_info_extractor_test.go b/modules/fiftyonedegrees/devicedetection/device_info_extractor_test.go new file mode 100644 index 00000000000..197e3928602 --- /dev/null +++ b/modules/fiftyonedegrees/devicedetection/device_info_extractor_test.go @@ -0,0 +1,130 @@ +package devicedetection + +import ( + "errors" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" +) + +type ResultsHashMock struct { + mock.Mock +} + +func (m *ResultsHashMock) DeviceId() (string, error) { + return "", nil +} + +func (m *ResultsHashMock) ValuesString(prop1 string, prop2 string) (string, error) { + args := m.Called(prop1, prop2) + return args.String(0), args.Error(1) +} + +func (m *ResultsHashMock) HasValues(prop1 string) (bool, error) { + args := m.Called(prop1) + return args.Bool(0), args.Error(1) +} + +func TestDeviceInfoExtraction(t *testing.T) { + results := &ResultsHashMock{} + + extractor := newDeviceInfoExtractor() + mockValue(results, "HardwareName", "Macbook") + mockValues(results) + + deviceInfo, _ := extractor.extract(results, "ua") + assert.NotNil(t, deviceInfo) + + assert.Equal(t, deviceInfo.HardwareName, "Macbook") + assertDeviceInfo(t, deviceInfo) +} + +func TestDeviceInfoExtractionNoProperty(t *testing.T) { + results := &ResultsHashMock{} + + extractor := newDeviceInfoExtractor() + results.Mock.On("ValuesString", "HardwareName", ",").Return("", errors.New("Error")) + results.Mock.On("HasValues", "HardwareName").Return(true, nil) + mockValues(results) + + deviceInfo, _ := extractor.extract(results, "ua") + assert.NotNil(t, deviceInfo) + + assertDeviceInfo(t, deviceInfo) + assert.Equal(t, deviceInfo.HardwareName, "") +} + +func TestDeviceInfoExtractionNoValue(t *testing.T) { + results := &ResultsHashMock{} + + extractor := newDeviceInfoExtractor() + mockValues(results) + mockValue(results, "HardwareVendor", "Apple") + + results.Mock.On("ValuesString", "HardwareName", ",").Return("Macbook", nil) + results.Mock.On("HasValues", "HardwareName").Return(false, nil) + + deviceInfo, _ := extractor.extract(results, "ua") + assert.NotNil(t, deviceInfo) + assertDeviceInfo(t, deviceInfo) + assert.Equal(t, deviceInfo.HardwareName, "Unknown") +} + +func TestDeviceInfoExtractionHasValueError(t *testing.T) { + results := &ResultsHashMock{} + + extractor := newDeviceInfoExtractor() + mockValue(results, "HardwareVendor", "Apple") + + results.Mock.On("ValuesString", "HardwareName", ",").Return("Macbook", nil) + results.Mock.On("HasValues", "HardwareName").Return(true, errors.New("error")) + + mockValues(results) + + deviceInfo, _ := extractor.extract(results, "ua") + assert.NotNil(t, deviceInfo) + assertDeviceInfo(t, deviceInfo) + assert.Equal(t, deviceInfo.HardwareName, "") +} + +func mockValues(results *ResultsHashMock) { + mockValue(results, "HardwareVendor", "Apple") + mockValue(results, "DeviceType", "Desctop") + mockValue(results, "PlatformVendor", "Apple") + mockValue(results, "PlatformName", "MacOs") + mockValue(results, "PlatformVersion", "14") + mockValue(results, "BrowserVendor", "Google") + mockValue(results, "BrowserName", "Crome") + mockValue(results, "BrowserVersion", "12") + mockValue(results, "ScreenPixelsWidth", "1024") + mockValue(results, "ScreenPixelsHeight", "1080") + mockValue(results, "PixelRatio", "223") + mockValue(results, "Javascript", "true") + mockValue(results, "GeoLocation", "true") + mockValue(results, "HardwareModel", "Macbook") + mockValue(results, "HardwareFamily", "Macbook") + mockValue(results, "HardwareModelVariants", "Macbook") + mockValue(results, "ScreenInchesHeight", "12") +} + +func assertDeviceInfo(t *testing.T, deviceInfo *deviceInfo) { + assert.Equal(t, deviceInfo.HardwareVendor, "Apple") + assert.Equal(t, deviceInfo.DeviceType, "Desctop") + assert.Equal(t, deviceInfo.PlatformVendor, "Apple") + assert.Equal(t, deviceInfo.PlatformName, "MacOs") + assert.Equal(t, deviceInfo.PlatformVersion, "14") + assert.Equal(t, deviceInfo.BrowserVendor, "Google") + assert.Equal(t, deviceInfo.BrowserName, "Crome") + assert.Equal(t, deviceInfo.BrowserVersion, "12") + assert.Equal(t, deviceInfo.ScreenPixelsWidth, int64(1024)) + assert.Equal(t, deviceInfo.ScreenPixelsHeight, int64(1080)) + assert.Equal(t, deviceInfo.PixelRatio, float64(223)) + assert.Equal(t, deviceInfo.Javascript, true) + assert.Equal(t, deviceInfo.GeoLocation, true) +} + +func mockValue(results *ResultsHashMock, name string, value string) { + results.Mock.On("ValuesString", name, ",").Return(value, nil) + results.Mock.On("HasValues", name).Return(true, nil) +} diff --git a/modules/fiftyonedegrees/devicedetection/evidence_extractor.go b/modules/fiftyonedegrees/devicedetection/evidence_extractor.go new file mode 100644 index 00000000000..a99a921e75f --- /dev/null +++ b/modules/fiftyonedegrees/devicedetection/evidence_extractor.go @@ -0,0 +1,118 @@ +package devicedetection + +import ( + "net/http" + + "github.com/51Degrees/device-detection-go/v4/onpremise" + "github.com/pkg/errors" + + "github.com/51Degrees/device-detection-go/v4/dd" + "github.com/prebid/prebid-server/v3/hooks/hookstage" +) + +type defaultEvidenceExtractor struct { + valFromHeaders evidenceFromRequestHeadersExtractor + valFromSUA evidenceFromSUAPayloadExtractor +} + +func newEvidenceExtractor() *defaultEvidenceExtractor { + evidenceExtractor := &defaultEvidenceExtractor{ + valFromHeaders: newEvidenceFromRequestHeadersExtractor(), + valFromSUA: newEvidenceFromSUAPayloadExtractor(), + } + + return evidenceExtractor +} + +func (x *defaultEvidenceExtractor) fromHeaders(request *http.Request, httpHeaderKeys []dd.EvidenceKey) []stringEvidence { + return x.valFromHeaders.extract(request, httpHeaderKeys) +} + +func (x *defaultEvidenceExtractor) fromSuaPayload(payload []byte) []stringEvidence { + return x.valFromSUA.extract(payload) +} + +// merge merges two slices of stringEvidence into one slice of stringEvidence +func merge(val1, val2 []stringEvidence) []stringEvidence { + evidenceMap := make(map[string]stringEvidence) + for _, e := range val1 { + evidenceMap[e.Key] = e + } + + for _, e := range val2 { + _, exists := evidenceMap[e.Key] + if !exists { + evidenceMap[e.Key] = e + } + } + + evidence := make([]stringEvidence, 0) + + for _, e := range evidenceMap { + evidence = append(evidence, e) + } + + return evidence +} + +func (x *defaultEvidenceExtractor) extract(ctx hookstage.ModuleContext) ([]onpremise.Evidence, string, error) { + if ctx == nil { + return nil, "", errors.New("context is nil") + } + + suaStrings, err := x.getEvidenceStrings(ctx[evidenceFromSuaCtxKey]) + if err != nil { + return nil, "", errors.Wrap(err, "error extracting sua evidence") + } + headerString, err := x.getEvidenceStrings(ctx[evidenceFromHeadersCtxKey]) + if err != nil { + return nil, "", errors.Wrap(err, "error extracting header evidence") + } + + // Merge evidence from headers and SUA, sua has higher priority + evidenceStrings := merge(suaStrings, headerString) + + if len(evidenceStrings) > 0 { + userAgentE, exists := getEvidenceByKey(evidenceStrings, userAgentHeader) + if !exists { + return nil, "", errors.New("User-Agent not found") + } + + evidence := x.extractEvidenceFromStrings(evidenceStrings) + + return evidence, userAgentE.Value, nil + } + + return nil, "", nil +} + +func (x *defaultEvidenceExtractor) getEvidenceStrings(source interface{}) ([]stringEvidence, error) { + if source == nil { + return []stringEvidence{}, nil + } + + evidenceStrings, ok := source.([]stringEvidence) + if !ok { + return nil, errors.New("bad cast to []stringEvidence") + } + + return evidenceStrings, nil +} + +func (x *defaultEvidenceExtractor) extractEvidenceFromStrings(strEvidence []stringEvidence) []onpremise.Evidence { + evidenceResult := make([]onpremise.Evidence, len(strEvidence)) + for i, e := range strEvidence { + prefix := dd.HttpHeaderString + if e.Prefix == queryPrefix { + prefix = dd.HttpEvidenceQuery + } + + evidenceResult[i] = onpremise.Evidence{ + Prefix: prefix, + Key: e.Key, + Value: e.Value, + } + } + + return evidenceResult +} diff --git a/modules/fiftyonedegrees/devicedetection/evidence_extractor_test.go b/modules/fiftyonedegrees/devicedetection/evidence_extractor_test.go new file mode 100644 index 00000000000..6b2f9b3ea85 --- /dev/null +++ b/modules/fiftyonedegrees/devicedetection/evidence_extractor_test.go @@ -0,0 +1,256 @@ +package devicedetection + +import ( + "net/http" + "testing" + + "github.com/51Degrees/device-detection-go/v4/dd" + "github.com/prebid/prebid-server/v3/hooks/hookstage" + "github.com/stretchr/testify/assert" +) + +func TestFromHeaders(t *testing.T) { + extractor := newEvidenceExtractor() + + req := http.Request{ + Header: make(map[string][]string), + } + req.Header.Add("header", "Value") + req.Header.Add("Sec-CH-UA-Full-Version-List", "Chrome;12") + evidenceKeys := []dd.EvidenceKey{ + { + Prefix: dd.EvidencePrefix(10), + Key: "header", + }, + { + Prefix: dd.EvidencePrefix(10), + Key: "Sec-CH-UA-Full-Version-List", + }, + } + + evidence := extractor.fromHeaders(&req, evidenceKeys) + + assert.NotNil(t, evidence) + assert.NotEmpty(t, evidence) + assert.Equal(t, evidence[0].Value, "Value") + assert.Equal(t, evidence[0].Key, "header") + assert.Equal(t, evidence[1].Value, "Chrome;12") + assert.Equal(t, evidence[1].Key, "Sec-CH-UA-Full-Version-List") +} + +func TestFromSuaPayload(t *testing.T) { + tests := []struct { + name string + payload []byte + evidenceSize int + evidenceKeyOrder int + expectedKey string + expectedValue string + }{ + { + name: "from_SUA_tag", + payload: []byte(`{ + "device": { + "sua": { + "browsers": [ + { + "brand": "Google Chrome", + "version": ["121", "0", "6167", "184"] + } + ], + "platform": { + "brand": "macOS", + "version": ["14", "0", "0"] + }, + "architecture": "arm" + } + } + }`), + evidenceSize: 4, + evidenceKeyOrder: 0, + expectedKey: "Sec-Ch-Ua-Arch", + expectedValue: "arm", + }, + { + name: "from_UA_headers", + payload: []byte(`{ + "device": { + "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148", + "sua": { + "architecture": "arm" + } + } + }`), + evidenceSize: 2, + evidenceKeyOrder: 1, + expectedKey: "Sec-Ch-Ua-Arch", + expectedValue: "arm", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + extractor := newEvidenceExtractor() + + evidence := extractor.fromSuaPayload(tt.payload) + + assert.NotNil(t, evidence) + assert.NotEmpty(t, evidence) + assert.Equal(t, len(evidence), tt.evidenceSize) + assert.Equal(t, evidence[tt.evidenceKeyOrder].Key, tt.expectedKey) + assert.Equal(t, evidence[tt.evidenceKeyOrder].Value, tt.expectedValue) + }) + } +} + +func TestExtract(t *testing.T) { + uaEvidence1 := stringEvidence{ + Prefix: "ua1", + Key: userAgentHeader, + Value: "uav1", + } + uaEvidence2 := stringEvidence{ + Prefix: "ua2", + Key: userAgentHeader, + Value: "uav2", + } + evidence1 := stringEvidence{ + Prefix: "e1", + Key: "k1", + Value: "v1", + } + emptyEvidence := stringEvidence{ + Prefix: "empty", + Key: "e1", + Value: "", + } + + tests := []struct { + name string + ctx hookstage.ModuleContext + wantEvidenceCount int + wantUserAgent string + wantError bool + }{ + { + name: "nil", + ctx: nil, + wantError: true, + }, + { + name: "empty", + ctx: hookstage.ModuleContext{ + evidenceFromSuaCtxKey: []stringEvidence{}, + evidenceFromHeadersCtxKey: []stringEvidence{}, + }, + wantEvidenceCount: 0, + wantUserAgent: "", + }, + { + name: "from_headers", + ctx: hookstage.ModuleContext{ + evidenceFromHeadersCtxKey: []stringEvidence{uaEvidence1}, + }, + wantEvidenceCount: 1, + wantUserAgent: "uav1", + }, + { + name: "from_headers_no_user_agent", + ctx: hookstage.ModuleContext{ + evidenceFromHeadersCtxKey: []stringEvidence{evidence1}, + }, + wantError: true, + }, + { + name: "from_sua", + ctx: hookstage.ModuleContext{ + evidenceFromSuaCtxKey: []stringEvidence{uaEvidence1}, + }, + wantEvidenceCount: 1, + wantUserAgent: "uav1", + }, + { + name: "from_sua_no_user_agent", + ctx: hookstage.ModuleContext{ + evidenceFromSuaCtxKey: []stringEvidence{evidence1}, + }, + wantError: true, + }, + { + name: "from_headers_error", + ctx: hookstage.ModuleContext{ + evidenceFromHeadersCtxKey: "bad value", + }, + wantError: true, + }, + { + name: "from_sua_error", + ctx: hookstage.ModuleContext{ + evidenceFromHeadersCtxKey: []stringEvidence{}, + evidenceFromSuaCtxKey: "bad value", + }, + wantError: true, + }, + { + name: "from_sua_and_headers", + ctx: hookstage.ModuleContext{ + evidenceFromHeadersCtxKey: []stringEvidence{uaEvidence1}, + evidenceFromSuaCtxKey: []stringEvidence{evidence1}, + }, + wantEvidenceCount: 2, + wantUserAgent: "uav1", + }, + { + name: "from_sua_and_headers_sua_can_overwrite_if_ua_present", + ctx: hookstage.ModuleContext{ + evidenceFromHeadersCtxKey: []stringEvidence{uaEvidence1}, + evidenceFromSuaCtxKey: []stringEvidence{uaEvidence2}, + }, + wantEvidenceCount: 1, + wantUserAgent: "uav2", + }, + { + name: "empty_string_values", + ctx: hookstage.ModuleContext{ + evidenceFromHeadersCtxKey: []stringEvidence{emptyEvidence}, + }, + wantError: true, + }, + { + name: "empty_sua_values", + ctx: hookstage.ModuleContext{ + evidenceFromSuaCtxKey: []stringEvidence{emptyEvidence}, + }, + wantError: true, + }, + { + name: "mixed_valid_and_invalid", + ctx: hookstage.ModuleContext{ + evidenceFromHeadersCtxKey: []stringEvidence{uaEvidence1}, + evidenceFromSuaCtxKey: "bad value", + }, + wantError: true, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + extractor := newEvidenceExtractor() + evidence, userAgent, err := extractor.extract(test.ctx) + + if test.wantError { + assert.Error(t, err) + assert.Nil(t, evidence) + assert.Equal(t, userAgent, "") + } else if test.wantEvidenceCount == 0 { + assert.NoError(t, err) + assert.Nil(t, evidence) + assert.Equal(t, userAgent, "") + } else { + assert.NoError(t, err) + assert.Equal(t, len(evidence), test.wantEvidenceCount) + assert.Equal(t, userAgent, test.wantUserAgent) + } + }) + } +} diff --git a/modules/fiftyonedegrees/devicedetection/fiftyone_device_types.go b/modules/fiftyonedegrees/devicedetection/fiftyone_device_types.go new file mode 100644 index 00000000000..7237698117d --- /dev/null +++ b/modules/fiftyonedegrees/devicedetection/fiftyone_device_types.go @@ -0,0 +1,77 @@ +package devicedetection + +import ( + "github.com/prebid/openrtb/v20/adcom1" +) + +type deviceTypeMap = map[deviceType]adcom1.DeviceType + +var mobileOrTabletDeviceTypes = []deviceType{ + deviceTypeMobile, + deviceTypeSmartPhone, +} + +var personalComputerDeviceTypes = []deviceType{ + deviceTypeDesktop, + deviceTypeEReader, + deviceTypeVehicleDisplay, +} + +var tvDeviceTypes = []deviceType{ + deviceTypeTv, +} + +var phoneDeviceTypes = []deviceType{ + deviceTypePhone, +} + +var tabletDeviceTypes = []deviceType{ + deviceTypeTablet, +} + +var connectedDeviceTypes = []deviceType{ + deviceTypeIoT, + deviceTypeRouter, + deviceTypeSmallScreen, + deviceTypeSmartSpeaker, + deviceTypeSmartWatch, +} + +var setTopBoxDeviceTypes = []deviceType{ + deviceTypeMediaHub, + deviceTypeConsole, +} + +var oohDeviceTypes = []deviceType{ + deviceTypeKiosk, +} + +func applyCollection(items []deviceType, value adcom1.DeviceType, mappedCollection deviceTypeMap) { + for _, item := range items { + mappedCollection[item] = value + } +} + +var deviceTypeMapCollection = deviceTypeMap{} + +func init() { + applyCollection(mobileOrTabletDeviceTypes, adcom1.DeviceMobile, deviceTypeMapCollection) + applyCollection(personalComputerDeviceTypes, adcom1.DevicePC, deviceTypeMapCollection) + applyCollection(tvDeviceTypes, adcom1.DeviceTV, deviceTypeMapCollection) + applyCollection(phoneDeviceTypes, adcom1.DevicePhone, deviceTypeMapCollection) + applyCollection(tabletDeviceTypes, adcom1.DeviceTablet, deviceTypeMapCollection) + applyCollection(connectedDeviceTypes, adcom1.DeviceConnected, deviceTypeMapCollection) + applyCollection(setTopBoxDeviceTypes, adcom1.DeviceSetTopBox, deviceTypeMapCollection) + applyCollection(oohDeviceTypes, adcom1.DeviceOOH, deviceTypeMapCollection) +} + +// fiftyOneDtToRTB converts a 51Degrees device type to an OpenRTB device type. +// If the device type is not recognized, it defaults to PC. +func fiftyOneDtToRTB(val string) adcom1.DeviceType { + id, ok := deviceTypeMapCollection[deviceType(val)] + if ok { + return id + } + + return adcom1.DevicePC +} diff --git a/modules/fiftyonedegrees/devicedetection/fiftyone_device_types_test.go b/modules/fiftyonedegrees/devicedetection/fiftyone_device_types_test.go new file mode 100644 index 00000000000..5fd0203bac8 --- /dev/null +++ b/modules/fiftyonedegrees/devicedetection/fiftyone_device_types_test.go @@ -0,0 +1,90 @@ +package devicedetection + +import ( + "testing" + + "github.com/prebid/openrtb/v20/adcom1" + "github.com/stretchr/testify/assert" +) + +func TestFiftyOneDtToRTB(t *testing.T) { + cases := []struct { + fiftyOneDt string + rtbDt adcom1.DeviceType + }{ + { + fiftyOneDt: "Phone", + rtbDt: adcom1.DevicePhone, + }, + { + fiftyOneDt: "Console", + rtbDt: adcom1.DeviceSetTopBox, + }, + { + fiftyOneDt: "Desktop", + rtbDt: adcom1.DevicePC, + }, + { + fiftyOneDt: "EReader", + rtbDt: adcom1.DevicePC, + }, + { + fiftyOneDt: "IoT", + rtbDt: adcom1.DeviceConnected, + }, + { + fiftyOneDt: "Kiosk", + rtbDt: adcom1.DeviceOOH, + }, + { + fiftyOneDt: "MediaHub", + rtbDt: adcom1.DeviceSetTopBox, + }, + { + fiftyOneDt: "Mobile", + rtbDt: adcom1.DeviceMobile, + }, + { + fiftyOneDt: "Router", + rtbDt: adcom1.DeviceConnected, + }, + { + fiftyOneDt: "SmallScreen", + rtbDt: adcom1.DeviceConnected, + }, + { + fiftyOneDt: "SmartPhone", + rtbDt: adcom1.DeviceMobile, + }, + { + fiftyOneDt: "SmartSpeaker", + rtbDt: adcom1.DeviceConnected, + }, + { + fiftyOneDt: "SmartWatch", + rtbDt: adcom1.DeviceConnected, + }, + { + fiftyOneDt: "Tablet", + rtbDt: adcom1.DeviceTablet, + }, + { + fiftyOneDt: "Tv", + rtbDt: adcom1.DeviceTV, + }, + { + fiftyOneDt: "Vehicle Display", + rtbDt: adcom1.DevicePC, + }, + { + fiftyOneDt: "Unknown", + rtbDt: adcom1.DevicePC, + }, + } + + for _, c := range cases { + t.Run(c.fiftyOneDt, func(t *testing.T) { + assert.Equal(t, c.rtbDt, fiftyOneDtToRTB(c.fiftyOneDt)) + }) + } +} diff --git a/modules/fiftyonedegrees/devicedetection/hook_auction_entrypoint.go b/modules/fiftyonedegrees/devicedetection/hook_auction_entrypoint.go new file mode 100644 index 00000000000..7597daa8e00 --- /dev/null +++ b/modules/fiftyonedegrees/devicedetection/hook_auction_entrypoint.go @@ -0,0 +1,27 @@ +package devicedetection + +import ( + "github.com/prebid/prebid-server/v3/hooks/hookexecution" + "github.com/prebid/prebid-server/v3/hooks/hookstage" +) + +// handleAuctionEntryPointRequestHook is a hookstage.HookFunc that is used to handle the auction entrypoint request hook. +func handleAuctionEntryPointRequestHook(cfg config, payload hookstage.EntrypointPayload, deviceDetector deviceDetector, evidenceExtractor evidenceExtractor, accountValidator accountValidator) (result hookstage.HookResult[hookstage.EntrypointPayload], err error) { + // if account/domain is not allowed, return failure + if !accountValidator.isAllowed(cfg, payload.Body) { + return hookstage.HookResult[hookstage.EntrypointPayload]{}, hookexecution.NewFailure("account not allowed") + } + // fetch evidence from headers and sua + evidenceFromHeaders := evidenceExtractor.fromHeaders(payload.Request, deviceDetector.getSupportedHeaders()) + evidenceFromSua := evidenceExtractor.fromSuaPayload(payload.Body) + + // create a Module context and set the evidence from headers, evidence from sua and dd enabled flag + moduleContext := make(hookstage.ModuleContext) + moduleContext[evidenceFromHeadersCtxKey] = evidenceFromHeaders + moduleContext[evidenceFromSuaCtxKey] = evidenceFromSua + moduleContext[ddEnabledCtxKey] = true + + return hookstage.HookResult[hookstage.EntrypointPayload]{ + ModuleContext: moduleContext, + }, nil +} diff --git a/modules/fiftyonedegrees/devicedetection/hook_raw_auction_request.go b/modules/fiftyonedegrees/devicedetection/hook_raw_auction_request.go new file mode 100644 index 00000000000..88d0686905d --- /dev/null +++ b/modules/fiftyonedegrees/devicedetection/hook_raw_auction_request.go @@ -0,0 +1,173 @@ +package devicedetection + +import ( + "fmt" + "math" + + "github.com/prebid/prebid-server/v3/hooks/hookexecution" + "github.com/prebid/prebid-server/v3/hooks/hookstage" + "github.com/tidwall/gjson" + "github.com/tidwall/sjson" +) + +func handleAuctionRequestHook(ctx hookstage.ModuleInvocationContext, deviceDetector deviceDetector, evidenceExtractor evidenceExtractor) (hookstage.HookResult[hookstage.RawAuctionRequestPayload], error) { + var result hookstage.HookResult[hookstage.RawAuctionRequestPayload] + + // If the entrypoint hook was not configured, return the result without any changes + if ctx.ModuleContext == nil { + return result, hookexecution.NewFailure("entrypoint hook was not configured") + } + + result.ChangeSet.AddMutation( + func(rawPayload hookstage.RawAuctionRequestPayload) (hookstage.RawAuctionRequestPayload, error) { + evidence, ua, err := evidenceExtractor.extract(ctx.ModuleContext) + if err != nil { + return rawPayload, hookexecution.NewFailure("error extracting evidence %s", err) + } + if evidence == nil { + return rawPayload, hookexecution.NewFailure("error extracting evidence") + } + + deviceInfo, err := deviceDetector.getDeviceInfo(evidence, ua) + if err != nil { + return rawPayload, hookexecution.NewFailure("error getting device info %s", err) + } + + result, err := hydrateFields(deviceInfo, rawPayload) + if err != nil { + return rawPayload, hookexecution.NewFailure(fmt.Sprintf("error hydrating fields %s", err)) + } + + return result, nil + }, hookstage.MutationUpdate, + ) + + return result, nil +} + +// hydrateFields hydrates the fields in the raw auction request payload with the device information +func hydrateFields(fiftyOneDd *deviceInfo, payload hookstage.RawAuctionRequestPayload) (hookstage.RawAuctionRequestPayload, error) { + devicePayload := gjson.GetBytes(payload, "device") + dPV := devicePayload.Value() + if dPV == nil { + return payload, nil + } + + deviceObject := dPV.(map[string]any) + deviceObject = setMissingFields(deviceObject, fiftyOneDd) + deviceObject = signDeviceData(deviceObject, fiftyOneDd) + + return mergeDeviceIntoPayload(payload, deviceObject) +} + +// setMissingFields sets fields such as ["devicetype", "ua", "make", "os", "osv", "h", "w", "pxratio", "js", "geoFetch", "model", "ppi"] +// if they are not already present in the device object +func setMissingFields(deviceObj map[string]any, fiftyOneDd *deviceInfo) map[string]any { + optionalFields := map[string]func() any{ + "devicetype": func() any { + return fiftyOneDtToRTB(fiftyOneDd.DeviceType) + }, + "ua": func() any { + if fiftyOneDd.UserAgent != ddUnknown { + return fiftyOneDd.UserAgent + } + return nil + }, + "make": func() any { + if fiftyOneDd.HardwareVendor != ddUnknown { + return fiftyOneDd.HardwareVendor + } + return nil + }, + "os": func() any { + if fiftyOneDd.PlatformName != ddUnknown { + return fiftyOneDd.PlatformName + } + return nil + }, + "osv": func() any { + if fiftyOneDd.PlatformVersion != ddUnknown { + return fiftyOneDd.PlatformVersion + } + return nil + }, + "h": func() any { + return fiftyOneDd.ScreenPixelsHeight + }, + "w": func() any { + return fiftyOneDd.ScreenPixelsWidth + }, + "pxratio": func() any { + return fiftyOneDd.PixelRatio + }, + "js": func() any { + val := 0 + if fiftyOneDd.Javascript { + val = 1 + } + return val + }, + "geoFetch": func() any { + val := 0 + if fiftyOneDd.GeoLocation { + val = 1 + } + return val + }, + "model": func() any { + newVal := fiftyOneDd.HardwareModel + if newVal == ddUnknown { + newVal = fiftyOneDd.HardwareName + } + if newVal != ddUnknown { + return newVal + } + return nil + }, + "ppi": func() any { + if fiftyOneDd.ScreenPixelsHeight > 0 && fiftyOneDd.ScreenInchesHeight > 0 { + ppi := float64(fiftyOneDd.ScreenPixelsHeight) / fiftyOneDd.ScreenInchesHeight + return int(math.Round(ppi)) + } + return nil + }, + } + + for field, valFunc := range optionalFields { + _, ok := deviceObj[field] + if !ok { + val := valFunc() + if val != nil { + deviceObj[field] = val + } + } + } + + return deviceObj +} + +// signDeviceData signs the device data with the device information in the ext map of the device object +func signDeviceData(deviceObj map[string]any, fiftyOneDd *deviceInfo) map[string]any { + extObj, ok := deviceObj["ext"] + var ext map[string]any + if ok { + ext = extObj.(map[string]any) + } else { + ext = make(map[string]any) + } + + ext["fiftyonedegrees_deviceId"] = fiftyOneDd.DeviceId + deviceObj["ext"] = ext + + return deviceObj +} + +// mergeDeviceIntoPayload merges the modified device object back into the RawAuctionRequestPayload +func mergeDeviceIntoPayload(payload hookstage.RawAuctionRequestPayload, deviceObject map[string]any) (hookstage.RawAuctionRequestPayload, error) { + newPayload, err := sjson.SetBytes(payload, "device", deviceObject) + if err != nil { + return payload, err + } + + return newPayload, nil +} diff --git a/modules/fiftyonedegrees/devicedetection/models.go b/modules/fiftyonedegrees/devicedetection/models.go new file mode 100644 index 00000000000..c58daa211fd --- /dev/null +++ b/modules/fiftyonedegrees/devicedetection/models.go @@ -0,0 +1,66 @@ +package devicedetection + +// Prefixes in literal format +const queryPrefix = "query." +const headerPrefix = "header." +const ddUnknown = "Unknown" + +// Evidence where all fields are in string format +type stringEvidence struct { + Prefix string + Key string + Value string +} + +func getEvidenceByKey(e []stringEvidence, key string) (stringEvidence, bool) { + for _, evidence := range e { + if evidence.Key == key { + return evidence, true + } + } + return stringEvidence{}, false +} + +type deviceType string + +const ( + deviceTypePhone = "Phone" + deviceTypeConsole = "Console" + deviceTypeDesktop = "Desktop" + deviceTypeEReader = "EReader" + deviceTypeIoT = "IoT" + deviceTypeKiosk = "Kiosk" + deviceTypeMediaHub = "MediaHub" + deviceTypeMobile = "Mobile" + deviceTypeRouter = "Router" + deviceTypeSmallScreen = "SmallScreen" + deviceTypeSmartPhone = "SmartPhone" + deviceTypeSmartSpeaker = "SmartSpeaker" + deviceTypeSmartWatch = "SmartWatch" + deviceTypeTablet = "Tablet" + deviceTypeTv = "Tv" + deviceTypeVehicleDisplay = "Vehicle Display" +) + +type deviceInfo struct { + HardwareVendor string + HardwareName string + DeviceType string + PlatformVendor string + PlatformName string + PlatformVersion string + BrowserVendor string + BrowserName string + BrowserVersion string + ScreenPixelsWidth int64 + ScreenPixelsHeight int64 + PixelRatio float64 + Javascript bool + GeoLocation bool + HardwareFamily string + HardwareModel string + HardwareModelVariants string + UserAgent string + DeviceId string + ScreenInchesHeight float64 +} diff --git a/modules/fiftyonedegrees/devicedetection/models_test.go b/modules/fiftyonedegrees/devicedetection/models_test.go new file mode 100644 index 00000000000..898f25f4144 --- /dev/null +++ b/modules/fiftyonedegrees/devicedetection/models_test.go @@ -0,0 +1,63 @@ +package devicedetection + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestGetEvidenceByKey(t *testing.T) { + populatedEvidence := []stringEvidence{ + {Key: "key1", Value: "value1"}, + {Key: "key2", Value: "value2"}, + {Key: "key3", Value: "value3"}, + } + + tests := []struct { + name string + evidence []stringEvidence + key string + expectEvidence stringEvidence + expectFound bool + }{ + { + name: "nil_evidence", + evidence: nil, + key: "key2", + expectEvidence: stringEvidence{}, + expectFound: false, + }, + { + name: "empty_evidence", + evidence: []stringEvidence{}, + key: "key2", + expectEvidence: stringEvidence{}, + expectFound: false, + }, + { + name: "key_found", + evidence: populatedEvidence, + key: "key2", + expectEvidence: stringEvidence{ + Key: "key2", + Value: "value2", + }, + expectFound: true, + }, + { + name: "key_not_found", + evidence: populatedEvidence, + key: "key4", + expectEvidence: stringEvidence{}, + expectFound: false, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + result, exists := getEvidenceByKey(test.evidence, test.key) + assert.Equal(t, test.expectFound, exists) + assert.Equal(t, test.expectEvidence, result) + }) + } +} diff --git a/modules/fiftyonedegrees/devicedetection/module.go b/modules/fiftyonedegrees/devicedetection/module.go new file mode 100644 index 00000000000..80eed36efda --- /dev/null +++ b/modules/fiftyonedegrees/devicedetection/module.go @@ -0,0 +1,107 @@ +package devicedetection + +import ( + "context" + "encoding/json" + "net/http" + + "github.com/51Degrees/device-detection-go/v4/dd" + "github.com/51Degrees/device-detection-go/v4/onpremise" + "github.com/pkg/errors" + "github.com/prebid/prebid-server/v3/hooks/hookstage" + "github.com/prebid/prebid-server/v3/modules/moduledeps" +) + +func configHashFromConfig(cfg *config) *dd.ConfigHash { + configHash := dd.NewConfigHash(cfg.getPerformanceProfile()) + if cfg.Performance.Concurrency != nil { + configHash.SetConcurrency(uint16(*cfg.Performance.Concurrency)) + } + + if cfg.Performance.Difference != nil { + configHash.SetDifference(int32(*cfg.Performance.Difference)) + } + + if cfg.Performance.AllowUnmatched != nil { + configHash.SetAllowUnmatched(*cfg.Performance.AllowUnmatched) + } + + if cfg.Performance.Drift != nil { + configHash.SetDrift(int32(*cfg.Performance.Drift)) + } + return configHash +} + +func Builder(rawConfig json.RawMessage, _ moduledeps.ModuleDeps) (interface{}, error) { + cfg, err := parseConfig(rawConfig) + if err != nil { + return Module{}, errors.Wrap(err, "failed to parse config") + } + + err = validateConfig(cfg) + if err != nil { + return nil, errors.Wrap(err, "invalid config") + } + + configHash := configHashFromConfig(&cfg) + + deviceDetectorImpl, err := newDeviceDetector( + configHash, + &cfg, + ) + if err != nil { + return nil, errors.Wrap(err, "failed to create device detector") + } + + return Module{ + cfg, + deviceDetectorImpl, + newEvidenceExtractor(), + newAccountValidator(), + }, + nil +} + +type Module struct { + config config + deviceDetector deviceDetector + evidenceExtractor evidenceExtractor + accountValidator accountValidator +} + +type deviceDetector interface { + getSupportedHeaders() []dd.EvidenceKey + getDeviceInfo(evidence []onpremise.Evidence, ua string) (*deviceInfo, error) +} + +type accountValidator interface { + isAllowed(cfg config, req []byte) bool +} + +type evidenceExtractor interface { + fromHeaders(request *http.Request, httpHeaderKeys []dd.EvidenceKey) []stringEvidence + fromSuaPayload(payload []byte) []stringEvidence + extract(ctx hookstage.ModuleContext) ([]onpremise.Evidence, string, error) +} + +func (m Module) HandleEntrypointHook( + _ context.Context, + _ hookstage.ModuleInvocationContext, + payload hookstage.EntrypointPayload, +) (hookstage.HookResult[hookstage.EntrypointPayload], error) { + return handleAuctionEntryPointRequestHook( + m.config, + payload, + m.deviceDetector, + m.evidenceExtractor, + m.accountValidator, + ) +} + +func (m Module) HandleRawAuctionHook( + _ context.Context, + mCtx hookstage.ModuleInvocationContext, + _ hookstage.RawAuctionRequestPayload, +) (hookstage.HookResult[hookstage.RawAuctionRequestPayload], error) { + return handleAuctionRequestHook(mCtx, m.deviceDetector, m.evidenceExtractor) +} diff --git a/modules/fiftyonedegrees/devicedetection/module_test.go b/modules/fiftyonedegrees/devicedetection/module_test.go new file mode 100644 index 00000000000..eb59d01359e --- /dev/null +++ b/modules/fiftyonedegrees/devicedetection/module_test.go @@ -0,0 +1,703 @@ +package devicedetection + +import ( + "context" + "encoding/json" + "errors" + "net/http" + "os" + "testing" + + "github.com/51Degrees/device-detection-go/v4/dd" + "github.com/51Degrees/device-detection-go/v4/onpremise" + "github.com/prebid/prebid-server/v3/hooks/hookstage" + "github.com/prebid/prebid-server/v3/modules/moduledeps" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" +) + +type mockAccValidator struct { + mock.Mock +} + +func (m *mockAccValidator) isAllowed(cfg config, req []byte) bool { + args := m.Called(cfg, req) + return args.Bool(0) +} + +type mockEvidenceExtractor struct { + mock.Mock +} + +func (m *mockEvidenceExtractor) fromHeaders(request *http.Request, httpHeaderKeys []dd.EvidenceKey) []stringEvidence { + args := m.Called(request, httpHeaderKeys) + + return args.Get(0).([]stringEvidence) +} + +func (m *mockEvidenceExtractor) fromSuaPayload(payload []byte) []stringEvidence { + args := m.Called(payload) + + return args.Get(0).([]stringEvidence) +} + +func (m *mockEvidenceExtractor) extract(ctx hookstage.ModuleContext) ([]onpremise.Evidence, string, error) { + args := m.Called(ctx) + + res := args.Get(0) + if res == nil { + return nil, args.String(1), args.Error(2) + } + + return res.([]onpremise.Evidence), args.String(1), args.Error(2) +} + +type mockDeviceDetector struct { + mock.Mock +} + +func (m *mockDeviceDetector) getSupportedHeaders() []dd.EvidenceKey { + args := m.Called() + return args.Get(0).([]dd.EvidenceKey) +} + +func (m *mockDeviceDetector) getDeviceInfo(evidence []onpremise.Evidence, ua string) (*deviceInfo, error) { + + args := m.Called(evidence, ua) + + res := args.Get(0) + + if res == nil { + return nil, args.Error(1) + } + + return res.(*deviceInfo), args.Error(1) +} + +func TestHandleEntrypointHookAccountNotAllowed(t *testing.T) { + var mockValidator mockAccValidator + + mockValidator.On("isAllowed", mock.Anything, mock.Anything).Return(false) + + module := Module{ + accountValidator: &mockValidator, + } + + _, err := module.HandleEntrypointHook(nil, hookstage.ModuleInvocationContext{}, hookstage.EntrypointPayload{}) + assert.Error(t, err) + assert.Equal(t, "hook execution failed: account not allowed", err.Error()) +} + +func TestHandleEntrypointHookAccountAllowed(t *testing.T) { + var mockValidator mockAccValidator + + mockValidator.On("isAllowed", mock.Anything, mock.Anything).Return(true) + + var mockEvidenceExtractor mockEvidenceExtractor + mockEvidenceExtractor.On("fromHeaders", mock.Anything, mock.Anything).Return( + []stringEvidence{{ + Prefix: "123", + Key: "key", + Value: "val", + }}, + ) + + mockEvidenceExtractor.On("fromSuaPayload", mock.Anything, mock.Anything).Return( + []stringEvidence{{ + Prefix: "123", + Key: "User-Agent", + Value: "ua", + }}, + ) + + var mockDeviceDetector mockDeviceDetector + + mockDeviceDetector.On("getSupportedHeaders").Return( + []dd.EvidenceKey{{ + Prefix: dd.HttpEvidenceQuery, + Key: "key", + }}, + ) + + module := Module{ + deviceDetector: &mockDeviceDetector, + evidenceExtractor: &mockEvidenceExtractor, + accountValidator: &mockValidator, + } + + result, err := module.HandleEntrypointHook(nil, hookstage.ModuleInvocationContext{}, hookstage.EntrypointPayload{}) + assert.NoError(t, err) + + assert.Equal( + t, result.ModuleContext[evidenceFromHeadersCtxKey], []stringEvidence{{ + Prefix: "123", + Key: "key", + Value: "val", + }}, + ) + + assert.Equal( + t, result.ModuleContext[evidenceFromSuaCtxKey], []stringEvidence{{ + Prefix: "123", + Key: "User-Agent", + Value: "ua", + }}, + ) +} + +func TestHandleRawAuctionHookNoCtx(t *testing.T) { + module := Module{} + + _, err := module.HandleRawAuctionHook( + nil, + hookstage.ModuleInvocationContext{}, + hookstage.RawAuctionRequestPayload{}, + ) + assert.Errorf(t, err, "entrypoint hook was not configured") +} + +func TestHandleRawAuctionHookExtractError(t *testing.T) { + var mockValidator mockAccValidator + + mockValidator.On("isAllowed", mock.Anything, mock.Anything).Return(true) + + var evidenceExtractorM mockEvidenceExtractor + evidenceExtractorM.On("extract", mock.Anything).Return( + nil, + "ua", + nil, + ) + + var mockDeviceDetector mockDeviceDetector + + module := Module{ + deviceDetector: &mockDeviceDetector, + evidenceExtractor: &evidenceExtractorM, + accountValidator: &mockValidator, + } + + mctx := make(hookstage.ModuleContext) + + mctx[ddEnabledCtxKey] = true + + result, err := module.HandleRawAuctionHook( + context.TODO(), hookstage.ModuleInvocationContext{ + ModuleContext: mctx, + }, + hookstage.RawAuctionRequestPayload{}, + ) + + assert.NoError(t, err) + assert.Equal(t, len(result.ChangeSet.Mutations()), 1) + assert.Equal(t, result.ChangeSet.Mutations()[0].Type(), hookstage.MutationUpdate) + + mutation := result.ChangeSet.Mutations()[0] + + body := []byte(`{}`) + + _, err = mutation.Apply(body) + assert.Errorf(t, err, "error extracting evidence") + + var mockEvidenceErrExtractor mockEvidenceExtractor + mockEvidenceErrExtractor.On("extract", mock.Anything).Return( + nil, + "", + errors.New("error"), + ) + + module.evidenceExtractor = &mockEvidenceErrExtractor + + result, err = module.HandleRawAuctionHook( + context.TODO(), hookstage.ModuleInvocationContext{ + ModuleContext: mctx, + }, + hookstage.RawAuctionRequestPayload{}, + ) + + assert.NoError(t, err) + + assert.Equal(t, len(result.ChangeSet.Mutations()), 1) + + assert.Equal(t, result.ChangeSet.Mutations()[0].Type(), hookstage.MutationUpdate) + + mutation = result.ChangeSet.Mutations()[0] + + _, err = mutation.Apply(body) + assert.Errorf(t, err, "error extracting evidence error") + +} + +func TestHandleRawAuctionHookEnrichment(t *testing.T) { + var mockValidator mockAccValidator + + mockValidator.On("isAllowed", mock.Anything, mock.Anything).Return(true) + + var mockEvidenceExtractor mockEvidenceExtractor + mockEvidenceExtractor.On("extract", mock.Anything).Return( + []onpremise.Evidence{ + { + Key: "key", + Value: "val", + }, + }, + "ua", + nil, + ) + + var deviceDetectorM mockDeviceDetector + + deviceDetectorM.On("getDeviceInfo", mock.Anything, mock.Anything).Return( + &deviceInfo{ + HardwareVendor: "Apple", + HardwareName: "Macbook", + DeviceType: "device", + PlatformVendor: "Apple", + PlatformName: "MacOs", + PlatformVersion: "14", + BrowserVendor: "Google", + BrowserName: "Crome", + BrowserVersion: "12", + ScreenPixelsWidth: 1024, + ScreenPixelsHeight: 1080, + PixelRatio: 223, + Javascript: true, + GeoLocation: true, + HardwareFamily: "Macbook", + HardwareModel: "Macbook", + HardwareModelVariants: "Macbook", + UserAgent: "ua", + DeviceId: "", + }, + nil, + ) + + module := Module{ + deviceDetector: &deviceDetectorM, + evidenceExtractor: &mockEvidenceExtractor, + accountValidator: &mockValidator, + } + + mctx := make(hookstage.ModuleContext) + mctx[ddEnabledCtxKey] = true + + result, err := module.HandleRawAuctionHook( + nil, hookstage.ModuleInvocationContext{ + ModuleContext: mctx, + }, + []byte{}, + ) + assert.NoError(t, err) + assert.Equal(t, len(result.ChangeSet.Mutations()), 1) + assert.Equal(t, result.ChangeSet.Mutations()[0].Type(), hookstage.MutationUpdate) + + mutation := result.ChangeSet.Mutations()[0] + + body := []byte(`{ + "device": { + "connectiontype": 2, + "ext": { + "atts": 0, + "ifv": "1B8EFA09-FF8F-4123-B07F-7283B50B3870" + }, + "sua": { + "source": 2, + "browsers": [ + { + "brand": "Not A(Brand", + "version": [ + "99", + "0", + "0", + "0" + ] + }, + { + "brand": "Google Chrome", + "version": [ + "121", + "0", + "6167", + "184" + ] + }, + { + "brand": "Chromium", + "version": [ + "121", + "0", + "6167", + "184" + ] + } + ], + "platform": { + "brand": "macOS", + "version": [ + "14", + "0", + "0" + ] + }, + "mobile": 0, + "architecture": "arm", + "model": "" + } + } + }`) + + mutationResult, err := mutation.Apply(body) + + require.JSONEq(t, string(mutationResult), `{ + "device": { + "connectiontype": 2, + "ext": { + "atts": 0, + "ifv": "1B8EFA09-FF8F-4123-B07F-7283B50B3870", + "fiftyonedegrees_deviceId":"" + }, + "sua": { + "source": 2, + "browsers": [ + { + "brand": "Not A(Brand", + "version": [ + "99", + "0", + "0", + "0" + ] + }, + { + "brand": "Google Chrome", + "version": [ + "121", + "0", + "6167", + "184" + ] + }, + { + "brand": "Chromium", + "version": [ + "121", + "0", + "6167", + "184" + ] + } + ], + "platform": { + "brand": "macOS", + "version": [ + "14", + "0", + "0" + ] + }, + "mobile": 0, + "architecture": "arm", + "model": "" + } + ,"devicetype":2,"ua":"ua","make":"Apple","model":"Macbook","os":"MacOs","osv":"14","h":1080,"w":1024,"pxratio":223,"js":1,"geoFetch":1} + }`) + + var deviceDetectorErrM mockDeviceDetector + + deviceDetectorErrM.On("getDeviceInfo", mock.Anything, mock.Anything).Return( + nil, + errors.New("error"), + ) + + module.deviceDetector = &deviceDetectorErrM + + result, err = module.HandleRawAuctionHook( + nil, hookstage.ModuleInvocationContext{ + ModuleContext: mctx, + }, + []byte{}, + ) + + assert.NoError(t, err) + + assert.Equal(t, len(result.ChangeSet.Mutations()), 1) + + assert.Equal(t, result.ChangeSet.Mutations()[0].Type(), hookstage.MutationUpdate) + + mutation = result.ChangeSet.Mutations()[0] + + _, err = mutation.Apply(body) + assert.Errorf(t, err, "error getting device info") +} + +func TestHandleRawAuctionHookEnrichmentWithErrors(t *testing.T) { + var mockValidator mockAccValidator + + mockValidator.On("isAllowed", mock.Anything, mock.Anything).Return(true) + + var mockEvidenceExtractor mockEvidenceExtractor + mockEvidenceExtractor.On("extract", mock.Anything).Return( + []onpremise.Evidence{ + { + Key: "key", + Value: "val", + }, + }, + "ua", + nil, + ) + + var mockDeviceDetector mockDeviceDetector + + mockDeviceDetector.On("getDeviceInfo", mock.Anything, mock.Anything).Return( + &deviceInfo{ + HardwareVendor: "Apple", + HardwareName: "Macbook", + DeviceType: "device", + PlatformVendor: "Apple", + PlatformName: "MacOs", + PlatformVersion: "14", + BrowserVendor: "Google", + BrowserName: "Crome", + BrowserVersion: "12", + ScreenPixelsWidth: 1024, + ScreenPixelsHeight: 1080, + PixelRatio: 223, + Javascript: true, + GeoLocation: true, + HardwareFamily: "Macbook", + HardwareModel: "Macbook", + HardwareModelVariants: "Macbook", + UserAgent: "ua", + DeviceId: "", + ScreenInchesHeight: 7, + }, + nil, + ) + + module := Module{ + deviceDetector: &mockDeviceDetector, + evidenceExtractor: &mockEvidenceExtractor, + accountValidator: &mockValidator, + } + + mctx := make(hookstage.ModuleContext) + mctx[ddEnabledCtxKey] = true + + result, err := module.HandleRawAuctionHook( + nil, hookstage.ModuleInvocationContext{ + ModuleContext: mctx, + }, + []byte{}, + ) + assert.NoError(t, err) + assert.Equal(t, len(result.ChangeSet.Mutations()), 1) + assert.Equal(t, result.ChangeSet.Mutations()[0].Type(), hookstage.MutationUpdate) + + mutation := result.ChangeSet.Mutations()[0] + + mutationResult, err := mutation.Apply(hookstage.RawAuctionRequestPayload(`{"device":{}}`)) + assert.NoError(t, err) + require.JSONEq(t, string(mutationResult), `{"device":{"devicetype":2,"ua":"ua","make":"Apple","model":"Macbook","os":"MacOs","osv":"14","h":1080,"w":1024,"pxratio":223,"js":1,"geoFetch":1,"ppi":154,"ext":{"fiftyonedegrees_deviceId":""}}}`) +} + +func TestConfigHashFromConfig(t *testing.T) { + cfg := config{ + Performance: performance{ + Profile: "", + Concurrency: nil, + Difference: nil, + AllowUnmatched: nil, + Drift: nil, + }, + } + + result := configHashFromConfig(&cfg) + assert.Equal(t, result.PerformanceProfile(), dd.Default) + assert.Equal(t, result.Concurrency(), uint16(0xa)) + assert.Equal(t, result.Difference(), int32(0)) + assert.Equal(t, result.AllowUnmatched(), false) + assert.Equal(t, result.Drift(), int32(0)) + + concurrency := 1 + difference := 1 + allowUnmatched := true + drift := 1 + + cfg = config{ + Performance: performance{ + Profile: "Balanced", + Concurrency: &concurrency, + Difference: &difference, + AllowUnmatched: &allowUnmatched, + Drift: &drift, + }, + } + + result = configHashFromConfig(&cfg) + assert.Equal(t, result.PerformanceProfile(), dd.Balanced) + assert.Equal(t, result.Concurrency(), uint16(1)) + assert.Equal(t, result.Difference(), int32(1)) + assert.Equal(t, result.AllowUnmatched(), true) + assert.Equal(t, result.Drift(), int32(1)) + + cfg = config{ + Performance: performance{ + Profile: "InMemory", + }, + } + result = configHashFromConfig(&cfg) + assert.Equal(t, result.PerformanceProfile(), dd.InMemory) + + cfg = config{ + Performance: performance{ + Profile: "HighPerformance", + }, + } + result = configHashFromConfig(&cfg) + assert.Equal(t, result.PerformanceProfile(), dd.HighPerformance) +} + +func TestSignDeviceData(t *testing.T) { + devicePld := map[string]any{ + "ext": map[string]any{ + "my-key": "my-value", + }, + } + + deviceInfo := deviceInfo{ + DeviceId: "test-device-id", + } + + result := signDeviceData(devicePld, &deviceInfo) + r, err := json.Marshal(result) + if err != nil { + t.Fatalf("unexpected error: %s", err.Error()) + } + + require.JSONEq( + t, + `{"ext":{"fiftyonedegrees_deviceId":"test-device-id","my-key":"my-value"}}`, + string(r), + ) +} + +func TestBuilderWithInvalidJson(t *testing.T) { + _, err := Builder([]byte(`{`), moduledeps.ModuleDeps{}) + assert.Error(t, err) + assert.Errorf(t, err, "failed to parse config") +} + +func TestBuilderWithInvalidConfig(t *testing.T) { + _, err := Builder([]byte(`{"data_file":{}}`), moduledeps.ModuleDeps{}) + assert.Error(t, err) + assert.Errorf(t, err, "invalid config") +} + +func TestBuilderHandleDeviceDetectorError(t *testing.T) { + var mockConfig config + mockConfig.Performance.Profile = "default" + testFile, _ := os.Create("test-builder-config.hash") + defer testFile.Close() + defer os.Remove("test-builder-config.hash") + + _, err := Builder( + []byte(`{ + "enabled": true, + "data_file": { + "path": "test-builder-config.hash", + "update": { + "auto": true, + "url": "https://my.datafile.com/datafile.gz", + "polling_interval": 3600, + "licence_key": "your_licence_key", + "product": "V4Enterprise" + } + }, + "account_filter": {"allow_list": ["123"]}, + "performance": { + "profile": "123", + "concurrency": 1, + "difference": 1, + "allow_unmatched": true, + "drift": 1 + } + }`), moduledeps.ModuleDeps{}, + ) + assert.Error(t, err) + assert.Errorf(t, err, "failed to create device detector") +} + +func TestHydrateFields(t *testing.T) { + deviceInfo := &deviceInfo{ + HardwareVendor: "Apple", + HardwareName: "Macbook", + DeviceType: "device", + PlatformVendor: "Apple", + PlatformName: "MacOs", + PlatformVersion: "14", + BrowserVendor: "Google", + BrowserName: "Crome", + BrowserVersion: "12", + ScreenPixelsWidth: 1024, + ScreenPixelsHeight: 1080, + PixelRatio: 223, + Javascript: true, + GeoLocation: true, + HardwareFamily: "Macbook", + HardwareModel: "Macbook", + HardwareModelVariants: "Macbook", + UserAgent: "ua", + DeviceId: "dev-ide", + } + + rawPld := `{ + "imp": [{ + "id": "", + "banner": { + "topframe": 1, + "format": [ + { + "w": 728, + "h": 90 + } + ], + "pos": 1 + }, + "bidfloor": 0.01, + "bidfloorcur": "USD" + }], + "device": { + "model": "Macintosh", + "w": 843, + "h": 901, + "dnt": 0, + "ua": "Mozilla/5.0 (Linux; Android 13; SAMSUNG SM-A037U) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/23.0 Chrome/115.0.0.0 Mobile Safari/537.36", + "language": "en", + "sua": {"browsers":[{"brand":"Not/A)Brand","version":["99","0","0","0"]},{"brand":"Samsung Internet","version":["23","0","1","1"]},{"brand":"Chromium","version":["115","0","5790","168"]}],"platform":{"brand":"Android","version":["13","0","0"]},"mobile":1,"model":"SM-A037U","source":2}, + "ext": {"h":"901","w":843} + }, + "cur": [ + "USD" + ], + "tmax": 1700 + }` + + payload, err := hydrateFields(deviceInfo, []byte(rawPld)) + assert.NoError(t, err) + + var deviceHolder struct { + Device json.RawMessage `json:"device"` + } + + err = json.Unmarshal(payload, &deviceHolder) + if err != nil { + t.Fatalf("unexpected error: %s", err.Error()) + } + + require.JSONEq( + t, + `{"devicetype":2,"dnt":0,"ext":{"fiftyonedegrees_deviceId":"dev-ide","h":"901","w":843},"geoFetch":1,"h":901,"js":1,"language":"en","make":"Apple","model":"Macintosh","os":"MacOs","osv":"14","pxratio":223,"sua":{"browsers":[{"brand":"Not/A)Brand","version":["99","0","0","0"]},{"brand":"Samsung Internet","version":["23","0","1","1"]},{"brand":"Chromium","version":["115","0","5790","168"]}],"mobile":1,"model":"SM-A037U","platform":{"brand":"Android","version":["13","0","0"]},"source":2},"ua":"Mozilla/5.0 (Linux; Android 13; SAMSUNG SM-A037U) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/23.0 Chrome/115.0.0.0 Mobile Safari/537.36","w":843}`, + string(deviceHolder.Device), + ) +} diff --git a/modules/fiftyonedegrees/devicedetection/request_headers_extractor.go b/modules/fiftyonedegrees/devicedetection/request_headers_extractor.go new file mode 100644 index 00000000000..8440886b353 --- /dev/null +++ b/modules/fiftyonedegrees/devicedetection/request_headers_extractor.go @@ -0,0 +1,47 @@ +package devicedetection + +import ( + "net/http" + "strings" + + "github.com/51Degrees/device-detection-go/v4/dd" +) + +// evidenceFromRequestHeadersExtractor is a struct that extracts evidence from http request headers +type evidenceFromRequestHeadersExtractor struct{} + +func newEvidenceFromRequestHeadersExtractor() evidenceFromRequestHeadersExtractor { + return evidenceFromRequestHeadersExtractor{} +} + +func (x evidenceFromRequestHeadersExtractor) extract(request *http.Request, httpHeaderKeys []dd.EvidenceKey) []stringEvidence { + return x.extractEvidenceStrings(request, httpHeaderKeys) +} + +func (x evidenceFromRequestHeadersExtractor) extractEvidenceStrings(r *http.Request, keys []dd.EvidenceKey) []stringEvidence { + evidence := make([]stringEvidence, 0) + for _, e := range keys { + if e.Prefix == dd.HttpEvidenceQuery { + continue + } + + // Get evidence from headers + headerVal := r.Header.Get(e.Key) + if headerVal == "" { + continue + } + + if e.Key != secUaFullVersionList && e.Key != secChUa { + headerVal = strings.Replace(headerVal, "\"", "", -1) + } + + if headerVal != "" { + evidence = append(evidence, stringEvidence{ + Prefix: headerPrefix, + Key: e.Key, + Value: headerVal, + }) + } + } + return evidence +} diff --git a/modules/fiftyonedegrees/devicedetection/request_headers_extractor_test.go b/modules/fiftyonedegrees/devicedetection/request_headers_extractor_test.go new file mode 100644 index 00000000000..77fbed3a42f --- /dev/null +++ b/modules/fiftyonedegrees/devicedetection/request_headers_extractor_test.go @@ -0,0 +1,118 @@ +package devicedetection + +import ( + "net/http" + "testing" + + "github.com/51Degrees/device-detection-go/v4/dd" + "github.com/stretchr/testify/assert" +) + +func TestExtractEvidenceStrings(t *testing.T) { + tests := []struct { + name string + headers map[string]string + keys []dd.EvidenceKey + expectedEvidence []stringEvidence + }{ + { + name: "Ignored_query_evidence", + headers: map[string]string{ + "User-Agent": "Mozilla/5.0", + }, + keys: []dd.EvidenceKey{ + {Prefix: dd.HttpEvidenceQuery, Key: "User-Agent"}, + }, + expectedEvidence: []stringEvidence{}, + }, + { + name: "Empty_headers", + headers: map[string]string{}, + keys: []dd.EvidenceKey{ + {Prefix: dd.HttpHeaderString, Key: "User-Agent"}, + }, + expectedEvidence: []stringEvidence{}, + }, + { + name: "Single_header", + headers: map[string]string{ + "User-Agent": "Mozilla/5.0", + }, + keys: []dd.EvidenceKey{ + {Prefix: dd.HttpHeaderString, Key: "User-Agent"}, + }, + expectedEvidence: []stringEvidence{ + {Prefix: headerPrefix, Key: "User-Agent", Value: "Mozilla/5.0"}, + }, + }, + { + name: "Multiple_headers", + headers: map[string]string{ + "User-Agent": "Mozilla/5.0", + "Accept": "text/html", + }, + keys: []dd.EvidenceKey{ + {Prefix: dd.HttpHeaderString, Key: "User-Agent"}, + {Prefix: dd.HttpEvidenceQuery, Key: "Query"}, + {Prefix: dd.HttpHeaderString, Key: "Accept"}, + }, + expectedEvidence: []stringEvidence{ + {Prefix: headerPrefix, Key: "User-Agent", Value: "Mozilla/5.0"}, + {Prefix: headerPrefix, Key: "Accept", Value: "text/html"}, + }, + }, + { + name: "Header_with_quotes_removed", + headers: map[string]string{ + "IP-List": "\"92.0.4515.159\"", + }, + keys: []dd.EvidenceKey{ + {Prefix: dd.HttpHeaderString, Key: "IP-List"}, + }, + expectedEvidence: []stringEvidence{ + {Prefix: headerPrefix, Key: "IP-List", Value: "92.0.4515.159"}, + }, + }, + { + name: "Sec-CH-UA_headers_with_quotes_left", + headers: map[string]string{ + "Sec-CH-UA": "\"Chromium\";v=\"92\", \"Google Chrome\";v=\"92\"", + }, + keys: []dd.EvidenceKey{ + {Prefix: dd.HttpHeaderString, Key: secChUa}, + }, + expectedEvidence: []stringEvidence{ + {Prefix: headerPrefix, Key: secChUa, Value: "\"Chromium\";v=\"92\", \"Google Chrome\";v=\"92\""}, + }, + }, + { + name: "Sec-CH-UA-Full-Version-List_headers_with_quotes_left", + headers: map[string]string{ + "Sec-CH-UA-Full-Version-List": "\"92.0.4515.159\"", + }, + keys: []dd.EvidenceKey{ + {Prefix: dd.HttpHeaderString, Key: secUaFullVersionList}, + }, + expectedEvidence: []stringEvidence{ + {Prefix: headerPrefix, Key: secUaFullVersionList, Value: "\"92.0.4515.159\""}, + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + req := http.Request{ + Header: make(map[string][]string), + } + + for key, value := range test.headers { + req.Header.Set(key, value) + } + + extractor := newEvidenceFromRequestHeadersExtractor() + evidence := extractor.extractEvidenceStrings(&req, test.keys) + + assert.Equal(t, test.expectedEvidence, evidence) + }) + } +} diff --git a/modules/fiftyonedegrees/devicedetection/sample/pbs.json b/modules/fiftyonedegrees/devicedetection/sample/pbs.json new file mode 100644 index 00000000000..43fd28610f1 --- /dev/null +++ b/modules/fiftyonedegrees/devicedetection/sample/pbs.json @@ -0,0 +1,84 @@ +{ + "adapters": [ + { + "appnexus": { + "enabled": true + } + } + ], + "gdpr": { + "enabled": true, + "default_value": 0, + "timeouts_ms": { + "active_vendorlist_fetch": 900000 + } + }, + "stored_requests": { + "filesystem": { + "enabled": true, + "directorypath": "sample/stored" + } + }, + "stored_responses": { + "filesystem": { + "enabled": true, + "directorypath": "sample/stored" + } + }, + "hooks": { + "enabled": true, + "modules": { + "fiftyonedegrees": { + "devicedetection": { + "enabled": true, + "data_file": { + "path": "TAC-HashV41.hash", + "update": { + "auto": false, + "polling_interval": 3600, + "license_key": "YOUR_LICENSE_KEY", + "product": "V4Enterprise" + } + }, + "performance": { + "profile": "InMemory" + } + } + } + }, + "host_execution_plan": { + "endpoints": { + "/openrtb2/auction": { + "stages": { + "entrypoint": { + "groups": [ + { + "timeout": 10, + "hook_sequence": [ + { + "module_code": "fiftyonedegrees.devicedetection", + "hook_impl_code": "fiftyone-devicedetection-entrypoint-hook" + } + ] + } + ] + }, + "raw_auction_request": { + "groups": [ + { + "timeout": 10, + "hook_sequence": [ + { + "module_code": "fiftyonedegrees.devicedetection", + "hook_impl_code": "fiftyone-devicedetection-raw-auction-request-hook" + } + ] + } + ] + } + } + } + } + } + } +} \ No newline at end of file diff --git a/modules/fiftyonedegrees/devicedetection/sample/request_data.json b/modules/fiftyonedegrees/devicedetection/sample/request_data.json new file mode 100644 index 00000000000..1f6bc8900f8 --- /dev/null +++ b/modules/fiftyonedegrees/devicedetection/sample/request_data.json @@ -0,0 +1,114 @@ +{ + "imp": [{ + "ext": { + "data": { + "adserver": { + "name": "gam", + "adslot": "test" + }, + "pbadslot": "test", + "gpid": "test" + }, + "gpid": "test", + "prebid": { + "bidder": { + "appnexus": { + "placement_id": 1, + "use_pmt_rule": false + } + }, + "adunitcode": "25e8ad9f-13a4-4404-ba74-f9eebff0e86c", + "floors": { + "floorMin": 0.01 + } + } + }, + "id": "2529eeea-813e-4da6-838f-f91c28d64867", + "banner": { + "topframe": 1, + "format": [ + { + "w": 728, + "h": 90 + } + ], + "pos": 1 + }, + "bidfloor": 0.01, + "bidfloorcur": "USD" + }], + "site": { + "domain": "test.com", + "publisher": { + "domain": "test.com", + "id": "1" + }, + "page": "https://www.test.com/" + }, + "device": { + "ua": "Mozilla/5.0 (Linux; Android 11; SM-G998W) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Mobile Safari/537.36" + }, + "id": "fc4670ce-4985-4316-a245-b43c885dc37a", + "test": 1, + "cur": [ + "USD" + ], + "source": { + "ext": { + "schain": { + "ver": "1.0", + "complete": 1, + "nodes": [ + { + "asi": "example.com", + "sid": "1234", + "hp": 1 + } + ] + } + } + }, + "ext": { + "prebid": { + "cache": { + "bids": { + "returnCreative": true + }, + "vastxml": { + "returnCreative": true + } + }, + "auctiontimestamp": 1698390609882, + "targeting": { + "includewinners": true, + "includebidderkeys": false + }, + "schains": [ + { + "bidders": [ + "appnexus" + ], + "schain": { + "ver": "1.0", + "complete": 1, + "nodes": [ + { + "asi": "example.com", + "sid": "1234", + "hp": 1 + } + ] + } + } + ], + "floors": { + "enabled": false, + "floorMin": 0.01, + "floorMinCur": "USD" + }, + "createtids": false + } + }, + "user": {}, + "tmax": 1700 +} \ No newline at end of file diff --git a/modules/fiftyonedegrees/devicedetection/sua_payload_extractor.go b/modules/fiftyonedegrees/devicedetection/sua_payload_extractor.go new file mode 100644 index 00000000000..ab69210449f --- /dev/null +++ b/modules/fiftyonedegrees/devicedetection/sua_payload_extractor.go @@ -0,0 +1,144 @@ +package devicedetection + +import ( + "fmt" + "strings" + + "github.com/spf13/cast" + "github.com/tidwall/gjson" +) + +const ( + secChUaArch = "Sec-Ch-Ua-Arch" + secChUaMobile = "Sec-Ch-Ua-Mobile" + secChUaModel = "Sec-Ch-Ua-Model" + secChUaPlatform = "Sec-Ch-Ua-Platform" + secUaFullVersionList = "Sec-Ch-Ua-Full-Version-List" + secChUaPlatformVersion = "Sec-Ch-Ua-Platform-Version" + secChUa = "Sec-Ch-Ua" + + userAgentHeader = "User-Agent" +) + +// evidenceFromSUAPayloadExtractor extracts evidence from the SUA payload of device +type evidenceFromSUAPayloadExtractor struct{} + +func newEvidenceFromSUAPayloadExtractor() evidenceFromSUAPayloadExtractor { + return evidenceFromSUAPayloadExtractor{} +} + +// Extract extracts evidence from the SUA payload +func (x evidenceFromSUAPayloadExtractor) extract(payload []byte) []stringEvidence { + if payload != nil { + return x.extractEvidenceStrings(payload) + } + + return nil +} + +var ( + uaPath = "device.ua" + archPath = "device.sua.architecture" + mobilePath = "device.sua.mobile" + modelPath = "device.sua.model" + platformBrandPath = "device.sua.platform.brand" + platformVersionPath = "device.sua.platform.version" + browsersPath = "device.sua.browsers" +) + +// extractEvidenceStrings extracts evidence from the SUA payload +func (x evidenceFromSUAPayloadExtractor) extractEvidenceStrings(payload []byte) []stringEvidence { + res := make([]stringEvidence, 0, 10) + + uaResult := gjson.GetBytes(payload, uaPath) + if uaResult.Exists() { + res = append( + res, + stringEvidence{Prefix: headerPrefix, Key: userAgentHeader, Value: uaResult.String()}, + ) + } + + archResult := gjson.GetBytes(payload, archPath) + if archResult.Exists() { + res = x.appendEvidenceIfExists(res, secChUaArch, archResult.String()) + } + + mobileResult := gjson.GetBytes(payload, mobilePath) + if mobileResult.Exists() { + res = x.appendEvidenceIfExists(res, secChUaMobile, mobileResult.String()) + } + + modelResult := gjson.GetBytes(payload, modelPath) + if modelResult.Exists() { + res = x.appendEvidenceIfExists(res, secChUaModel, modelResult.String()) + } + + platformBrandResult := gjson.GetBytes(payload, platformBrandPath) + if platformBrandResult.Exists() { + res = x.appendEvidenceIfExists(res, secChUaPlatform, platformBrandResult.String()) + } + + platformVersionResult := gjson.GetBytes(payload, platformVersionPath) + if platformVersionResult.Exists() { + res = x.appendEvidenceIfExists( + res, + secChUaPlatformVersion, + strings.Join(resultToStringArray(platformVersionResult.Array()), "."), + ) + } + + browsersResult := gjson.GetBytes(payload, browsersPath) + if browsersResult.Exists() { + res = x.appendEvidenceIfExists(res, secUaFullVersionList, x.extractBrowsers(browsersResult)) + + } + + return res +} + +func resultToStringArray(array []gjson.Result) []string { + strArray := make([]string, len(array)) + for i, result := range array { + strArray[i] = result.String() + } + + return strArray +} + +// appendEvidenceIfExists appends evidence to the destination if the value is not nil +func (x evidenceFromSUAPayloadExtractor) appendEvidenceIfExists(destination []stringEvidence, name string, value interface{}) []stringEvidence { + if value != nil { + valStr := cast.ToString(value) + if len(valStr) == 0 { + return destination + } + + return append( + destination, + stringEvidence{Prefix: headerPrefix, Key: name, Value: valStr}, + ) + } + + return destination +} + +// extractBrowsers extracts browsers from the SUA payload +func (x evidenceFromSUAPayloadExtractor) extractBrowsers(browsers gjson.Result) string { + if !browsers.IsArray() { + return "" + } + + browsersRaw := make([]string, len(browsers.Array())) + + for i, result := range browsers.Array() { + brand := result.Get("brand").String() + versionsRaw := result.Get("version").Array() + versions := resultToStringArray(versionsRaw) + + browsersRaw[i] = fmt.Sprintf(`"%s";v="%s"`, brand, strings.Join(versions, ".")) + } + + res := strings.Join(browsersRaw, ",") + + return res +} diff --git a/modules/generator/builder.tmpl b/modules/generator/builder.tmpl index db0cd1a4fb4..211e0d1e085 100644 --- a/modules/generator/builder.tmpl +++ b/modules/generator/builder.tmpl @@ -2,7 +2,7 @@ package modules import ( {{- range $vendor, $modules := .}} {{- range $module := $modules}} - {{$vendor}}{{$module | Title}} "github.com/prebid/prebid-server/v2/modules/{{$vendor}}/{{$module}}" + {{$vendor}}{{$module | Title}} "github.com/prebid/prebid-server/v3/modules/{{$vendor}}/{{$module}}" {{- end}} {{- end}} ) diff --git a/modules/helpers.go b/modules/helpers.go index 10890743691..c38b224931e 100644 --- a/modules/helpers.go +++ b/modules/helpers.go @@ -4,8 +4,8 @@ import ( "fmt" "strings" - "github.com/prebid/prebid-server/v2/hooks" - "github.com/prebid/prebid-server/v2/hooks/hookstage" + "github.com/prebid/prebid-server/v3/hooks" + "github.com/prebid/prebid-server/v3/hooks/hookstage" ) var moduleReplacer = strings.NewReplacer(".", "_", "-", "_") diff --git a/modules/moduledeps/deps.go b/modules/moduledeps/deps.go index a1fa89173b4..266e22575e5 100644 --- a/modules/moduledeps/deps.go +++ b/modules/moduledeps/deps.go @@ -3,7 +3,7 @@ package moduledeps import ( "net/http" - "github.com/prebid/prebid-server/v2/currency" + "github.com/prebid/prebid-server/v3/currency" ) // ModuleDeps provides dependencies that custom modules may need for hooks execution. diff --git a/modules/modules.go b/modules/modules.go index f3ccd6b1ece..3b266a14c5b 100644 --- a/modules/modules.go +++ b/modules/modules.go @@ -5,10 +5,10 @@ import ( "fmt" "github.com/golang/glog" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/hooks" - "github.com/prebid/prebid-server/v2/modules/moduledeps" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/hooks" + "github.com/prebid/prebid-server/v3/modules/moduledeps" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) //go:generate go run ./generator/buildergen.go diff --git a/modules/modules_test.go b/modules/modules_test.go index 008c1e75c51..b6c59d73168 100644 --- a/modules/modules_test.go +++ b/modules/modules_test.go @@ -9,10 +9,10 @@ import ( "net/http" "testing" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/hooks" - "github.com/prebid/prebid-server/v2/hooks/hookstage" - "github.com/prebid/prebid-server/v2/modules/moduledeps" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/hooks" + "github.com/prebid/prebid-server/v3/hooks/hookstage" + "github.com/prebid/prebid-server/v3/modules/moduledeps" "github.com/stretchr/testify/assert" ) diff --git a/modules/prebid/ortb2blocking/analytics.go b/modules/prebid/ortb2blocking/analytics.go index 1309858c7b6..bab50e3a4e9 100644 --- a/modules/prebid/ortb2blocking/analytics.go +++ b/modules/prebid/ortb2blocking/analytics.go @@ -1,8 +1,8 @@ package ortb2blocking import ( - "github.com/prebid/prebid-server/v2/hooks/hookanalytics" - "github.com/prebid/prebid-server/v2/hooks/hookstage" + "github.com/prebid/prebid-server/v3/hooks/hookanalytics" + "github.com/prebid/prebid-server/v3/hooks/hookstage" ) const enforceBlockingTag = "enforce_blocking" diff --git a/modules/prebid/ortb2blocking/config.go b/modules/prebid/ortb2blocking/config.go index 634170ef192..1990b0a56aa 100644 --- a/modules/prebid/ortb2blocking/config.go +++ b/modules/prebid/ortb2blocking/config.go @@ -5,7 +5,7 @@ import ( "fmt" "github.com/prebid/openrtb/v20/adcom1" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) func newConfig(data json.RawMessage) (config, error) { diff --git a/modules/prebid/ortb2blocking/hook_bidderrequest.go b/modules/prebid/ortb2blocking/hook_bidderrequest.go index 02e3634f679..4b3cb87c855 100644 --- a/modules/prebid/ortb2blocking/hook_bidderrequest.go +++ b/modules/prebid/ortb2blocking/hook_bidderrequest.go @@ -7,9 +7,9 @@ import ( "github.com/prebid/openrtb/v20/adcom1" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/hooks/hookexecution" - "github.com/prebid/prebid-server/v2/hooks/hookstage" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/hooks/hookexecution" + "github.com/prebid/prebid-server/v3/hooks/hookstage" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func handleBidderRequestHook( diff --git a/modules/prebid/ortb2blocking/hook_raw_bidder_response.go b/modules/prebid/ortb2blocking/hook_raw_bidder_response.go index 215de260b09..f9b028b3c40 100644 --- a/modules/prebid/ortb2blocking/hook_raw_bidder_response.go +++ b/modules/prebid/ortb2blocking/hook_raw_bidder_response.go @@ -7,9 +7,9 @@ import ( "github.com/prebid/openrtb/v20/adcom1" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/hooks/hookexecution" - "github.com/prebid/prebid-server/v2/hooks/hookstage" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/hooks/hookexecution" + "github.com/prebid/prebid-server/v3/hooks/hookstage" ) func handleRawBidderResponseHook( diff --git a/modules/prebid/ortb2blocking/module.go b/modules/prebid/ortb2blocking/module.go index 0b85c43dad2..24ff28df746 100644 --- a/modules/prebid/ortb2blocking/module.go +++ b/modules/prebid/ortb2blocking/module.go @@ -5,8 +5,8 @@ import ( "encoding/json" "github.com/prebid/openrtb/v20/adcom1" - "github.com/prebid/prebid-server/v2/hooks/hookstage" - "github.com/prebid/prebid-server/v2/modules/moduledeps" + "github.com/prebid/prebid-server/v3/hooks/hookstage" + "github.com/prebid/prebid-server/v3/modules/moduledeps" ) func Builder(_ json.RawMessage, _ moduledeps.ModuleDeps) (interface{}, error) { diff --git a/modules/prebid/ortb2blocking/module_test.go b/modules/prebid/ortb2blocking/module_test.go index 8178cba15fe..d07ea6bd4d0 100644 --- a/modules/prebid/ortb2blocking/module_test.go +++ b/modules/prebid/ortb2blocking/module_test.go @@ -8,12 +8,12 @@ import ( "github.com/prebid/openrtb/v20/adcom1" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/adapters" - "github.com/prebid/prebid-server/v2/hooks/hookanalytics" - "github.com/prebid/prebid-server/v2/hooks/hookexecution" - "github.com/prebid/prebid-server/v2/hooks/hookstage" - "github.com/prebid/prebid-server/v2/modules/moduledeps" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/hooks/hookanalytics" + "github.com/prebid/prebid-server/v3/hooks/hookexecution" + "github.com/prebid/prebid-server/v3/hooks/hookstage" + "github.com/prebid/prebid-server/v3/modules/moduledeps" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 49f5d317ff8..68b3c1d241e 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -29,6 +29,7 @@ var coreBidderNames []BidderName = []BidderName{ BidderAdkernel, BidderAdkernelAdn, BidderAdman, + BidderAdmatic, BidderAdmixer, BidderAdnuntius, BidderAdOcean, @@ -42,6 +43,7 @@ var coreBidderNames []BidderName = []BidderName{ BidderAdtarget, BidderAdtrgtme, BidderAdtelligent, + BidderAdTonos, BidderAdvangelists, BidderAdView, BidderAdxcg, @@ -66,10 +68,12 @@ var coreBidderNames []BidderName = []BidderName{ BidderBetween, BidderBeyondMedia, BidderBidmachine, + BidderBidmatic, BidderBidmyadz, BidderBidsCube, BidderBidstack, - BidderBizzclick, + BidderBigoAd, + BidderBlasto, BidderBliink, BidderBlue, BidderBluesea, @@ -79,6 +83,7 @@ var coreBidderNames []BidderName = []BidderName{ BidderBWX, BidderCadentApertureMX, BidderCcx, + BidderCointraffic, BidderCoinzilla, BidderColossus, BidderCompass, @@ -86,6 +91,7 @@ var coreBidderNames []BidderName = []BidderName{ BidderConnectAd, BidderConsumable, BidderConversant, + BidderCopper6ssp, BidderCpmstar, BidderCriteo, BidderCWire, @@ -94,6 +100,7 @@ var coreBidderNames []BidderName = []BidderName{ BidderDeepintent, BidderDefinemedia, BidderDianomi, + BidderDisplayio, BidderEdge226, BidderDmx, BidderDXKulture, @@ -102,6 +109,7 @@ var coreBidderNames []BidderName = []BidderName{ BidderEmxDigital, BidderEPlanning, BidderEpom, + BidderEscalax, BidderEVolution, BidderFlipp, BidderFreewheelSSP, @@ -141,10 +149,14 @@ var coreBidderNames []BidderName = []BidderName{ BidderMadvertise, BidderMarsmedia, BidderMediafuse, + BidderMediaGo, BidderMedianet, + BidderMeloZen, + BidderMetaX, BidderMgid, BidderMgidX, BidderMinuteMedia, + BidderMissena, BidderMobfoxpb, BidderMobileFuse, BidderMotorik, @@ -155,6 +167,7 @@ var coreBidderNames []BidderName = []BidderName{ BidderOpenWeb, BidderOpenx, BidderOperaads, + BidderOraki, BidderOrbidder, BidderOutbrain, BidderOwnAdx, @@ -162,11 +175,14 @@ var coreBidderNames []BidderName = []BidderName{ BidderPGAMSsp, BidderPlaydigo, BidderPubmatic, + BidderPubrise, BidderPubnative, BidderPulsepoint, BidderPWBid, + BidderQT, BidderReadpeak, BidderRelevantDigital, + BidderResetDigital, BidderRevcontent, BidderRichaudience, BidderRise, @@ -197,6 +213,7 @@ var coreBidderNames []BidderName = []BidderName{ BidderTeads, BidderTelaria, BidderTheadx, + BidderTheTradeDesk, BidderTpmn, BidderTrafficGate, BidderTriplelift, @@ -206,6 +223,7 @@ var coreBidderNames []BidderName = []BidderName{ BidderUndertone, BidderUnicorn, BidderUnruly, + BidderVidazoo, BidderVideoByte, BidderVideoHeroes, BidderVidoomy, @@ -341,6 +359,7 @@ const ( BidderAdkernel BidderName = "adkernel" BidderAdkernelAdn BidderName = "adkernelAdn" BidderAdman BidderName = "adman" + BidderAdmatic BidderName = "admatic" BidderAdmixer BidderName = "admixer" BidderAdnuntius BidderName = "adnuntius" BidderAdOcean BidderName = "adocean" @@ -353,6 +372,7 @@ const ( BidderAdsinteractive BidderName = "adsinteractive" BidderAdtarget BidderName = "adtarget" BidderAdtrgtme BidderName = "adtrgtme" + BidderAdTonos BidderName = "adtonos" BidderAdtelligent BidderName = "adtelligent" BidderAdvangelists BidderName = "advangelists" BidderAdView BidderName = "adview" @@ -378,10 +398,12 @@ const ( BidderBetween BidderName = "between" BidderBeyondMedia BidderName = "beyondmedia" BidderBidmachine BidderName = "bidmachine" + BidderBidmatic BidderName = "bidmatic" BidderBidmyadz BidderName = "bidmyadz" BidderBidsCube BidderName = "bidscube" BidderBidstack BidderName = "bidstack" - BidderBizzclick BidderName = "bizzclick" + BidderBigoAd BidderName = "bigoad" + BidderBlasto BidderName = "blasto" BidderBliink BidderName = "bliink" BidderBlue BidderName = "blue" BidderBluesea BidderName = "bluesea" @@ -391,6 +413,7 @@ const ( BidderBWX BidderName = "bwx" BidderCadentApertureMX BidderName = "cadent_aperture_mx" BidderCcx BidderName = "ccx" + BidderCointraffic BidderName = "cointraffic" BidderCoinzilla BidderName = "coinzilla" BidderColossus BidderName = "colossus" BidderCompass BidderName = "compass" @@ -398,6 +421,7 @@ const ( BidderConnectAd BidderName = "connectad" BidderConsumable BidderName = "consumable" BidderConversant BidderName = "conversant" + BidderCopper6ssp BidderName = "copper6ssp" BidderCpmstar BidderName = "cpmstar" BidderCriteo BidderName = "criteo" BidderCWire BidderName = "cwire" @@ -406,6 +430,7 @@ const ( BidderDeepintent BidderName = "deepintent" BidderDefinemedia BidderName = "definemedia" BidderDianomi BidderName = "dianomi" + BidderDisplayio BidderName = "displayio" BidderEdge226 BidderName = "edge226" BidderDmx BidderName = "dmx" BidderDXKulture BidderName = "dxkulture" @@ -414,6 +439,7 @@ const ( BidderEmxDigital BidderName = "emx_digital" BidderEPlanning BidderName = "eplanning" BidderEpom BidderName = "epom" + BidderEscalax BidderName = "escalax" BidderEVolution BidderName = "e_volution" BidderFlipp BidderName = "flipp" BidderFreewheelSSP BidderName = "freewheelssp" @@ -453,10 +479,14 @@ const ( BidderMadvertise BidderName = "madvertise" BidderMarsmedia BidderName = "marsmedia" BidderMediafuse BidderName = "mediafuse" + BidderMediaGo BidderName = "mediago" BidderMedianet BidderName = "medianet" + BidderMeloZen BidderName = "melozen" + BidderMetaX BidderName = "metax" BidderMgid BidderName = "mgid" BidderMgidX BidderName = "mgidX" BidderMinuteMedia BidderName = "minutemedia" + BidderMissena BidderName = "missena" BidderMobfoxpb BidderName = "mobfoxpb" BidderMobileFuse BidderName = "mobilefuse" BidderMotorik BidderName = "motorik" @@ -467,6 +497,7 @@ const ( BidderOpenWeb BidderName = "openweb" BidderOpenx BidderName = "openx" BidderOperaads BidderName = "operaads" + BidderOraki BidderName = "oraki" BidderOrbidder BidderName = "orbidder" BidderOutbrain BidderName = "outbrain" BidderOwnAdx BidderName = "ownadx" @@ -474,11 +505,14 @@ const ( BidderPGAMSsp BidderName = "pgamssp" BidderPlaydigo BidderName = "playdigo" BidderPubmatic BidderName = "pubmatic" + BidderPubrise BidderName = "pubrise" BidderPubnative BidderName = "pubnative" BidderPulsepoint BidderName = "pulsepoint" BidderPWBid BidderName = "pwbid" + BidderQT BidderName = "qt" BidderReadpeak BidderName = "readpeak" BidderRelevantDigital BidderName = "relevantdigital" + BidderResetDigital BidderName = "resetdigital" BidderRevcontent BidderName = "revcontent" BidderRichaudience BidderName = "richaudience" BidderRise BidderName = "rise" @@ -509,6 +543,7 @@ const ( BidderTeads BidderName = "teads" BidderTelaria BidderName = "telaria" BidderTheadx BidderName = "theadx" + BidderTheTradeDesk BidderName = "thetradedesk" BidderTpmn BidderName = "tpmn" BidderTrafficGate BidderName = "trafficgate" BidderTriplelift BidderName = "triplelift" @@ -518,6 +553,7 @@ const ( BidderUndertone BidderName = "undertone" BidderUnicorn BidderName = "unicorn" BidderUnruly BidderName = "unruly" + BidderVidazoo BidderName = "vidazoo" BidderVideoByte BidderName = "videobyte" BidderVideoHeroes BidderName = "videoheroes" BidderVidoomy BidderName = "vidoomy" diff --git a/openrtb_ext/convert_down.go b/openrtb_ext/convert_down.go index e0842978551..bfb6028d8c7 100644 --- a/openrtb_ext/convert_down.go +++ b/openrtb_ext/convert_down.go @@ -31,13 +31,6 @@ func ConvertDownTo25(r *RequestWrapper) error { } } - // Remove fields introduced in OpenRTB 2.6+. The previous OpenRTB 2.5 spec did not specify that - // bidders must tolerate new or unexpected fields. - clear26Fields(r) - clear202211Fields(r) - clear202303Fields(r) - clear202309Fields(r) - return nil } diff --git a/openrtb_ext/convert_down_test.go b/openrtb_ext/convert_down_test.go index 1bf112dcb3a..f32f3da04bb 100644 --- a/openrtb_ext/convert_down_test.go +++ b/openrtb_ext/convert_down_test.go @@ -6,8 +6,8 @@ import ( "github.com/prebid/openrtb/v20/adcom1" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/util/ptrutil" "github.com/stretchr/testify/assert" ) @@ -35,50 +35,6 @@ func TestConvertDownTo25(t *testing.T) { User: &openrtb2.User{Ext: json.RawMessage(`{"consent":"1","eids":[{"source":"42"}]}`)}, }, }, - { - name: "2.6-dropped", // integration with clear26Fields - givenRequest: openrtb2.BidRequest{ - ID: "anyID", - CatTax: adcom1.CatTaxIABContent10, - Device: &openrtb2.Device{LangB: "anyLang"}, - }, - expectedRequest: openrtb2.BidRequest{ - ID: "anyID", - Device: &openrtb2.Device{}, - }, - }, - { - name: "2.6-202211-dropped", // integration with clear202211Fields - givenRequest: openrtb2.BidRequest{ - ID: "anyID", - App: &openrtb2.App{InventoryPartnerDomain: "anyDomain"}, - }, - expectedRequest: openrtb2.BidRequest{ - ID: "anyID", - App: &openrtb2.App{}, - }, - }, - { - name: "2.6-202303-dropped", // integration with clear202303Fields - givenRequest: openrtb2.BidRequest{ - ID: "anyID", - Imp: []openrtb2.Imp{{ID: "1", Refresh: &openrtb2.Refresh{Count: ptrutil.ToPtr(1)}}}, - }, - expectedRequest: openrtb2.BidRequest{ - ID: "anyID", - Imp: []openrtb2.Imp{{ID: "1"}}, - }, - }, - { - name: "2.6-202309-dropped", // integration with clear202309Fields - givenRequest: openrtb2.BidRequest{ - ID: "anyID", - ACat: []string{"anyACat"}, - }, - expectedRequest: openrtb2.BidRequest{ - ID: "anyID", - }, - }, { name: "2.6-to-2.5-OtherExtFields", givenRequest: openrtb2.BidRequest{ diff --git a/openrtb_ext/deal_tier.go b/openrtb_ext/deal_tier.go index e96ca4b8473..b0f2675d660 100644 --- a/openrtb_ext/deal_tier.go +++ b/openrtb_ext/deal_tier.go @@ -2,7 +2,7 @@ package openrtb_ext import ( "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) // DealTier defines the configuration of a deal tier. diff --git a/openrtb_ext/deal_tier_test.go b/openrtb_ext/deal_tier_test.go index 5407dd2af38..6808f90a0da 100644 --- a/openrtb_ext/deal_tier_test.go +++ b/openrtb_ext/deal_tier_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v3/errortypes" "github.com/stretchr/testify/assert" ) diff --git a/openrtb_ext/device.go b/openrtb_ext/device.go index 0888d06160f..2107a3081ff 100644 --- a/openrtb_ext/device.go +++ b/openrtb_ext/device.go @@ -6,7 +6,7 @@ import ( "strconv" "github.com/buger/jsonparser" - "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v3/errortypes" ) // PrebidExtKey represents the prebid extension key used in requests diff --git a/openrtb_ext/device_test.go b/openrtb_ext/device_test.go index f40e9650061..52b679fda38 100644 --- a/openrtb_ext/device_test.go +++ b/openrtb_ext/device_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/jsonutil" "github.com/stretchr/testify/assert" ) diff --git a/openrtb_ext/floors.go b/openrtb_ext/floors.go index d903fe971f0..e663229a797 100644 --- a/openrtb_ext/floors.go +++ b/openrtb_ext/floors.go @@ -4,7 +4,7 @@ import ( "maps" "slices" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/util/ptrutil" ) // Defines strings for FetchStatus diff --git a/openrtb_ext/floors_test.go b/openrtb_ext/floors_test.go index 687101bfa3a..df7d1e5dc22 100644 --- a/openrtb_ext/floors_test.go +++ b/openrtb_ext/floors_test.go @@ -4,7 +4,7 @@ import ( "reflect" "testing" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/openrtb_ext/imp_admatic.go b/openrtb_ext/imp_admatic.go new file mode 100644 index 00000000000..89e9acc1f72 --- /dev/null +++ b/openrtb_ext/imp_admatic.go @@ -0,0 +1,6 @@ +package openrtb_ext + +type ImpExtAdmatic struct { + Host string `json:"host"` + NetworkId int `json:"networkId"` +} diff --git a/openrtb_ext/imp_adtarget.go b/openrtb_ext/imp_adtarget.go index ab6cb5642c6..aa3b6136e58 100644 --- a/openrtb_ext/imp_adtarget.go +++ b/openrtb_ext/imp_adtarget.go @@ -1,9 +1,11 @@ package openrtb_ext +import "encoding/json" + // ExtImpAdtarget defines the contract for bidrequest.imp[i].ext.prebid.bidder.adtarget type ExtImpAdtarget struct { - SourceId int `json:"aid"` - PlacementId int `json:"placementId,omitempty"` - SiteId int `json:"siteId,omitempty"` - BidFloor float64 `json:"bidFloor,omitempty"` + SourceId json.Number `json:"aid"` + PlacementId int `json:"placementId,omitempty"` + SiteId int `json:"siteId,omitempty"` + BidFloor float64 `json:"bidFloor,omitempty"` } diff --git a/openrtb_ext/imp_adtelligent.go b/openrtb_ext/imp_adtelligent.go index c2233209352..b13c44ea360 100644 --- a/openrtb_ext/imp_adtelligent.go +++ b/openrtb_ext/imp_adtelligent.go @@ -1,9 +1,11 @@ package openrtb_ext +import "encoding/json" + // ExtImpAdtelligent defines the contract for bidrequest.imp[i].ext.prebid.bidder.adtelligent type ExtImpAdtelligent struct { - SourceId int `json:"aid"` - PlacementId int `json:"placementId,omitempty"` - SiteId int `json:"siteId,omitempty"` - BidFloor float64 `json:"bidFloor,omitempty"` + SourceId json.Number `json:"aid"` + PlacementId int `json:"placementId,omitempty"` + SiteId int `json:"siteId,omitempty"` + BidFloor float64 `json:"bidFloor,omitempty"` } diff --git a/openrtb_ext/imp_adtonos.go b/openrtb_ext/imp_adtonos.go new file mode 100644 index 00000000000..f59ee35b329 --- /dev/null +++ b/openrtb_ext/imp_adtonos.go @@ -0,0 +1,5 @@ +package openrtb_ext + +type ImpExtAdTonos struct { + SupplierID string `json:"supplierId"` +} diff --git a/openrtb_ext/imp_appnexus.go b/openrtb_ext/imp_appnexus.go index db949f661fd..9e7a43495c8 100644 --- a/openrtb_ext/imp_appnexus.go +++ b/openrtb_ext/imp_appnexus.go @@ -5,7 +5,7 @@ import ( "fmt" "strings" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) // ExtImpAppnexus defines the contract for bidrequest.imp[i].ext.prebid.bidder.appnexus diff --git a/openrtb_ext/imp_appnexus_test.go b/openrtb_ext/imp_appnexus_test.go index 9d65f3be3ad..52e42d4d53a 100644 --- a/openrtb_ext/imp_appnexus_test.go +++ b/openrtb_ext/imp_appnexus_test.go @@ -3,7 +3,7 @@ package openrtb_ext import ( "testing" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/jsonutil" "github.com/stretchr/testify/assert" ) diff --git a/openrtb_ext/imp_bidmatic.go b/openrtb_ext/imp_bidmatic.go new file mode 100644 index 00000000000..935c977e7ac --- /dev/null +++ b/openrtb_ext/imp_bidmatic.go @@ -0,0 +1,11 @@ +package openrtb_ext + +import "encoding/json" + +// ExtImpBidmatic defines the contract for bidrequest.imp[i].ext.prebid.bidder.bidmatic +type ExtImpBidmatic struct { + SourceId json.Number `json:"source"` + PlacementId int `json:"placementId,omitempty"` + SiteId int `json:"siteId,omitempty"` + BidFloor float64 `json:"bidFloor,omitempty"` +} diff --git a/openrtb_ext/imp_bigoad.go b/openrtb_ext/imp_bigoad.go new file mode 100644 index 00000000000..dad9c4fd878 --- /dev/null +++ b/openrtb_ext/imp_bigoad.go @@ -0,0 +1,5 @@ +package openrtb_ext + +type ExtImpBigoAd struct { + SspId string `json:"sspid"` +} diff --git a/openrtb_ext/imp_bizzclick.go b/openrtb_ext/imp_blasto.go similarity index 86% rename from openrtb_ext/imp_bizzclick.go rename to openrtb_ext/imp_blasto.go index 15a8c2d0d46..b49544895a9 100644 --- a/openrtb_ext/imp_bizzclick.go +++ b/openrtb_ext/imp_blasto.go @@ -1,6 +1,6 @@ package openrtb_ext -type ExtBizzclick struct { +type ExtBlasto struct { AccountID string `json:"accountId"` SourceID string `json:"sourceId"` Host string `json:"host"` diff --git a/openrtb_ext/imp_cointraffic.go b/openrtb_ext/imp_cointraffic.go new file mode 100644 index 00000000000..da5ea69b1b5 --- /dev/null +++ b/openrtb_ext/imp_cointraffic.go @@ -0,0 +1,5 @@ +package openrtb_ext + +type ExtImpCointraffic struct { + PlacementId string `json:"placementId"` +} diff --git a/openrtb_ext/imp_connectad.go b/openrtb_ext/imp_connectad.go index c4c7ab696f2..4affaed1ea3 100644 --- a/openrtb_ext/imp_connectad.go +++ b/openrtb_ext/imp_connectad.go @@ -1,7 +1,9 @@ package openrtb_ext +import "github.com/prebid/prebid-server/v3/util/jsonutil" + type ExtImpConnectAd struct { - NetworkID int `json:"networkId"` - SiteID int `json:"siteId"` - Bidfloor float64 `json:"bidfloor,omitempty"` + NetworkID jsonutil.StringInt `json:"networkId"` + SiteID jsonutil.StringInt `json:"siteId"` + Bidfloor float64 `json:"bidfloor,omitempty"` } diff --git a/openrtb_ext/imp_copper6ssp.go b/openrtb_ext/imp_copper6ssp.go new file mode 100644 index 00000000000..a9fd47a1eb6 --- /dev/null +++ b/openrtb_ext/imp_copper6ssp.go @@ -0,0 +1,6 @@ +package openrtb_ext + +type ImpExtCopper6ssp struct { + PlacementID string `json:"placementId"` + EndpointID string `json:"endpointId"` +} diff --git a/openrtb_ext/imp_displayio.go b/openrtb_ext/imp_displayio.go new file mode 100644 index 00000000000..bb8c2020276 --- /dev/null +++ b/openrtb_ext/imp_displayio.go @@ -0,0 +1,7 @@ +package openrtb_ext + +type ExtImpDisplayio struct { + PublisherId string `json:"publisherId"` + InventoryId string `json:"inventoryId"` + PlacementId string `json:"placementId"` +} diff --git a/openrtb_ext/imp_escalax.go b/openrtb_ext/imp_escalax.go new file mode 100644 index 00000000000..15292b59552 --- /dev/null +++ b/openrtb_ext/imp_escalax.go @@ -0,0 +1,6 @@ +package openrtb_ext + +type ExtEscalax struct { + AccountID string `json:"accountId"` + SourceID string `json:"sourceId"` +} diff --git a/openrtb_ext/imp_freewheelssp.go b/openrtb_ext/imp_freewheelssp.go index 3d015d96722..5ed1f626093 100644 --- a/openrtb_ext/imp_freewheelssp.go +++ b/openrtb_ext/imp_freewheelssp.go @@ -1,7 +1,7 @@ package openrtb_ext import ( - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type ImpExtFreewheelSSP struct { diff --git a/openrtb_ext/imp_mediago.go b/openrtb_ext/imp_mediago.go new file mode 100644 index 00000000000..89a5ff0dade --- /dev/null +++ b/openrtb_ext/imp_mediago.go @@ -0,0 +1,13 @@ +package openrtb_ext + +// ExtImpMediaGo defines the contract for bidrequest.imp[i].ext.prebid.bidder.mediago +type ExtImpMediaGo struct { + Token string `json:"token"` + Region string `json:"region"` + PlacementId string `json:"placementId"` +} + +type ExtMediaGo struct { + Token string `json:"token"` + Region string `json:"region"` +} diff --git a/openrtb_ext/imp_melozen.go b/openrtb_ext/imp_melozen.go new file mode 100644 index 00000000000..598df6a28e9 --- /dev/null +++ b/openrtb_ext/imp_melozen.go @@ -0,0 +1,5 @@ +package openrtb_ext + +type ImpExtMeloZen struct { + PubId string `json:"pubId"` +} diff --git a/openrtb_ext/imp_metax.go b/openrtb_ext/imp_metax.go new file mode 100644 index 00000000000..ab54505fbf3 --- /dev/null +++ b/openrtb_ext/imp_metax.go @@ -0,0 +1,7 @@ +package openrtb_ext + +// ExtImpMetaX defines the contract for bidrequest.imp[i].ext.prebid.bidder.metax +type ExtImpMetaX struct { + PublisherID int `json:"publisherId"` + Adunit int `json:"adunit"` +} diff --git a/openrtb_ext/imp_missena.go b/openrtb_ext/imp_missena.go new file mode 100644 index 00000000000..3e341957123 --- /dev/null +++ b/openrtb_ext/imp_missena.go @@ -0,0 +1,7 @@ +package openrtb_ext + +type ExtImpMissena struct { + ApiKey string `json:"apiKey"` + Placement string `json:"placement"` + TestMode string `json:"test"` +} diff --git a/openrtb_ext/imp_openweb.go b/openrtb_ext/imp_openweb.go index fc3cbdacdd0..5df8e7d18e5 100644 --- a/openrtb_ext/imp_openweb.go +++ b/openrtb_ext/imp_openweb.go @@ -2,8 +2,7 @@ package openrtb_ext // ExtImpOpenWeb defines the contract for bidrequest.imp[i].ext.prebid.bidder.openweb type ExtImpOpenWeb struct { - SourceID int `json:"aid"` - PlacementID int `json:"placementId,omitempty"` - SiteID int `json:"siteId,omitempty"` - BidFloor float64 `json:"bidFloor,omitempty"` + Aid int `json:"aid,omitempty"` + Org string `json:"org,omitempty"` + PlacementID string `json:"placementId"` } diff --git a/openrtb_ext/imp_openx.go b/openrtb_ext/imp_openx.go index 38bce75f17c..880e4a6d457 100644 --- a/openrtb_ext/imp_openx.go +++ b/openrtb_ext/imp_openx.go @@ -1,10 +1,12 @@ package openrtb_ext +import "encoding/json" + // ExtImpOpenx defines the contract for bidrequest.imp[i].ext.prebid.bidder.openx type ExtImpOpenx struct { - Unit string `json:"unit"` + Unit json.Number `json:"unit"` Platform string `json:"platform"` DelDomain string `json:"delDomain"` - CustomFloor float64 `json:"customFloor"` + CustomFloor json.Number `json:"customFloor"` CustomParams map[string]interface{} `json:"customParams"` } diff --git a/openrtb_ext/imp_oraki.go b/openrtb_ext/imp_oraki.go new file mode 100644 index 00000000000..a9dea04434f --- /dev/null +++ b/openrtb_ext/imp_oraki.go @@ -0,0 +1,6 @@ +package openrtb_ext + +type ImpExtOraki struct { + PlacementID string `json:"placementId"` + EndpointID string `json:"endpointId"` +} diff --git a/openrtb_ext/imp_pubrise.go b/openrtb_ext/imp_pubrise.go new file mode 100644 index 00000000000..c2b30391748 --- /dev/null +++ b/openrtb_ext/imp_pubrise.go @@ -0,0 +1,6 @@ +package openrtb_ext + +type ImpExtPubrise struct { + PlacementID string `json:"placementId"` + EndpointID string `json:"endpointId"` +} diff --git a/openrtb_ext/imp_pulsepoint.go b/openrtb_ext/imp_pulsepoint.go index a901592c45b..a372e3765c5 100644 --- a/openrtb_ext/imp_pulsepoint.go +++ b/openrtb_ext/imp_pulsepoint.go @@ -1,9 +1,13 @@ package openrtb_ext +import ( + "github.com/prebid/prebid-server/v3/util/jsonutil" +) + // ExtImpPulsePoint defines the json spec for bidrequest.imp[i].ext.prebid.bidder.pulsepoint // PubId/TagId are mandatory params type ExtImpPulsePoint struct { - PubID int `json:"cp"` - TagID int `json:"ct"` + PubID jsonutil.StringInt `json:"cp"` + TagID jsonutil.StringInt `json:"ct"` } diff --git a/openrtb_ext/imp_qt.go b/openrtb_ext/imp_qt.go new file mode 100644 index 00000000000..78e4d11e746 --- /dev/null +++ b/openrtb_ext/imp_qt.go @@ -0,0 +1,6 @@ +package openrtb_ext + +type ImpExtQT struct { + PlacementID string `json:"placementId"` + EndpointID string `json:"endpointId"` +} diff --git a/openrtb_ext/imp_resetdigital.go b/openrtb_ext/imp_resetdigital.go new file mode 100644 index 00000000000..6e3f800ab98 --- /dev/null +++ b/openrtb_ext/imp_resetdigital.go @@ -0,0 +1,5 @@ +package openrtb_ext + +type ImpExtResetDigital struct { + PlacementID string `json:"placement_id"` +} diff --git a/openrtb_ext/imp_thetradedesk.go b/openrtb_ext/imp_thetradedesk.go new file mode 100644 index 00000000000..89cca83f65e --- /dev/null +++ b/openrtb_ext/imp_thetradedesk.go @@ -0,0 +1,8 @@ +package openrtb_ext + +// ExtImpTheTradeDesk defines the contract for bidrequest.imp[i].ext +// PublisherId is mandatory parameters, others are optional parameters + +type ExtImpTheTradeDesk struct { + PublisherId string `json:"publisherId"` +} diff --git a/openrtb_ext/imp_vidazoo.go b/openrtb_ext/imp_vidazoo.go new file mode 100644 index 00000000000..c2589d3f1ae --- /dev/null +++ b/openrtb_ext/imp_vidazoo.go @@ -0,0 +1,6 @@ +package openrtb_ext + +// ImpExtVidazoo defines the contract for bidrequest.imp[i].ext.prebid.bidder.vidazoo +type ImpExtVidazoo struct { + ConnectionId string `json:"cId"` +} diff --git a/openrtb_ext/multibid_test.go b/openrtb_ext/multibid_test.go index 926ab261b0f..5a552653119 100644 --- a/openrtb_ext/multibid_test.go +++ b/openrtb_ext/multibid_test.go @@ -4,7 +4,7 @@ import ( "fmt" "testing" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/openrtb_ext/regs_test.go b/openrtb_ext/regs_test.go index a32c0362a1c..064282c1f3f 100644 --- a/openrtb_ext/regs_test.go +++ b/openrtb_ext/regs_test.go @@ -3,7 +3,7 @@ package openrtb_ext import ( "testing" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/openrtb_ext/request.go b/openrtb_ext/request.go index b4f29a704d9..eb01098c097 100644 --- a/openrtb_ext/request.go +++ b/openrtb_ext/request.go @@ -7,8 +7,8 @@ import ( "slices" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/util/jsonutil" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/ptrutil" ) // FirstPartyDataExtKey defines a field name within request.ext and request.imp.ext reserved for first party data. diff --git a/openrtb_ext/request_test.go b/openrtb_ext/request_test.go index 81a12965307..c5f4abe22d4 100644 --- a/openrtb_ext/request_test.go +++ b/openrtb_ext/request_test.go @@ -6,8 +6,8 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/util/jsonutil" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/openrtb_ext/request_wrapper.go b/openrtb_ext/request_wrapper.go index 27c20e98f35..cb60948768f 100644 --- a/openrtb_ext/request_wrapper.go +++ b/openrtb_ext/request_wrapper.go @@ -7,8 +7,8 @@ import ( "slices" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/util/jsonutil" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/ptrutil" ) // RequestWrapper wraps the OpenRTB request to provide a storage location for unmarshalled ext fields, so they @@ -61,6 +61,7 @@ const ( schainKey = "schain" us_privacyKey = "us_privacy" cdepKey = "cdep" + gpcKey = "gpc" ) // LenImp returns the number of impressions without causing the creation of ImpWrapper objects. @@ -94,6 +95,12 @@ func (rw *RequestWrapper) GetImp() []*ImpWrapper { func (rw *RequestWrapper) SetImp(imps []*ImpWrapper) { rw.impWrappers = imps + imparr := make([]openrtb2.Imp, len(imps)) + for i, iw := range imps { + imparr[i] = *iw.Imp + iw.Imp = &imparr[i] + } + rw.Imp = imparr rw.impWrappersAccessed = true } @@ -238,6 +245,7 @@ func (rw *RequestWrapper) rebuildImp() error { return err } rw.Imp[i] = *rw.impWrappers[i].Imp + rw.impWrappers[i].Imp = &rw.Imp[i] } return nil @@ -391,6 +399,8 @@ func (rw *RequestWrapper) rebuildSourceExt() error { return nil } +// Clone clones the request wrapper exts and the imp wrappers +// the cloned imp wrappers are pointing to the bid request imps func (rw *RequestWrapper) Clone() *RequestWrapper { if rw == nil { return nil @@ -413,6 +423,26 @@ func (rw *RequestWrapper) Clone() *RequestWrapper { return &clone } +func (rw *RequestWrapper) CloneAndClearImpWrappers() *RequestWrapper { + if rw == nil { + return nil + } + rw.impWrappersAccessed = false + + clone := *rw + clone.impWrappers = nil + clone.userExt = rw.userExt.Clone() + clone.deviceExt = rw.deviceExt.Clone() + clone.requestExt = rw.requestExt.Clone() + clone.appExt = rw.appExt.Clone() + clone.regExt = rw.regExt.Clone() + clone.siteExt = rw.siteExt.Clone() + clone.doohExt = rw.doohExt.Clone() + clone.sourceExt = rw.sourceExt.Clone() + + return &clone +} + // --------------------------------------------------------------- // UserExt provides an interface for request.user.ext // --------------------------------------------------------------- @@ -1201,6 +1231,8 @@ type RegExt struct { dsaDirty bool gdpr *int8 gdprDirty bool + gpc *string + gpcDirty bool usPrivacy string usPrivacyDirty bool } @@ -1244,6 +1276,13 @@ func (re *RegExt) unmarshal(extJson json.RawMessage) error { } } + gpcJson, hasGPC := re.ext[gpcKey] + if hasGPC && gpcJson != nil { + if err := jsonutil.Unmarshal(gpcJson, &re.gpc); err != nil { + return err + } + } + return nil } @@ -1287,6 +1326,19 @@ func (re *RegExt) marshal() (json.RawMessage, error) { re.usPrivacyDirty = false } + if re.gpcDirty { + if re.gpc != nil { + rawjson, err := jsonutil.Marshal(re.gpc) + if err != nil { + return nil, err + } + re.ext[gpcKey] = rawjson + } else { + delete(re.ext, gpcKey) + } + re.gpcDirty = false + } + re.extDirty = false if len(re.ext) == 0 { return nil, nil @@ -1295,7 +1347,7 @@ func (re *RegExt) marshal() (json.RawMessage, error) { } func (re *RegExt) Dirty() bool { - return re.extDirty || re.dsaDirty || re.gdprDirty || re.usPrivacyDirty + return re.extDirty || re.dsaDirty || re.gdprDirty || re.usPrivacyDirty || re.gpcDirty } func (re *RegExt) GetExt() map[string]json.RawMessage { @@ -1337,6 +1389,19 @@ func (re *RegExt) SetGDPR(gdpr *int8) { re.gdprDirty = true } +func (re *RegExt) GetGPC() *string { + if re.gpc == nil { + return nil + } + gpc := *re.gpc + return &gpc +} + +func (re *RegExt) SetGPC(gpc *string) { + re.gpc = gpc + re.gpcDirty = true +} + func (re *RegExt) GetUSPrivacy() string { uSPrivacy := re.usPrivacy return uSPrivacy diff --git a/openrtb_ext/request_wrapper_test.go b/openrtb_ext/request_wrapper_test.go index 7b21531e02e..650a1efbe93 100644 --- a/openrtb_ext/request_wrapper_test.go +++ b/openrtb_ext/request_wrapper_test.go @@ -5,8 +5,8 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/util/ptrutil" "github.com/stretchr/testify/assert" ) @@ -198,6 +198,7 @@ func TestRebuildImp(t *testing.T) { request openrtb2.BidRequest requestImpWrapper []*ImpWrapper expectedRequest openrtb2.BidRequest + expectedAccessed bool expectedError string }{ { @@ -217,11 +218,13 @@ func TestRebuildImp(t *testing.T) { request: openrtb2.BidRequest{Imp: []openrtb2.Imp{{ID: "1"}}}, requestImpWrapper: []*ImpWrapper{{Imp: &openrtb2.Imp{ID: "2"}, impExt: &ImpExt{prebid: prebid, prebidDirty: true}}}, expectedRequest: openrtb2.BidRequest{Imp: []openrtb2.Imp{{ID: "2", Ext: prebidJson}}}, + expectedAccessed: true, }, { description: "One - Accessed - Error", request: openrtb2.BidRequest{Imp: []openrtb2.Imp{{ID: "1"}}}, requestImpWrapper: []*ImpWrapper{{Imp: nil, impExt: &ImpExt{}}}, + expectedAccessed: true, expectedError: "ImpWrapper RebuildImp called on a nil Imp", }, { @@ -229,6 +232,7 @@ func TestRebuildImp(t *testing.T) { request: openrtb2.BidRequest{Imp: []openrtb2.Imp{{ID: "1"}, {ID: "2"}}}, requestImpWrapper: []*ImpWrapper{{Imp: &openrtb2.Imp{ID: "1"}, impExt: &ImpExt{}}, {Imp: &openrtb2.Imp{ID: "2"}, impExt: &ImpExt{prebid: prebid, prebidDirty: true}}}, expectedRequest: openrtb2.BidRequest{Imp: []openrtb2.Imp{{ID: "1"}, {ID: "2", Ext: prebidJson}}}, + expectedAccessed: true, }, } @@ -247,6 +251,20 @@ func TestRebuildImp(t *testing.T) { assert.NoError(t, err, test.description) assert.Equal(t, test.expectedRequest, *w.BidRequest, test.description) } + + if test.expectedAccessed && test.expectedError == "" { + bidRequestImps := make(map[string]*openrtb2.Imp, 0) + for i, v := range w.Imp { + bidRequestImps[v.ID] = &w.Imp[i] + } + wrapperImps := make(map[string]*openrtb2.Imp, 0) + for i, v := range w.impWrappers { + wrapperImps[v.ID] = w.impWrappers[i].Imp + } + for k := range bidRequestImps { + assert.Same(t, bidRequestImps[k], wrapperImps[k], test.description) + } + } } } @@ -1866,6 +1884,37 @@ func TestImpWrapperGetImpExt(t *testing.T) { } } +func TestImpWrapperSetImp(t *testing.T) { + origImps := []openrtb2.Imp{ + {ID: "imp1", TagID: "tag1"}, + {ID: "imp2", TagID: "tag2"}, + {ID: "imp3", TagID: "tag3"}, + } + expectedImps := []openrtb2.Imp{ + {ID: "imp1", TagID: "tag4", BidFloor: 0.5}, + {ID: "imp1.1", TagID: "tag2", BidFloor: 0.6}, + {ID: "imp2", TagID: "notag"}, + {ID: "imp3", TagID: "tag3"}, + } + rw := RequestWrapper{BidRequest: &openrtb2.BidRequest{Imp: origImps}} + iw := rw.GetImp() + rw.Imp[0].TagID = "tag4" + rw.Imp[0].BidFloor = 0.5 + iw[1] = &ImpWrapper{Imp: &expectedImps[1]} + *iw[2] = ImpWrapper{Imp: &expectedImps[2]} + iw = append(iw, &ImpWrapper{Imp: &expectedImps[3]}) + + rw.SetImp(iw) + assert.Equal(t, expectedImps, rw.BidRequest.Imp) + iw = rw.GetImp() + // Ensure that the wrapper pointers are in sync. + for i := range rw.BidRequest.Imp { + // Assert the pointers are in sync. + assert.Same(t, &rw.Imp[i], iw[i].Imp) + } + +} + func TestImpExtTid(t *testing.T) { impExt := &ImpExt{} @@ -2174,6 +2223,30 @@ func TestRebuildRegExt(t *testing.T) { regExt: RegExt{usPrivacy: "", usPrivacyDirty: true}, expectedRequest: openrtb2.BidRequest{Regs: &openrtb2.Regs{}}, }, + { + name: "req_regs_gpc_populated_-_not_dirty_-_no_change", + request: openrtb2.BidRequest{Regs: &openrtb2.Regs{Ext: json.RawMessage(`{"gpc":"a"}`)}}, + regExt: RegExt{}, + expectedRequest: openrtb2.BidRequest{Regs: &openrtb2.Regs{Ext: json.RawMessage(`{"gpc":"a"}`)}}, + }, + { + name: "req_regs_gpc_populated_-_dirty_and_different-_change", + request: openrtb2.BidRequest{Regs: &openrtb2.Regs{Ext: json.RawMessage(`{"gpc":"a"}`)}}, + regExt: RegExt{gpc: &strB, gpcDirty: true}, + expectedRequest: openrtb2.BidRequest{Regs: &openrtb2.Regs{Ext: json.RawMessage(`{"gpc":"b"}`)}}, + }, + { + name: "req_regs_gpc_populated_-_dirty_and_same_-_no_change", + request: openrtb2.BidRequest{Regs: &openrtb2.Regs{Ext: json.RawMessage(`{"gpc":"a"}`)}}, + regExt: RegExt{gpc: &strA, gpcDirty: true}, + expectedRequest: openrtb2.BidRequest{Regs: &openrtb2.Regs{Ext: json.RawMessage(`{"gpc":"a"}`)}}, + }, + { + name: "req_regs_gpc_populated_-_dirty_and_nil_-_cleared", + request: openrtb2.BidRequest{Regs: &openrtb2.Regs{Ext: json.RawMessage(`{"gpc":"a"}`)}}, + regExt: RegExt{gpc: nil, gpcDirty: true}, + expectedRequest: openrtb2.BidRequest{Regs: &openrtb2.Regs{}}, + }, } for _, tt := range tests { @@ -2194,6 +2267,7 @@ func TestRegExtUnmarshal(t *testing.T) { extJson json.RawMessage expectDSA *ExtRegsDSA expectGDPR *int8 + expectGPC *string expectUSPrivacy string expectError bool }{ @@ -2253,6 +2327,21 @@ func TestRegExtUnmarshal(t *testing.T) { expectGDPR: ptrutil.ToPtr[int8](0), expectError: true, }, + // GPC + { + name: "valid_gpc_json", + regExt: &RegExt{}, + extJson: json.RawMessage(`{"gpc":"some_value"}`), + expectGPC: ptrutil.ToPtr("some_value"), + expectError: false, + }, + { + name: "malformed_gpc_json", + regExt: &RegExt{}, + extJson: json.RawMessage(`{"gpc":nill}`), + expectGPC: nil, + expectError: true, + }, // us_privacy { name: "valid_usprivacy_json", @@ -2348,3 +2437,18 @@ func TestRegExtGetGDPRSetGDPR(t *testing.T) { assert.Equal(t, regExtGDPR, gdpr) assert.NotSame(t, regExtGDPR, gdpr) } + +func TestRegExtGetGPCSetGPC(t *testing.T) { + regExt := &RegExt{} + regExtGPC := regExt.GetGPC() + assert.Nil(t, regExtGPC) + assert.False(t, regExt.Dirty()) + + gpc := ptrutil.ToPtr("Gpc") + regExt.SetGPC(gpc) + assert.True(t, regExt.Dirty()) + + regExtGPC = regExt.GetGPC() + assert.Equal(t, regExtGPC, gpc) + assert.NotSame(t, regExtGPC, gpc) +} diff --git a/openrtb_ext/response.go b/openrtb_ext/response.go index d9baea3f4da..449ff939bf5 100644 --- a/openrtb_ext/response.go +++ b/openrtb_ext/response.go @@ -132,14 +132,14 @@ type NonBidExt struct { // NonBid represnts the Non Bid Reason (statusCode) for given impression ID type NonBid struct { - ImpId string `json:"impid"` - StatusCode int `json:"statuscode"` - Ext NonBidExt `json:"ext"` + ImpId string `json:"impid"` + StatusCode int `json:"statuscode"` + Ext *NonBidExt `json:"ext,omitempty"` } // SeatNonBid is collection of NonBid objects with seat information type SeatNonBid struct { NonBid []NonBid `json:"nonbid"` Seat string `json:"seat"` - Ext json.RawMessage `json:"ext"` + Ext json.RawMessage `json:"ext,omitempty"` } diff --git a/openrtb_ext/site_test.go b/openrtb_ext/site_test.go index f6fb04c50ee..e06c0e67bd4 100644 --- a/openrtb_ext/site_test.go +++ b/openrtb_ext/site_test.go @@ -3,8 +3,8 @@ package openrtb_ext_test import ( "testing" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" "github.com/stretchr/testify/assert" ) diff --git a/openrtb_ext/supplyChain.go b/openrtb_ext/supplyChain.go index 1dc9cc3b359..0051d647ff9 100644 --- a/openrtb_ext/supplyChain.go +++ b/openrtb_ext/supplyChain.go @@ -2,7 +2,7 @@ package openrtb_ext import ( "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/util/ptrutil" ) func cloneSupplyChain(schain *openrtb2.SupplyChain) *openrtb2.SupplyChain { diff --git a/openrtb_ext/supplyChain_test.go b/openrtb_ext/supplyChain_test.go index 0ab67e87d67..1adfaf8f62b 100644 --- a/openrtb_ext/supplyChain_test.go +++ b/openrtb_ext/supplyChain_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/ortb/clone.go b/ortb/clone.go index 1e34795e05a..07eaf2886b7 100644 --- a/ortb/clone.go +++ b/ortb/clone.go @@ -4,7 +4,7 @@ import ( "slices" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/util/ptrutil" ) func CloneDataSlice(s []openrtb2.Data) []openrtb2.Data { @@ -277,3 +277,19 @@ func CloneBidRequestPartial(s *openrtb2.BidRequest) *openrtb2.BidRequest { return &c } + +func CloneRegs(s *openrtb2.Regs) *openrtb2.Regs { + if s == nil { + return nil + } + + // Shallow Copy (Value Fields) + c := *s + + // Deep Copy (Pointers) + c.GDPR = ptrutil.Clone(s.GDPR) + c.GPPSID = slices.Clone(s.GPPSID) + c.Ext = slices.Clone(s.Ext) + + return &c +} diff --git a/ortb/clone_test.go b/ortb/clone_test.go index 21c19f170c6..14bdc0bb194 100644 --- a/ortb/clone_test.go +++ b/ortb/clone_test.go @@ -7,7 +7,7 @@ import ( "github.com/prebid/openrtb/v20/adcom1" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/util/ptrutil" "github.com/stretchr/testify/assert" ) @@ -759,3 +759,44 @@ func discoverPointerFields(t reflect.Type) []string { } return fields } + +func TestCloneRegs(t *testing.T) { + t.Run("nil", func(t *testing.T) { + result := CloneRegs(nil) + assert.Nil(t, result) + }) + + t.Run("empty", func(t *testing.T) { + given := &openrtb2.Regs{} + result := CloneRegs(given) + assert.Empty(t, result) + assert.NotSame(t, given, result) + }) + + t.Run("populated", func(t *testing.T) { + given := &openrtb2.Regs{ + COPPA: 1, + GDPR: ptrutil.ToPtr(int8(0)), + USPrivacy: "1YNN", + GPP: "SomeGPPStrig", + GPPSID: []int8{1, 2, 3}, + Ext: json.RawMessage(`{"anyField":1}`), + } + result := CloneRegs(given) + assert.Equal(t, given, result, "equality") + assert.NotSame(t, given, result, "pointer") + assert.NotSame(t, given.GDPR, result.GDPR, "gdpr") + assert.NotSame(t, given.GPPSID, result.GPPSID, "gppsid[]") + assert.NotSame(t, given.GPPSID[0], result.GPPSID[0], "gppsid[0]") + assert.NotSame(t, given.Ext, result.Ext, "ext") + }) + + t.Run("assumptions", func(t *testing.T) { + assert.ElementsMatch(t, discoverPointerFields(reflect.TypeOf(openrtb2.Regs{})), + []string{ + "GDPR", + "GPPSID", + "Ext", + }) + }) +} diff --git a/ortb/default.go b/ortb/default.go index c5e43e2e770..4a25051e78a 100644 --- a/ortb/default.go +++ b/ortb/default.go @@ -1,8 +1,8 @@ package ortb import ( - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/ptrutil" ) const ( diff --git a/ortb/default_test.go b/ortb/default_test.go index 7017f5f2114..a52fc508cb7 100644 --- a/ortb/default_test.go +++ b/ortb/default_test.go @@ -8,10 +8,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/jsonutil" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/ptrutil" ) func TestSetDefaults(t *testing.T) { diff --git a/ortb/request_validator.go b/ortb/request_validator.go index efe047f986f..c7cc0a4ee9b 100644 --- a/ortb/request_validator.go +++ b/ortb/request_validator.go @@ -4,9 +4,9 @@ import ( "encoding/json" "fmt" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/stored_responses" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/stored_responses" ) type ValidationConfig struct { diff --git a/ortb/request_validator_banner.go b/ortb/request_validator_banner.go index 55197c5636b..fea68121a9a 100644 --- a/ortb/request_validator_banner.go +++ b/ortb/request_validator_banner.go @@ -4,7 +4,7 @@ import ( "fmt" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) func isInterstitial(imp *openrtb_ext.ImpWrapper) bool { diff --git a/ortb/request_validator_banner_test.go b/ortb/request_validator_banner_test.go index ea3ec3a008e..e131c32e98e 100644 --- a/ortb/request_validator_banner_test.go +++ b/ortb/request_validator_banner_test.go @@ -4,7 +4,7 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/ortb/request_validator_native.go b/ortb/request_validator_native.go index 02c0c606e97..1209a13913f 100644 --- a/ortb/request_validator_native.go +++ b/ortb/request_validator_native.go @@ -8,8 +8,8 @@ import ( "github.com/prebid/openrtb/v20/native1" nativeRequests "github.com/prebid/openrtb/v20/native1/request" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) // fillAndValidateNative validates the request, and assigns the Asset IDs as recommended by the Native v1.2 spec. diff --git a/ortb/request_validator_test.go b/ortb/request_validator_test.go index 1eb0708fcc8..abceda31efb 100644 --- a/ortb/request_validator_test.go +++ b/ortb/request_validator_test.go @@ -6,8 +6,8 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/ortb/request_validator_video_test.go b/ortb/request_validator_video_test.go index 10dbfee4967..3d579e2c77c 100644 --- a/ortb/request_validator_video_test.go +++ b/ortb/request_validator_video_test.go @@ -4,7 +4,7 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/pbs/usersync.go b/pbs/usersync.go index bfe12689177..b8c0572c4ac 100644 --- a/pbs/usersync.go +++ b/pbs/usersync.go @@ -10,9 +10,9 @@ import ( "github.com/golang/glog" "github.com/julienschmidt/httprouter" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/server/ssl" - "github.com/prebid/prebid-server/v2/usersync" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/server/ssl" + "github.com/prebid/prebid-server/v3/usersync" ) // Recaptcha code from https://github.com/haisum/recaptcha/blob/master/recaptcha.go diff --git a/prebid_cache_client/client.go b/prebid_cache_client/client.go index fb3fb24d9cc..a409b4f7d1a 100644 --- a/prebid_cache_client/client.go +++ b/prebid_cache_client/client.go @@ -12,8 +12,8 @@ import ( "strings" "time" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/metrics" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/metrics" "github.com/buger/jsonparser" "github.com/golang/glog" diff --git a/prebid_cache_client/client_test.go b/prebid_cache_client/client_test.go index f3ee3065ff1..f00a835a4a0 100644 --- a/prebid_cache_client/client_test.go +++ b/prebid_cache_client/client_test.go @@ -10,10 +10,10 @@ import ( "strconv" "testing" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/metrics" - metricsConf "github.com/prebid/prebid-server/v2/metrics/config" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/metrics" + metricsConf "github.com/prebid/prebid-server/v3/metrics/config" + "github.com/prebid/prebid-server/v3/util/jsonutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" diff --git a/privacy/activitycontrol.go b/privacy/activitycontrol.go index 7d1e16e99a5..674d7519881 100644 --- a/privacy/activitycontrol.go +++ b/privacy/activitycontrol.go @@ -1,8 +1,8 @@ package privacy import ( - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" ) type ActivityResult int diff --git a/privacy/activitycontrol_test.go b/privacy/activitycontrol_test.go index 5cd9f38b011..add20ad2c3e 100644 --- a/privacy/activitycontrol_test.go +++ b/privacy/activitycontrol_test.go @@ -3,9 +3,9 @@ package privacy import ( "testing" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/privacy/ccpa/consentwriter.go b/privacy/ccpa/consentwriter.go index 265d47e8595..3a0934c5722 100644 --- a/privacy/ccpa/consentwriter.go +++ b/privacy/ccpa/consentwriter.go @@ -2,7 +2,6 @@ package ccpa import ( "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/openrtb_ext" ) // ConsentWriter implements the old PolicyWriter interface for CCPA. @@ -16,16 +15,14 @@ func (c ConsentWriter) Write(req *openrtb2.BidRequest) error { if req == nil { return nil } - reqWrap := &openrtb_ext.RequestWrapper{BidRequest: req} // Set consent string in USPrivacy if c.Consent != "" { - if regsExt, err := reqWrap.GetRegExt(); err == nil { - regsExt.SetUSPrivacy(c.Consent) - } else { - return err + if req.Regs == nil { + req.Regs = &openrtb2.Regs{} } + req.Regs.USPrivacy = c.Consent } - return reqWrap.RebuildRequest() + return nil } diff --git a/privacy/ccpa/consentwriter_test.go b/privacy/ccpa/consentwriter_test.go index a92400dce53..6d0b89e24c2 100644 --- a/privacy/ccpa/consentwriter_test.go +++ b/privacy/ccpa/consentwriter_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) @@ -75,7 +75,9 @@ func TestConsentWriterLegacy(t *testing.T) { description: "Success", request: &openrtb2.BidRequest{}, expected: &openrtb2.BidRequest{ - Regs: &openrtb2.Regs{Ext: json.RawMessage(`{"us_privacy":"anyConsent"}`)}, + Regs: &openrtb2.Regs{ + USPrivacy: "anyConsent", + }, }, }, { @@ -83,9 +85,12 @@ func TestConsentWriterLegacy(t *testing.T) { request: &openrtb2.BidRequest{ Regs: &openrtb2.Regs{Ext: json.RawMessage(`malformed}`)}, }, - expectedError: true, + expectedError: false, expected: &openrtb2.BidRequest{ - Regs: &openrtb2.Regs{Ext: json.RawMessage(`malformed}`)}, + Regs: &openrtb2.Regs{ + USPrivacy: "anyConsent", + Ext: json.RawMessage(`malformed}`), + }, }, }, } diff --git a/privacy/ccpa/parsedpolicy.go b/privacy/ccpa/parsedpolicy.go index 056cc99ee1b..98b04a16322 100644 --- a/privacy/ccpa/parsedpolicy.go +++ b/privacy/ccpa/parsedpolicy.go @@ -4,7 +4,7 @@ import ( "errors" "fmt" - "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v3/errortypes" ) const ( diff --git a/privacy/ccpa/policy.go b/privacy/ccpa/policy.go index 0b719bf1455..b4841a174f8 100644 --- a/privacy/ccpa/policy.go +++ b/privacy/ccpa/policy.go @@ -7,9 +7,9 @@ import ( gpplib "github.com/prebid/go-gpp" gppConstants "github.com/prebid/go-gpp/constants" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/openrtb_ext" - gppPolicy "github.com/prebid/prebid-server/v2/privacy/gpp" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + gppPolicy "github.com/prebid/prebid-server/v3/privacy/gpp" ) // Policy represents the CCPA regulatory information from an OpenRTB bid request. @@ -41,15 +41,8 @@ func ReadFromRequestWrapper(req *openrtb_ext.RequestWrapper, gpp gpplib.GppConta WarningCode: errortypes.InvalidPrivacyConsentWarningCode} } - if consent == "" { - // Read consent from request.regs.ext - regsExt, err := req.GetRegExt() - if err != nil { - return Policy{}, fmt.Errorf("error reading request.regs.ext: %s", err) - } - if regsExt != nil { - consent = regsExt.GetUSPrivacy() - } + if consent == "" && req.Regs != nil { + consent = req.Regs.USPrivacy } // Read no sale bidders from request.ext.prebid reqExt, err := req.GetRequestExt() @@ -75,21 +68,19 @@ func ReadFromRequest(req *openrtb2.BidRequest) (Policy, error) { // Write mutates an OpenRTB bid request with the CCPA regulatory information. func (p Policy) Write(req *openrtb_ext.RequestWrapper) error { - if req == nil { + if req == nil || req.BidRequest == nil { return nil } - regsExt, err := req.GetRegExt() - if err != nil { - return err - } - reqExt, err := req.GetRequestExt() if err != nil { return err } - regsExt.SetUSPrivacy(p.Consent) + if req.Regs == nil { + req.Regs = &openrtb2.Regs{} + } + req.Regs.USPrivacy = p.Consent setPrebidNoSale(p.NoSaleBidders, reqExt) return nil } diff --git a/privacy/ccpa/policy_test.go b/privacy/ccpa/policy_test.go index 20d9f680ba1..89bb2ccf040 100644 --- a/privacy/ccpa/policy_test.go +++ b/privacy/ccpa/policy_test.go @@ -8,7 +8,7 @@ import ( gpplib "github.com/prebid/go-gpp" gppConstants "github.com/prebid/go-gpp/constants" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) @@ -23,7 +23,7 @@ func TestReadFromRequestWrapper(t *testing.T) { { description: "Success", request: &openrtb2.BidRequest{ - Regs: &openrtb2.Regs{Ext: json.RawMessage(`{"us_privacy":"ABC"}`)}, + Regs: &openrtb2.Regs{USPrivacy: "ABC"}, Ext: json.RawMessage(`{"prebid":{"nosale":["a", "b"]}}`), }, expectedPolicy: Policy{ @@ -83,26 +83,10 @@ func TestReadFromRequestWrapper(t *testing.T) { NoSaleBidders: []string{"a", "b"}, }, }, - { - description: "Malformed Regs.Ext", - request: &openrtb2.BidRequest{ - Regs: &openrtb2.Regs{Ext: json.RawMessage(`malformed`)}, - Ext: json.RawMessage(`{"prebid":{"nosale":["a", "b"]}}`), - }, - expectedError: true, - }, - { - description: "Invalid Regs.Ext Type", - request: &openrtb2.BidRequest{ - Regs: &openrtb2.Regs{Ext: json.RawMessage(`{"us_privacy":123`)}, - Ext: json.RawMessage(`{"prebid":{"nosale":["a", "b"]}}`), - }, - expectedError: true, - }, { description: "Nil Ext", request: &openrtb2.BidRequest{ - Regs: &openrtb2.Regs{Ext: json.RawMessage(`{"us_privacy":"ABC"}`)}, + Regs: &openrtb2.Regs{USPrivacy: "ABC"}, Ext: nil, }, expectedPolicy: Policy{ @@ -113,7 +97,7 @@ func TestReadFromRequestWrapper(t *testing.T) { { description: "Empty Ext", request: &openrtb2.BidRequest{ - Regs: &openrtb2.Regs{Ext: json.RawMessage(`{"us_privacy":"ABC"}`)}, + Regs: &openrtb2.Regs{USPrivacy: "ABC"}, Ext: json.RawMessage(`{}`), }, expectedPolicy: Policy{ @@ -124,7 +108,7 @@ func TestReadFromRequestWrapper(t *testing.T) { { description: "Missing Ext.Prebid No Sale Value", request: &openrtb2.BidRequest{ - Regs: &openrtb2.Regs{Ext: json.RawMessage(`{"us_privacy":"ABC"}`)}, + Regs: &openrtb2.Regs{USPrivacy: "ABC"}, Ext: json.RawMessage(`{"anythingElse":"42"}`), }, expectedPolicy: Policy{ @@ -148,15 +132,6 @@ func TestReadFromRequestWrapper(t *testing.T) { }, expectedError: true, }, - { - description: "Injection Attack", - request: &openrtb2.BidRequest{ - Regs: &openrtb2.Regs{Ext: json.RawMessage(`{"us_privacy":"1YYY\"},\"oops\":\"malicious\",\"p\":{\"p\":\""}`)}, - }, - expectedPolicy: Policy{ - Consent: "1YYY\"},\"oops\":\"malicious\",\"p\":{\"p\":\"", - }, - }, { description: "GPP Success", request: &openrtb2.BidRequest{ @@ -244,7 +219,7 @@ func TestReadFromRequest(t *testing.T) { { description: "Success", request: &openrtb2.BidRequest{ - Regs: &openrtb2.Regs{Ext: json.RawMessage(`{"us_privacy":"ABC"}`)}, + Regs: &openrtb2.Regs{USPrivacy: "ABC"}, Ext: json.RawMessage(`{"prebid":{"nosale":["a", "b"]}}`), }, expectedPolicy: Policy{ @@ -353,7 +328,7 @@ func TestWrite(t *testing.T) { policy: Policy{Consent: "anyConsent", NoSaleBidders: []string{"a", "b"}}, request: &openrtb2.BidRequest{}, expected: &openrtb2.BidRequest{ - Regs: &openrtb2.Regs{Ext: json.RawMessage(`{"us_privacy":"anyConsent"}`)}, + Regs: &openrtb2.Regs{USPrivacy: "anyConsent"}, Ext: json.RawMessage(`{"prebid":{"nosale":["a","b"]}}`), }, }, diff --git a/privacy/gdpr/consentwriter.go b/privacy/gdpr/consentwriter.go index 243a6cf79e9..8269352355d 100644 --- a/privacy/gdpr/consentwriter.go +++ b/privacy/gdpr/consentwriter.go @@ -2,13 +2,12 @@ package gdpr import ( "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/openrtb_ext" ) // ConsentWriter implements the PolicyWriter interface for GDPR TCF. type ConsentWriter struct { - Consent string - RegExtGDPR *int8 + Consent string + GDPR *int8 } // Write mutates an OpenRTB bid request with the GDPR TCF consent. @@ -16,26 +15,19 @@ func (c ConsentWriter) Write(req *openrtb2.BidRequest) error { if req == nil { return nil } - reqWrap := &openrtb_ext.RequestWrapper{BidRequest: req} - if c.RegExtGDPR != nil { - if regsExt, err := reqWrap.GetRegExt(); err == nil { - regsExt.SetGDPR(c.RegExtGDPR) - } else { - return err + if c.GDPR != nil { + if req.Regs == nil { + req.Regs = &openrtb2.Regs{} } + req.Regs.GDPR = c.GDPR } if c.Consent != "" { - if userExt, err := reqWrap.GetUserExt(); err == nil { - userExt.SetConsent(&c.Consent) - } else { - return err + if req.User == nil { + req.User = &openrtb2.User{} } - } - - if err := reqWrap.RebuildRequest(); err != nil { - return err + req.User.Consent = c.Consent } return nil diff --git a/privacy/gdpr/consentwriter_test.go b/privacy/gdpr/consentwriter_test.go index 47f24bc9ecc..436f46dd563 100644 --- a/privacy/gdpr/consentwriter_test.go +++ b/privacy/gdpr/consentwriter_test.go @@ -27,14 +27,14 @@ func TestConsentWriter(t *testing.T) { consent: "anyConsent", request: &openrtb2.BidRequest{}, expected: &openrtb2.BidRequest{User: &openrtb2.User{ - Ext: json.RawMessage(`{"consent":"anyConsent"}`)}}, + Consent: "anyConsent"}}, }, { description: "Enabled With Nil Request User Ext Object", consent: "anyConsent", request: &openrtb2.BidRequest{User: &openrtb2.User{}}, expected: &openrtb2.BidRequest{User: &openrtb2.User{ - Ext: json.RawMessage(`{"consent":"anyConsent"}`)}}, + Consent: "anyConsent"}}, }, { description: "Enabled With Existing Request User Ext Object - Doesn't Overwrite", @@ -42,29 +42,25 @@ func TestConsentWriter(t *testing.T) { request: &openrtb2.BidRequest{User: &openrtb2.User{ Ext: json.RawMessage(`{"existing":"any"}`)}}, expected: &openrtb2.BidRequest{User: &openrtb2.User{ - Ext: json.RawMessage(`{"consent":"anyConsent","existing":"any"}`)}}, + Consent: "anyConsent", + Ext: json.RawMessage(`{"existing":"any"}`)}}, }, { description: "Enabled With Existing Request User Ext Object - Overwrites", consent: "anyConsent", request: &openrtb2.BidRequest{User: &openrtb2.User{ - Ext: json.RawMessage(`{"existing":"any","consent":"toBeOverwritten"}`)}}, + Consent: "toBeOverwritten", + Ext: json.RawMessage(`{"existing":"any"}`)}}, expected: &openrtb2.BidRequest{User: &openrtb2.User{ - Ext: json.RawMessage(`{"consent":"anyConsent","existing":"any"}`)}}, - }, - { - description: "Enabled With Existing Malformed Request User Ext Object", - consent: "anyConsent", - request: &openrtb2.BidRequest{User: &openrtb2.User{ - Ext: json.RawMessage(`malformed`)}}, - expectedError: true, + Consent: "anyConsent", + Ext: json.RawMessage(`{"existing":"any"}`)}}, }, { description: "Injection Attack With Nil Request User Object", consent: "BONV8oqONXwgmADACHENAO7pqzAAppY\"},\"oops\":\"malicious\",\"p\":{\"p\":\"", request: &openrtb2.BidRequest{}, expected: &openrtb2.BidRequest{User: &openrtb2.User{ - Ext: json.RawMessage(`{"consent":"BONV8oqONXwgmADACHENAO7pqzAAppY\"},\"oops\":\"malicious\",\"p\":{\"p\":\""}`), + Consent: "BONV8oqONXwgmADACHENAO7pqzAAppY\"},\"oops\":\"malicious\",\"p\":{\"p\":\"", }}, }, { @@ -72,7 +68,8 @@ func TestConsentWriter(t *testing.T) { consent: "BONV8oqONXwgmADACHENAO7pqzAAppY\"},\"oops\":\"malicious\",\"p\":{\"p\":\"", request: &openrtb2.BidRequest{User: &openrtb2.User{}}, expected: &openrtb2.BidRequest{User: &openrtb2.User{ - Ext: json.RawMessage(`{"consent":"BONV8oqONXwgmADACHENAO7pqzAAppY\"},\"oops\":\"malicious\",\"p\":{\"p\":\""}`), + Consent: "BONV8oqONXwgmADACHENAO7pqzAAppY\"},\"oops\":\"malicious\",\"p\":{\"p\":\"", + Ext: nil, }}, }, { @@ -82,7 +79,8 @@ func TestConsentWriter(t *testing.T) { Ext: json.RawMessage(`{"existing":"any"}`), }}, expected: &openrtb2.BidRequest{User: &openrtb2.User{ - Ext: json.RawMessage(`{"consent":"BONV8oqONXwgmADACHENAO7pqzAAppY\"},\"oops\":\"malicious\",\"p\":{\"p\":\"","existing":"any"}`), + Consent: "BONV8oqONXwgmADACHENAO7pqzAAppY\"},\"oops\":\"malicious\",\"p\":{\"p\":\"", + Ext: json.RawMessage(`{"existing":"any"}`), }}, }, } diff --git a/privacy/lmt/ios.go b/privacy/lmt/ios.go index b7cb836cfe4..7778a02d0a5 100644 --- a/privacy/lmt/ios.go +++ b/privacy/lmt/ios.go @@ -4,8 +4,8 @@ import ( "strings" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/iosutil" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/iosutil" ) var ( diff --git a/privacy/lmt/ios_test.go b/privacy/lmt/ios_test.go index 83b59b287fd..42636759eb1 100644 --- a/privacy/lmt/ios_test.go +++ b/privacy/lmt/ios_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/util/iosutil" + "github.com/prebid/prebid-server/v3/util/iosutil" "github.com/stretchr/testify/assert" ) diff --git a/privacy/rule_condition_test.go b/privacy/rule_condition_test.go index a0b3f855951..97bdeef35fd 100644 --- a/privacy/rule_condition_test.go +++ b/privacy/rule_condition_test.go @@ -4,7 +4,7 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/openrtb_ext" + "github.com/prebid/prebid-server/v3/openrtb_ext" "github.com/stretchr/testify/assert" ) diff --git a/privacy/scrubber.go b/privacy/scrubber.go index 7a67737f028..8f4a9b103f6 100644 --- a/privacy/scrubber.go +++ b/privacy/scrubber.go @@ -4,12 +4,12 @@ import ( "encoding/json" "net" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/jsonutil" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/iputil" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/iputil" ) type IPConf struct { diff --git a/privacy/scrubber_test.go b/privacy/scrubber_test.go index d06e0c9842e..ccb065bccbc 100644 --- a/privacy/scrubber_test.go +++ b/privacy/scrubber_test.go @@ -5,8 +5,8 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/ptrutil" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/ptrutil" "github.com/stretchr/testify/assert" ) diff --git a/privacysandbox/topics.go b/privacysandbox/topics.go index 4c129d0a535..3ed620b4bdd 100644 --- a/privacysandbox/topics.go +++ b/privacysandbox/topics.go @@ -8,8 +8,8 @@ import ( "strings" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/util/jsonutil" ) type Topic struct { diff --git a/privacysandbox/topics_test.go b/privacysandbox/topics_test.go index 90a46f770c6..73d5ef0c12f 100644 --- a/privacysandbox/topics_test.go +++ b/privacysandbox/topics_test.go @@ -6,7 +6,7 @@ import ( "testing" "github.com/prebid/openrtb/v20/openrtb2" - "github.com/prebid/prebid-server/v2/errortypes" + "github.com/prebid/prebid-server/v3/errortypes" "github.com/stretchr/testify/assert" ) diff --git a/router/admin.go b/router/admin.go index 1be7c8656da..a90e5f233d9 100644 --- a/router/admin.go +++ b/router/admin.go @@ -5,9 +5,9 @@ import ( "net/http/pprof" "time" - "github.com/prebid/prebid-server/v2/currency" - "github.com/prebid/prebid-server/v2/endpoints" - "github.com/prebid/prebid-server/v2/version" + "github.com/prebid/prebid-server/v3/currency" + "github.com/prebid/prebid-server/v3/endpoints" + "github.com/prebid/prebid-server/v3/version" ) func Admin(rateConverter *currency.RateConverter, rateConverterFetchingInterval time.Duration) *http.ServeMux { diff --git a/router/aspects/request_timeout_handler.go b/router/aspects/request_timeout_handler.go index 7b94c96b11b..0a4d147d908 100644 --- a/router/aspects/request_timeout_handler.go +++ b/router/aspects/request_timeout_handler.go @@ -6,8 +6,8 @@ import ( "time" "github.com/julienschmidt/httprouter" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/metrics" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/metrics" ) func QueuedRequestTimeout(f httprouter.Handle, reqTimeoutHeaders config.RequestTimeoutHeaders, metricsEngine metrics.MetricsEngine, requestType metrics.RequestType) httprouter.Handle { diff --git a/router/aspects/request_timeout_handler_test.go b/router/aspects/request_timeout_handler_test.go index 0d6f2cf8114..2ac8f36ae35 100644 --- a/router/aspects/request_timeout_handler_test.go +++ b/router/aspects/request_timeout_handler_test.go @@ -8,8 +8,8 @@ import ( "time" "github.com/julienschmidt/httprouter" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/metrics" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/metrics" "github.com/stretchr/testify/assert" ) diff --git a/router/router.go b/router/router.go index 0712f6723dc..d412b5152e2 100644 --- a/router/router.go +++ b/router/router.go @@ -10,35 +10,36 @@ import ( "strings" "time" - analyticsBuild "github.com/prebid/prebid-server/v2/analytics/build" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/currency" - "github.com/prebid/prebid-server/v2/endpoints" - "github.com/prebid/prebid-server/v2/endpoints/events" - infoEndpoints "github.com/prebid/prebid-server/v2/endpoints/info" - "github.com/prebid/prebid-server/v2/endpoints/openrtb2" - "github.com/prebid/prebid-server/v2/errortypes" - "github.com/prebid/prebid-server/v2/exchange" - "github.com/prebid/prebid-server/v2/experiment/adscert" - "github.com/prebid/prebid-server/v2/floors" - "github.com/prebid/prebid-server/v2/gdpr" - "github.com/prebid/prebid-server/v2/hooks" - "github.com/prebid/prebid-server/v2/macros" - "github.com/prebid/prebid-server/v2/metrics" - metricsConf "github.com/prebid/prebid-server/v2/metrics/config" - "github.com/prebid/prebid-server/v2/modules" - "github.com/prebid/prebid-server/v2/modules/moduledeps" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/ortb" - "github.com/prebid/prebid-server/v2/pbs" - pbc "github.com/prebid/prebid-server/v2/prebid_cache_client" - "github.com/prebid/prebid-server/v2/router/aspects" - "github.com/prebid/prebid-server/v2/server/ssl" - storedRequestsConf "github.com/prebid/prebid-server/v2/stored_requests/config" - "github.com/prebid/prebid-server/v2/usersync" - "github.com/prebid/prebid-server/v2/util/jsonutil" - "github.com/prebid/prebid-server/v2/util/uuidutil" - "github.com/prebid/prebid-server/v2/version" + openrtb2model "github.com/prebid/openrtb/v20/openrtb2" + analyticsBuild "github.com/prebid/prebid-server/v3/analytics/build" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/currency" + "github.com/prebid/prebid-server/v3/endpoints" + "github.com/prebid/prebid-server/v3/endpoints/events" + infoEndpoints "github.com/prebid/prebid-server/v3/endpoints/info" + "github.com/prebid/prebid-server/v3/endpoints/openrtb2" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/exchange" + "github.com/prebid/prebid-server/v3/experiment/adscert" + "github.com/prebid/prebid-server/v3/floors" + "github.com/prebid/prebid-server/v3/gdpr" + "github.com/prebid/prebid-server/v3/hooks" + "github.com/prebid/prebid-server/v3/macros" + "github.com/prebid/prebid-server/v3/metrics" + metricsConf "github.com/prebid/prebid-server/v3/metrics/config" + "github.com/prebid/prebid-server/v3/modules" + "github.com/prebid/prebid-server/v3/modules/moduledeps" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/ortb" + "github.com/prebid/prebid-server/v3/pbs" + pbc "github.com/prebid/prebid-server/v3/prebid_cache_client" + "github.com/prebid/prebid-server/v3/router/aspects" + "github.com/prebid/prebid-server/v3/server/ssl" + storedRequestsConf "github.com/prebid/prebid-server/v3/stored_requests/config" + "github.com/prebid/prebid-server/v3/usersync" + "github.com/prebid/prebid-server/v3/util/jsonutil" + "github.com/prebid/prebid-server/v3/util/uuidutil" + "github.com/prebid/prebid-server/v3/version" _ "github.com/go-sql-driver/mysql" "github.com/golang/glog" @@ -57,11 +58,11 @@ import ( // // This function stores the file contents in memory, and should not be used on large directories. // If the root directory, or any of the files in it, cannot be read, then the program will exit. -func NewJsonDirectoryServer(schemaDirectory string, validator openrtb_ext.BidderParamValidator, aliases map[string]string) httprouter.Handle { - return newJsonDirectoryServer(schemaDirectory, validator, aliases, openrtb_ext.GetAliasBidderToParent()) +func NewJsonDirectoryServer(schemaDirectory string, validator openrtb_ext.BidderParamValidator) httprouter.Handle { + return newJsonDirectoryServer(schemaDirectory, validator, openrtb_ext.GetAliasBidderToParent()) } -func newJsonDirectoryServer(schemaDirectory string, validator openrtb_ext.BidderParamValidator, aliases map[string]string, yamlAliases map[openrtb_ext.BidderName]openrtb_ext.BidderName) httprouter.Handle { +func newJsonDirectoryServer(schemaDirectory string, validator openrtb_ext.BidderParamValidator, aliases map[openrtb_ext.BidderName]openrtb_ext.BidderName) httprouter.Handle { // Slurp the files into memory first, since they're small and it minimizes request latency. files, err := os.ReadDir(schemaDirectory) if err != nil { @@ -81,19 +82,10 @@ func newJsonDirectoryServer(schemaDirectory string, validator openrtb_ext.Bidder } // Add in any aliases - for aliasName, parentBidder := range yamlAliases { + for aliasName, parentBidder := range aliases { data[string(aliasName)] = json.RawMessage(validator.Schema(parentBidder)) } - // Add in any default aliases - for aliasName, bidderName := range aliases { - bidderData, ok := data[bidderName] - if !ok { - glog.Fatalf("Default alias (%s) exists referencing unknown bidder: %s", aliasName, bidderName) - } - data[aliasName] = bidderData - } - response, err := jsonutil.Marshal(data) if err != nil { glog.Fatalf("Failed to marshal bidder param JSON-schema: %v", err) @@ -124,7 +116,8 @@ type Router struct { *httprouter.Router MetricsEngine *metricsConf.DetailedMetricsEngine ParamsValidator openrtb_ext.BidderParamValidator - Shutdown func() + + shutdowns []func() } func New(cfg *config.Configuration, rateConvertor *currency.RateConverter) (r *Router, err error) { @@ -201,11 +194,12 @@ func New(cfg *config.Configuration, rateConvertor *currency.RateConverter) (r *R // Metrics engine r.MetricsEngine = metricsConf.NewMetricsEngine(cfg, openrtb_ext.CoreBidderNames(), syncerKeys, moduleStageNames) shutdown, fetcher, ampFetcher, accounts, categoriesFetcher, videoFetcher, storedRespFetcher := storedRequestsConf.NewStoredRequests(cfg, r.MetricsEngine, generalHttpClient, r.Router) - // todo(zachbadgett): better shutdown - r.Shutdown = shutdown analyticsRunner := analyticsBuild.New(&cfg.Analytics) + // register the analytics runner for shutdown + r.shutdowns = append(r.shutdowns, shutdown, analyticsRunner.Shutdown) + paramsValidator, err := openrtb_ext.NewBidderParamsValidator(schemaDirectory) if err != nil { glog.Fatalf("Failed to create the bidder params validator. %v", err) @@ -214,10 +208,7 @@ func New(cfg *config.Configuration, rateConvertor *currency.RateConverter) (r *R activeBidders := exchange.GetActiveBidders(cfg.BidderInfos) disabledBidders := exchange.GetDisabledBidderWarningMessages(cfg.BidderInfos) - defaultAliases, defReqJSON := readDefaultRequest(cfg.DefReqConfig) - if err := validateDefaultAliases(defaultAliases); err != nil { - return nil, err - } + defReqJSON := readDefaultRequest(cfg.DefReqConfig) gvlVendorIDs := cfg.BidderInfos.ToGVLVendorIDMap() vendorListFetcher := gdpr.NewVendorListFetcher(context.Background(), cfg.GDPR, generalHttpClient, gdpr.VendorListURLMaker) @@ -267,9 +258,9 @@ func New(cfg *config.Configuration, rateConvertor *currency.RateConverter) (r *R r.POST("/openrtb2/auction", openrtbEndpoint) r.POST("/openrtb2/video", videoEndpoint) r.GET("/openrtb2/amp", ampEndpoint) - r.GET("/info/bidders", infoEndpoints.NewBiddersEndpoint(cfg.BidderInfos, defaultAliases)) - r.GET("/info/bidders/:bidderName", infoEndpoints.NewBiddersDetailEndpoint(cfg.BidderInfos, defaultAliases)) - r.GET("/bidders/params", NewJsonDirectoryServer(schemaDirectory, paramsValidator, defaultAliases)) + r.GET("/info/bidders", infoEndpoints.NewBiddersEndpoint(cfg.BidderInfos)) + r.GET("/info/bidders/:bidderName", infoEndpoints.NewBiddersDetailEndpoint(cfg.BidderInfos)) + r.GET("/bidders/params", NewJsonDirectoryServer(schemaDirectory, paramsValidator)) r.POST("/cookie_sync", endpoints.NewCookieSyncEndpoint(syncersByBidder, cfg, gdprPermsBuilder, tcf2CfgBuilder, r.MetricsEngine, analyticsRunner, accounts, activeBidders).Handle) r.GET("/status", endpoints.NewStatusEndpoint(cfg.StatusResponse)) r.GET("/", serveIndex) @@ -301,6 +292,15 @@ func New(cfg *config.Configuration, rateConvertor *currency.RateConverter) (r *R return r, nil } +// Shutdown closes any dependencies of the router that may need closing +func (r *Router) Shutdown() { + glog.Info("[PBS Router] shutting down") + for _, shutdown := range r.shutdowns { + shutdown() + } + glog.Info("[PBS Router] shut down") +} + func checkSupportedUserSyncEndpoints(bidderInfos config.BidderInfos) error { for name, info := range bidderInfos { if info.Syncer == nil { @@ -351,56 +351,31 @@ func SupportCORS(handler http.Handler) http.Handler { return c.Handler(handler) } -type defReq struct { - Ext defExt `json:"ext"` -} -type defExt struct { - Prebid defaultAliases `json:"prebid"` -} -type defaultAliases struct { - Aliases map[string]string `json:"aliases"` -} - -func readDefaultRequest(defReqConfig config.DefReqConfig) (map[string]string, []byte) { - defReq := &defReq{} - aliases := make(map[string]string) - if defReqConfig.Type == "file" { - if len(defReqConfig.FileSystem.FileName) == 0 { - return aliases, []byte{} - } - defReqJSON, err := os.ReadFile(defReqConfig.FileSystem.FileName) - if err != nil { - glog.Fatalf("error reading aliases from file %s: %v", defReqConfig.FileSystem.FileName, err) - return aliases, []byte{} - } - - if err := jsonutil.UnmarshalValid(defReqJSON, defReq); err != nil { - // we might not have aliases defined, but will at least show that the JSON file is parsable. - glog.Fatalf("error parsing alias json in file %s: %v", defReqConfig.FileSystem.FileName, err) - return aliases, []byte{} - } - - // Read in the alias map if we want to populate the info endpoints with aliases. - if defReqConfig.AliasInfo { - aliases = defReq.Ext.Prebid.Aliases - } - return aliases, defReqJSON +func readDefaultRequest(defReqConfig config.DefReqConfig) []byte { + switch defReqConfig.Type { + case "file": + return readDefaultRequestFromFile(defReqConfig) + default: + return []byte{} } - return aliases, []byte{} } -func validateDefaultAliases(aliases map[string]string) error { - var errs []error +func readDefaultRequestFromFile(defReqConfig config.DefReqConfig) []byte { + if len(defReqConfig.FileSystem.FileName) == 0 { + return []byte{} + } - for alias := range aliases { - if openrtb_ext.IsBidderNameReserved(alias) { - errs = append(errs, fmt.Errorf("alias %s is a reserved bidder name and cannot be used", alias)) - } + defaultRequestJSON, err := os.ReadFile(defReqConfig.FileSystem.FileName) + if err != nil { + glog.Fatalf("error reading default request from file %s: %v", defReqConfig.FileSystem.FileName, err) + return []byte{} } - if len(errs) > 0 { - return errortypes.NewAggregateError("default request alias errors", errs) + // validate json is valid + if err := jsonutil.UnmarshalValid(defaultRequestJSON, &openrtb2model.BidRequest{}); err != nil { + glog.Fatalf("error parsing default request from file %s: %v", defReqConfig.FileSystem.FileName, err) + return []byte{} } - return nil + return defaultRequestJSON } diff --git a/router/router_test.go b/router/router_test.go index 866a8440f3f..08d7468446e 100644 --- a/router/router_test.go +++ b/router/router_test.go @@ -8,9 +8,9 @@ import ( "testing" jsoniter "github.com/json-iterator/go" - "github.com/prebid/prebid-server/v2/config" - "github.com/prebid/prebid-server/v2/openrtb_ext" - "github.com/prebid/prebid-server/v2/util/jsonutil" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" "github.com/stretchr/testify/assert" ) @@ -44,9 +44,8 @@ func ensureHasKey(t *testing.T, data map[string]json.RawMessage, key string) { } func TestNewJsonDirectoryServer(t *testing.T) { - defaultAlias := map[string]string{"aliastest": "appnexus"} - yamlAlias := map[openrtb_ext.BidderName]openrtb_ext.BidderName{openrtb_ext.BidderName("alias"): openrtb_ext.BidderName("parentAlias")} - handler := newJsonDirectoryServer("../static/bidder-params", &testValidator{}, defaultAlias, yamlAlias) + alias := map[openrtb_ext.BidderName]openrtb_ext.BidderName{openrtb_ext.BidderName("alias"): openrtb_ext.BidderName("parentAlias")} + handler := newJsonDirectoryServer("../static/bidder-params", &testValidator{}, alias) recorder := httptest.NewRecorder() request, _ := http.NewRequest("GET", "/whatever", nil) handler(recorder, request, nil) @@ -66,7 +65,6 @@ func TestNewJsonDirectoryServer(t *testing.T) { } } - ensureHasKey(t, data, "aliastest") ensureHasKey(t, data, "alias") } @@ -211,77 +209,6 @@ func TestNoCache(t *testing.T) { } } -var testDefReqConfig = config.DefReqConfig{ - Type: "file", - FileSystem: config.DefReqFiles{ - FileName: "test_aliases.json", - }, - AliasInfo: true, -} - -func TestLoadDefaultAliases(t *testing.T) { - defAliases, aliasJSON := readDefaultRequest(testDefReqConfig) - expectedJSON := []byte(`{"ext":{"prebid":{"aliases": {"test1": "appnexus", "test2": "rubicon", "test3": "openx"}}}}`) - expectedAliases := map[string]string{ - "test1": "appnexus", - "test2": "rubicon", - "test3": "openx", - } - - assert.JSONEq(t, string(expectedJSON), string(aliasJSON)) - assert.Equal(t, expectedAliases, defAliases) -} - -func TestLoadDefaultAliasesNoInfo(t *testing.T) { - noInfoConfig := testDefReqConfig - noInfoConfig.AliasInfo = false - defAliases, aliasJSON := readDefaultRequest(noInfoConfig) - expectedJSON := []byte(`{"ext":{"prebid":{"aliases": {"test1": "appnexus", "test2": "rubicon", "test3": "openx"}}}}`) - expectedAliases := map[string]string{} - - assert.JSONEq(t, string(expectedJSON), string(aliasJSON)) - assert.Equal(t, expectedAliases, defAliases) -} - -func TestValidateDefaultAliases(t *testing.T) { - var testCases = []struct { - description string - givenAliases map[string]string - expectedError string - }{ - { - description: "None", - givenAliases: map[string]string{}, - expectedError: "", - }, - { - description: "Valid", - givenAliases: map[string]string{"aAlias": "a"}, - expectedError: "", - }, - { - description: "Invalid", - givenAliases: map[string]string{"all": "a"}, - expectedError: "default request alias errors (1 error):\n 1: alias all is a reserved bidder name and cannot be used\n", - }, - { - description: "Mixed", - givenAliases: map[string]string{"aAlias": "a", "all": "a"}, - expectedError: "default request alias errors (1 error):\n 1: alias all is a reserved bidder name and cannot be used\n", - }, - } - - for _, test := range testCases { - err := validateDefaultAliases(test.givenAliases) - - if test.expectedError == "" { - assert.NoError(t, err, test.description) - } else { - assert.EqualError(t, err, test.expectedError, test.description) - } - } -} - func TestBidderParamsCompactedOutput(t *testing.T) { expectedFormattedResponse := `{"appnexus":{"$schema":"http://json-schema.org/draft-04/schema#","title":"Sample schema","description":"A sample schema to test the bidder/params endpoint","type":"object","properties":{"integer_param":{"type":"integer","minimum":1,"description":"A customer id"},"string_param_1":{"type":"string","minLength":1,"description":"Text with blanks in between"},"string_param_2":{"type":"string","minLength":1,"description":"Text_with_no_blanks_in_between"}},"required":["integer_param","string_param_2"]}}` @@ -290,7 +217,7 @@ func TestBidderParamsCompactedOutput(t *testing.T) { paramsValidator, err := openrtb_ext.NewBidderParamsValidator(inSchemaDirectory) assert.NoError(t, err, "Error initialing validator") - handler := newJsonDirectoryServer(inSchemaDirectory, paramsValidator, nil, nil) + handler := newJsonDirectoryServer(inSchemaDirectory, paramsValidator, nil) recorder := httptest.NewRecorder() request, err := http.NewRequest("GET", "/bidder/params", nil) assert.NoError(t, err, "Error creating request") diff --git a/router/test_aliases.json b/router/test_aliases.json deleted file mode 100644 index e1be6455664..00000000000 --- a/router/test_aliases.json +++ /dev/null @@ -1,12 +0,0 @@ - -{ - "ext": { - "prebid": { - "aliases": { - "test1": "appnexus", - "test2": "rubicon", - "test3": "openx" - } - } - } -} \ No newline at end of file diff --git a/sample/001_banner/pbjs.html b/sample/001_banner/pbjs.html index b02ba95b995..af6ad643eec 100644 --- a/sample/001_banner/pbjs.html +++ b/sample/001_banner/pbjs.html @@ -12,8 +12,8 @@ border-style: solid; } - - + -